8 releases (5 breaking)
0.5.0 | Feb 27, 2022 |
---|---|
0.4.1 | Nov 22, 2021 |
0.3.1 | Sep 20, 2021 |
0.2.0 | Sep 11, 2021 |
0.0.0 | Apr 14, 2021 |
#1903 in Database interfaces
25 downloads per month
24KB
344 lines
naphtha
This crate is currently in progress. Visit the docs.rs documentation page for more information.
lib.rs
:
This library provides several traits in order to make database access a lot
easier. In addition when using naphtha
, it is possible to change
the database that is used for specific models in your application without
the requirement of changing any code.
It implements the most common operations on a database like insert
, update
and remove
for you, while also providing the ability to send custom queries
to the database.
In addition to that, when using the barrel-XXX
features, you can write your
SQL migrations and use them in your application during runtime.
See the examples below.
Features overview
- Most common function implementations
insert
,update
,remove
for your models. - Custom transactions provided by the
custom
function - DatabaseUpdateHandler enables you to change the models values before and
after the
update
transaction to the database. - Change database on specific model in your application without the need to change your code.
- Possibility to query a model from the database by using one of its member.
- Integrated [barrel] for writing your SQL migrations and the possibility to apply them during runtime.
- Thread safe handling of the database connection.
Supported databases
- SQlite3 (using diesel under the hood).
- MySQL (using diesel under the hood).
- PostgreSQL (using diesel under the hood).
Examples
In this chapter, minimal usages are shown. Please have a look at the examples in the repository for more and detailed use.
Connecting to a database
use naphtha::{DatabaseConnection, DatabaseConnect};
// This is the only line required to be changed to switch database types.
type DbBackend = diesel::SqliteConnection;
let db: DatabaseConnection<DbBackend> = DatabaseConnection::connect(":memory:").unwrap();
// do some database work
Defining a model and use database connection
To create a model and its database integration, the following code is required.
Note that this is an excerpt, see the examples
folder in the repository for
a full working example.
#[model(table_name = "persons")]
pub struct Person {
id: i32,
pub description: Option<String>,
pub updated_at: NaiveDateTime,
}
pub mod schema {
table! {
persons (id) {
id -> Int4,
description -> Nullable<Varchar>,
updated_at -> Timestamp,
}
}
}
impl DatabaseModel for Person {
type PrimaryKey = i32;
fn primary_key(&self) -> Self::PrimaryKey {
self.id
}
fn set_primary_key(&mut self, value: &Self::PrimaryKey) {
self.id = *value;
}
fn default_primary_key() -> Self::PrimaryKey {
0
}
fn table_name() -> &'static str {
"persons"
}
}
// Define your custom changes to the model before and after the transactions.
impl<T> naphtha::DatabaseUpdateHandler<T> for Person {}
impl<T> naphtha::DatabaseRemoveHandler<T> for Person {}
impl<T> naphtha::DatabaseInsertHandler<T> for Person {}
// This implements your database migration functions.
impl DatabaseSqlMigration for Person {
fn migration_up(migration: &mut Migration) {
use naphtha::DatabaseModel;
migration.create_table_if_not_exists(Self::table_name(), |t| {
t.add_column("id", types::primary());
t.add_column("description", types::text().nullable(true));
t.add_column("updated_at", types::custom("timestamp"));
});
}
fn migration_down(migration: &mut Migration) {
use naphtha::DatabaseModel;
migration.drop_table_if_exists(Self::table_name());
}
}
fn main() {
use naphtha::{DatabaseConnection, DatabaseConnect};
let db = DatabaseConnection::connect(":memory:").unwrap();
// p is to be mutable because the insert function updates the id member
// to the one given by the database.
let mut p = Person {
id: Person::default_primary_key(),
description: Some("The new person is registered".into()),
};
p.insert(&db);
// id member is set to the correct number given by the database.
// do a custom query to the database
db.custom::<diesel::result::QueryResult::<Person>, _>(|c: &DbBackend| {
use schema::{persons, persons::dsl::*};
persons.filter(id.eq(1)).first(c)
});
p.remove(&db);
// p not available anymore in the database
}
Dependencies
~4–8.5MB
~175K SLoC