diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 34da65e..917d5e7 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -13,17 +13,13 @@
-
-
-
-
-
-
-
-
+
+
+
+
-
-
+
+
@@ -51,6 +47,7 @@
+
@@ -83,6 +80,7 @@
+
@@ -93,7 +91,7 @@
1599728150675
-
+
@@ -101,22 +99,38 @@
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/database/mod.rs b/src/database/mod.rs
index 50010e1..3ad7b0e 100644
--- a/src/database/mod.rs
+++ b/src/database/mod.rs
@@ -1,45 +1,64 @@
+use crate::database::permissions::Permissions;
+use crate::database::role_permissions::RolePermissions;
+use crate::database::roles::Roles;
+use crate::database::user_roles::UserRoles;
+use crate::database::users::Users;
+use dotenv;
use postgres::{Client, Error, NoTls};
+use std::sync::{Arc, Mutex};
+
+pub mod permissions;
+pub mod role_permissions;
+pub mod roles;
+pub mod user_roles;
pub mod users;
-use dotenv;
const DB_CONNECTION_URL: &str = "POSTGRES_CONNECTION_URL";
const DEFAULT_CONNECTION: &str = "postgres://postgres:postgres@localhost/postgrees";
+pub trait Model {
+ fn new(connection: Arc>) -> Self;
+ fn init(&self) -> Result<(), Error>;
+}
+
+#[derive(Clone)]
+pub struct Database {
+ connection: Arc>,
+ pub users: Users,
+ pub roles: Roles,
+ pub permissions: Permissions,
+ role_permission: RolePermissions,
+ user_roles: UserRoles,
+}
+
+type PostgresResult = Result;
+
+impl Database {
+ pub fn new() -> PostgresResult {
+ let connection = Arc::new(Mutex::new(get_connection()?));
+ Ok(Self {
+ users: Users::new(Arc::clone(&connection)),
+ roles: Roles::new(Arc::clone(&connection)),
+ permissions: Permissions::new(Arc::clone(&connection)),
+ user_roles: UserRoles::new(Arc::clone(&connection)),
+ role_permission: RolePermissions::new(Arc::clone(&connection)),
+ connection,
+ })
+ }
+
+ /// Inits all database models
+ pub fn init(&self) -> PostgresResult<()> {
+ self.users.init()?;
+ self.roles.init()?;
+ self.permissions.init()?;
+ self.user_roles.init()?;
+ self.role_permission.init()?;
+
+ Ok(())
+ }
+}
/// Returns a database connection
-pub fn get_connection() -> Result {
+fn get_connection() -> Result {
let conn_url = dotenv::var(DB_CONNECTION_URL).unwrap_or(DEFAULT_CONNECTION.to_string());
Client::connect(conn_url.as_str(), NoTls)
}
-
-/// Inits the database
-pub fn init_database(client: &mut Client) -> Result<(), Error> {
- client.batch_execute("
- CREATE TABLE IF NOT EXISTS users (
- id SERIAL PRIMARY KEY,
- name VARCHAR(255) NOT NULL,
- email VARCHAR(255) UNIQUE NOT NULL,
- password_hash VARCHAR(32) NOT NULL,
- salt VARCHAR(16) NOT NULL
- );
- CREATE TABLE IF NOT EXISTS roles (
- id SERIAL PRIMARY KEY,
- name VARCHAR(128) UNIQUE NOT NULL,
- description VARCHAR(512)
- );
- CREATE TABLE IF NOT EXISTS user_roles (
- user_id INT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
- role_id INT NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
- PRIMARY KEY (user_id, role_id)
- );
- CREATE TABLE IF NOT EXISTS permissions (
- id SERIAL PRIMARY KEY,
- name VARCHAR(128) UNIQUE NOT NULL,
- description VARCHAR(512)
- );
- CREATE TABLE IF NOT EXISTS role_permissions (
- role_id INT NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
- permission_id INT NOT NULL REFERENCES permissions(id) ON DELETE CASCADE,
- PRIMARY KEY (role_id, permission_id)
- );
- ")
-}
\ No newline at end of file
diff --git a/src/database/permissions.rs b/src/database/permissions.rs
new file mode 100644
index 0000000..dd223e1
--- /dev/null
+++ b/src/database/permissions.rs
@@ -0,0 +1,24 @@
+use crate::database::Model;
+use postgres::{Client, Error};
+use std::sync::{Arc, Mutex};
+
+#[derive(Clone)]
+pub struct Permissions {
+ connection: Arc>,
+}
+
+impl Model for Permissions {
+ fn new(connection: Arc>) -> Self {
+ Self { connection }
+ }
+
+ fn init(&self) -> Result<(), Error> {
+ self.connection.lock().unwrap().batch_execute(
+ "CREATE TABLE IF NOT EXISTS permissions (
+ id SERIAL PRIMARY KEY,
+ name VARCHAR(128) UNIQUE NOT NULL,
+ description VARCHAR(512)
+ );",
+ )
+ }
+}
diff --git a/src/database/role_permissions.rs b/src/database/role_permissions.rs
new file mode 100644
index 0000000..853b11f
--- /dev/null
+++ b/src/database/role_permissions.rs
@@ -0,0 +1,25 @@
+use crate::database::Model;
+use postgres::{Client, Error};
+use std::sync::{Arc, Mutex};
+
+#[derive(Clone)]
+pub struct RolePermissions {
+ connection: Arc>,
+}
+
+impl Model for RolePermissions {
+ fn new(connection: Arc>) -> Self {
+ Self { connection }
+ }
+
+ fn init(&self) -> Result<(), Error> {
+ self.connection.lock().unwrap().batch_execute(
+ "
+ CREATE TABLE IF NOT EXISTS role_permissions (
+ role_id INT NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
+ permission_id INT NOT NULL REFERENCES permissions(id) ON DELETE CASCADE,
+ PRIMARY KEY (role_id, permission_id)
+ );",
+ )
+ }
+}
diff --git a/src/database/roles.rs b/src/database/roles.rs
new file mode 100644
index 0000000..c8a61f1
--- /dev/null
+++ b/src/database/roles.rs
@@ -0,0 +1,30 @@
+use crate::database::role_permissions::RolePermissions;
+use crate::database::Model;
+use postgres::{Client, Error};
+use std::sync::{Arc, Mutex};
+
+#[derive(Clone)]
+pub struct Roles {
+ connection: Arc>,
+ role_permission: RolePermissions,
+}
+
+impl Model for Roles {
+ fn new(connection: Arc>) -> Self {
+ Self {
+ role_permission: RolePermissions::new(Arc::clone(&connection)),
+ connection,
+ }
+ }
+
+ fn init(&self) -> Result<(), Error> {
+ self.connection.lock().unwrap().batch_execute(
+ "
+ CREATE TABLE IF NOT EXISTS roles (
+ id SERIAL PRIMARY KEY,
+ name VARCHAR(128) UNIQUE NOT NULL,
+ description VARCHAR(512)
+ );",
+ )
+ }
+}
diff --git a/src/database/user_roles.rs b/src/database/user_roles.rs
new file mode 100644
index 0000000..6cca12c
--- /dev/null
+++ b/src/database/user_roles.rs
@@ -0,0 +1,25 @@
+use crate::database::Model;
+use postgres::{Client, Error};
+use std::sync::{Arc, Mutex};
+
+#[derive(Clone)]
+pub struct UserRoles {
+ connection: Arc>,
+}
+
+impl Model for UserRoles {
+ fn new(connection: Arc>) -> Self {
+ Self { connection }
+ }
+
+ fn init(&self) -> Result<(), Error> {
+ self.connection.lock().unwrap().batch_execute(
+ "
+ CREATE TABLE IF NOT EXISTS user_roles (
+ user_id INT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
+ role_id INT NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
+ PRIMARY KEY (user_id, role_id)
+ );",
+ )
+ }
+}
diff --git a/src/database/users.rs b/src/database/users.rs
index e69de29..999b27c 100644
--- a/src/database/users.rs
+++ b/src/database/users.rs
@@ -0,0 +1,31 @@
+use crate::database::user_roles::UserRoles;
+use crate::database::Model;
+use postgres::{Client, Error};
+use std::sync::{Arc, Mutex};
+
+#[derive(Clone)]
+pub struct Users {
+ connection: Arc>,
+ user_roles: UserRoles,
+}
+
+impl Model for Users {
+ fn new(connection: Arc>) -> Self {
+ Self {
+ user_roles: UserRoles::new(Arc::clone(&connection)),
+ connection,
+ }
+ }
+
+ fn init(&self) -> Result<(), Error> {
+ self.connection.lock().unwrap().batch_execute(
+ "CREATE TABLE IF NOT EXISTS users (
+ id SERIAL PRIMARY KEY,
+ name VARCHAR(255) NOT NULL,
+ email VARCHAR(255) UNIQUE NOT NULL,
+ password_hash VARCHAR(32) NOT NULL,
+ salt VARCHAR(16) NOT NULL
+ );",
+ )
+ }
+}
diff --git a/src/main.rs b/src/main.rs
index 28e7ffe..bea523c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,6 +1,6 @@
-use flotte_user_management::database::{get_connection, init_database};
+use flotte_user_management::database::Database;
fn main() {
- let mut client = get_connection().unwrap();
- init_database(&mut client).unwrap()
+ let database = Database::new().unwrap();
+ database.init().unwrap();
}