trying to add sea-orm as a way to create sql based models

This commit is contained in:
Chris Cochrun 2023-04-04 11:20:00 -05:00
parent 43f8c92253
commit db99525963
11 changed files with 2191 additions and 16 deletions

1808
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -22,6 +22,7 @@ cxx-qt = "0.5.1"
cxx-qt-lib = "0.5.1"
# home = "0.5.4"
dirs = "5.0.0"
sea-orm = { version = "0.11.2", features = ["sqlx-sqlite", "sqlx", "runtime-async-std-rustls"] }
# ffmpeg-next = "6.0.0"
# cxx-qt-build generates C++ code from the `#[cxx_qt::bridge]` module

View file

@ -7,5 +7,6 @@ fn main() {
.file("src/rust/file_helper.rs")
.file("src/rust/slide_obj.rs")
.file("src/rust/slide_model.rs")
.file("src/rust/image_model.rs")
.build();
}

View file

@ -0,0 +1,19 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.2
use sea_orm::entity::prelude::*;
use sea_orm::EntityTrait;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "images")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: i32,
pub title: String,
#[sea_orm(column_name = "filePath")]
pub path: String,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}

8
src/rust/entities/mod.rs Normal file
View file

@ -0,0 +1,8 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.2
pub mod prelude ;
pub mod images ;
pub mod presentations ;
pub mod songs ;
pub mod videos ;

View file

@ -0,0 +1,6 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.2
pub use super :: images :: Entity as Images ;
pub use super :: presentations :: Entity as Presentations ;
pub use super :: songs :: Entity as Songs ;
pub use super :: videos :: Entity as Videos ;

View file

@ -0,0 +1,20 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.2
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "presentations")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: i32,
pub title: String,
#[sea_orm(column_name = "filePath")]
pub file_path: String,
#[sea_orm(column_name = "pageCount")]
pub page_count: Option<i32>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,31 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.2
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "songs")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: i32,
pub title: String,
pub lyrics: Option<String>,
pub author: Option<String>,
pub ccli: Option<String>,
pub audio: Option<String>,
pub vorder: Option<String>,
pub background: Option<String>,
#[sea_orm(column_name = "backgroundType")]
pub background_type: Option<String>,
#[sea_orm(column_name = "horizontalTextAlignment")]
pub horizontal_text_alignment: Option<String>,
#[sea_orm(column_name = "verticalTextAlignment")]
pub vertical_text_alignment: Option<String>,
pub font: Option<String>,
#[sea_orm(column_name = "fontSize")]
pub font_size: Option<i32>,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -0,0 +1,24 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.2
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "videos")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: i32,
pub title: String,
#[sea_orm(column_name = "filePath")]
pub file_path: String,
#[sea_orm(column_name = "startTime")]
pub start_time: i32,
#[sea_orm(column_name = "endTime")]
pub end_time: i32,
#[sea_orm(column_name = "loop")]
pub looping: bool,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -18,9 +18,286 @@ mod image_model {
type QStringList = cxx_qt_lib::QStringList;
include!("cxx-qt-lib/qlist.h");
type QList_QString = cxx_qt_lib::QList<QString>;
// #[cxx_name = "Slidey"]
// type CxxSlidey = super::qobject::Slidey;
// include!("cxx-qt-lib/qvector.h");
// type QVector_Slidey = cxx_qt_lib::QVector<Slidey>;
}
#[cxx_qt::qobject(base = "QAbstractListModel")]
#[derive(Default, Debug)]
pub struct ImageModel {
images: Vec<Image>,
}
#[derive(Default, Clone, Debug)]
pub struct Image {
id: i32,
title: QString,
path: QString,
}
#[cxx_qt::qsignals(ImageModel)]
pub enum Signals<'a> {
#[inherit]
DataChanged {
top_left: &'a QModelIndex,
bottom_right: &'a QModelIndex,
roles: &'a QVector_i32,
},
}
enum Role {
IdRole,
PathRole,
TitleRole,
}
use crate::entities::{images, prelude::Images};
use sea_orm::{ConnectionTrait, Database, DbBackend, DbErr, Statement, ActiveValue};
use std::path::PathBuf;
impl qobject::ImageModel {
#[qinvokable]
pub fn clear(mut self: Pin<&mut Self>) {
unsafe {
self.as_mut().begin_reset_model();
self.as_mut().images_mut().clear();
self.as_mut().end_reset_model();
}
}
#[qinvokable]
pub fn remove_item(mut self: Pin<&mut Self>, index: i32) {
if index < 0 || (index as usize) >= self.images().len() {
return;
}
unsafe {
self.as_mut()
.begin_remove_rows(&QModelIndex::default(), index, index);
self.as_mut().images_mut().remove(index as usize);
self.as_mut().end_remove_rows();
}
}
#[qinvokable]
pub async fn add_item(mut self: Pin<&mut Self>, id: i32, title: QString, path: QString) -> Result<(), DBErr> {
const DATABASE_URL: &str = "sqlite://library-db.sqlite3";
const DB_NAME: &str = "library_db";
let db = Database::connect(DATABASE_URL).await?;
let image = Image { id, title, path };
let model = images::ActiveModel {
id: ActiveValue::set(id),
title: ActiveValue::set(title.to_string()),
path: ActiveValue::set(path.to_string()),
..Default::default()
};
let res = Images::insert(model).exec(db).await?;
self.as_mut().add_image(image);
Ok(())
}
fn add_image(mut self: Pin<&mut Self>, image: Image) {
let index = self.as_ref().images().len() as i32;
println!("{:?}", image);
unsafe {
self.as_mut()
.begin_insert_rows(&QModelIndex::default(), index, index);
self.as_mut().images_mut().push(image);
self.as_mut().end_insert_rows();
}
}
#[qinvokable]
pub fn insert_item(
mut self: Pin<&mut Self>,
id: i32,
title: QString,
path: QString,
index: i32,
) {
let image = Image { id, title, path };
self.as_mut().insert_image(image, index);
}
fn insert_image(mut self: Pin<&mut Self>, image: Image, id: i32) {
unsafe {
self.as_mut()
.begin_insert_rows(&QModelIndex::default(), id, id);
self.as_mut().images_mut().insert(id as usize, image);
self.as_mut().end_insert_rows();
}
}
// #[qinvokable]
// pub fn insert_item_from_service(
// mut self: Pin<&mut Self>,
// index: i32,
// service_item: &QMap_QString_QVariant,
// ) {
// let ty = service_item
// .get(&QString::from("type"))
// .unwrap_or(QVariant::from(&QString::from("")))
// .value::<QString>();
// let background = service_item
// .get(&QString::from("background"))
// .unwrap_or(QVariant::from(&QString::from("")))
// .value::<QString>()
// .unwrap_or_default();
// let background_type = service_item
// .get(&QString::from("backgroundType"))
// .unwrap_or(QVariant::from(&QString::from("")))
// .value::<QString>()
// .unwrap_or_default();
// let mut image = Image::default();
// self.as_mut().insert_image(&image, index);
// println!("Item added in rust model!");
// }
// #[qinvokable]
// pub fn add_item_from_service(
// mut self: Pin<&mut Self>,
// index: i32,
// service_item: &QMap_QString_QVariant,
// ) {
// println!("add rust image {:?}", index);
// let ty = service_item
// .get(&QString::from("type"))
// .unwrap_or(QVariant::from(&QString::from("")))
// .value::<QString>();
// let background = service_item
// .get(&QString::from("background"))
// .unwrap_or(QVariant::from(&QString::from("")))
// .value::<QString>()
// .unwrap_or_default();
// let background_type = service_item
// .get(&QString::from("backgroundType"))
// .unwrap_or(QVariant::from(&QString::from("")))
// .value::<QString>()
// .unwrap_or_default();
// let mut image = Image::default();
// self.as_mut().add_image(&image);
// println!("Item added in rust model!");
// }
#[qinvokable]
pub fn get_item(self: Pin<&mut Self>, index: i32) -> QMap_QString_QVariant {
println!("{index}");
let mut qvariantmap = QMap_QString_QVariant::default();
let idx = self.index(index, 0, &QModelIndex::default());
if !idx.is_valid() {
return qvariantmap;
}
let rn = self.as_ref().role_names();
let rn_iter = rn.iter();
if let Some(image) = self.rust().images.get(index as usize) {
for i in rn_iter {
qvariantmap.insert(
QString::from(&i.1.to_string()),
self.as_ref().data(&idx, *i.0),
);
}
};
qvariantmap
}
fn get_role(&self, role: Role) -> i32 {
match role {
Role::IdRole => 0,
Role::TitleRole => 1,
Role::PathRole => 2,
_ => 0,
}
}
}
// Create Rust bindings for C++ functions of the base class (QAbstractItemModel)
#[cxx_qt::inherit]
extern "C++" {
unsafe fn begin_insert_rows(
self: Pin<&mut qobject::ImageModel>,
parent: &QModelIndex,
first: i32,
last: i32,
);
unsafe fn end_insert_rows(self: Pin<&mut qobject::ImageModel>);
unsafe fn begin_remove_rows(
self: Pin<&mut qobject::ImageModel>,
parent: &QModelIndex,
first: i32,
last: i32,
);
unsafe fn end_remove_rows(self: Pin<&mut qobject::ImageModel>);
unsafe fn begin_reset_model(self: Pin<&mut qobject::ImageModel>);
unsafe fn end_reset_model(self: Pin<&mut qobject::ImageModel>);
}
#[cxx_qt::inherit]
unsafe extern "C++" {
#[cxx_name = "canFetchMore"]
fn base_can_fetch_more(self: &qobject::ImageModel, parent: &QModelIndex) -> bool;
fn index(
self: &qobject::ImageModel,
row: i32,
column: i32,
parent: &QModelIndex,
) -> QModelIndex;
}
// QAbstractListModel implementation
impl qobject::ImageModel {
#[qinvokable(cxx_override)]
fn data(&self, index: &QModelIndex, role: i32) -> QVariant {
if let Some(image) = self.images().get(index.row() as usize) {
return match role {
0 => QVariant::from(&image.id),
1 => QVariant::from(&image.title),
2 => QVariant::from(&image.path),
_ => QVariant::default(),
};
}
QVariant::default()
}
// Example of overriding a C++ virtual method and calling the base class implementation.
#[qinvokable(cxx_override)]
pub fn can_fetch_more(&self, parent: &QModelIndex) -> bool {
self.base_can_fetch_more(parent)
}
#[qinvokable(cxx_override)]
pub fn role_names(&self) -> QHash_i32_QByteArray {
let mut roles = QHash_i32_QByteArray::default();
roles.insert(0, cxx_qt_lib::QByteArray::from("id"));
roles.insert(1, cxx_qt_lib::QByteArray::from("title"));
roles.insert(2, cxx_qt_lib::QByteArray::from("path"));
roles
}
#[qinvokable(cxx_override)]
pub fn row_count(&self, _parent: &QModelIndex) -> i32 {
let cnt = self.rust().images.len() as i32;
// println!("row count is {cnt}");
cnt
}
#[qinvokable]
pub fn count(&self) -> i32 {
self.rust().images.len() as i32
}
}
}

View file

@ -12,6 +12,8 @@
// assert_eq!(result, 4);
// }
// }
const DATABASE_URL: &str = "sqlite://library-db.sqlite3";
const DB_NAME: &str = "library_db";
// mod my_object;
mod file_helper;
@ -19,4 +21,6 @@ mod service_thing;
mod settings;
mod slide_obj;
mod slide_model;
mod image_model;
mod entities;
// mod video_thumbnail;