web


git clone https://radroots.dev/git/web.git
Log | Files | Refs | Submodules | README | LICENSE

commit c4fda1760dea226f5faeb63d1a6b69ce7c0887a0
parent 16020cf78c67fefdb0d94f1bd63ec864d553b5be
Author: triesap <137732411+triesap@users.noreply.github.com>
Date:   Mon, 28 Apr 2025 04:06:28 +0000

Edit `model` crate adding `farm` and `farm_location` models, edit `tangle` crate adding models handlers. Refactor `location_gcs` table fields. Edit farms routes.

Diffstat:
Mapp/src/lib/util/model/location-gcs.ts | 12++++++------
Mapp/src/routes/(app)/farms/+page.svelte | 46++++++++++++++++++++++++++++++++++++++++++++--
Mapp/src/routes/(app)/farms/add/+page.svelte | 33+++++++++++++++++++++++++++++++++
Mapp/src/routes/(cfg)/init/+page.svelte | 1-
Acrates/model/src/tables/farm.rs | 227+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acrates/model/src/tables/farm_location.rs | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcrates/model/src/tables/location_gcs.rs | 8++++----
Mcrates/model/src/tables/mod.rs | 4+++-
Mcrates/tangle/icons/icon.icns | 0
Acrates/tangle/migrations/down/0007_farm.sql | 2++
Rcrates/tangle/migrations/down/0007_nostr_profile_relay.sql -> crates/tangle/migrations/down/0008_nostr_profile_relay.sql | 0
Acrates/tangle/migrations/down/0009_farm_location.sql | 2++
Rcrates/tangle/migrations/down/0008_trade_product_location.sql -> crates/tangle/migrations/down/0010_trade_product_location.sql | 0
Rcrates/tangle/migrations/down/0009_trade_product_media.sql -> crates/tangle/migrations/down/0011_trade_product_media.sql | 0
Mcrates/tangle/migrations/up/0001_location_gcs.sql | 2+-
Acrates/tangle/migrations/up/0007_farm.sql | 11+++++++++++
Rcrates/tangle/migrations/up/0007_nostr_profile_relay.sql -> crates/tangle/migrations/up/0008_nostr_profile_relay.sql | 0
Acrates/tangle/migrations/up/0009_farm_location.sql | 8++++++++
Rcrates/tangle/migrations/up/0008_trade_product_location.sql -> crates/tangle/migrations/up/0010_trade_product_location.sql | 0
Rcrates/tangle/migrations/up/0009_trade_product_media.sql -> crates/tangle/migrations/up/0011_trade_product_media.sql | 0
Acrates/tangle/src/commands/model/farm.rs | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acrates/tangle/src/commands/model/farm_location.rs | 29+++++++++++++++++++++++++++++
Mcrates/tangle/src/commands/model/mod.rs | 2++
Mcrates/tangle/src/lib.rs | 14++++++++++++++
Mcrates/tangle/src/util.rs | 2+-
25 files changed, 506 insertions(+), 16 deletions(-)

diff --git a/app/src/lib/util/model/location-gcs.ts b/app/src/lib/util/model/location-gcs.ts @@ -3,9 +3,9 @@ import type { ILocationGcsCreateResolve, LocationGcsFormFields } from "@radroots import { err_msg, location_geohash, type GeocoderReverseResult, type GeolocationCoordinatesPoint, type GeolocationPoint } from "@radroots/util"; import { db, geoc } from ".."; -export const model_location_gcs_create_geol_p = async (opts: { +export const model_location_gcs_create_geol_point = async (opts: { label?: string; - kind: string; + tag_0?: string; geol_p: GeolocationPoint; }): Promise<ILocationGcsCreateResolve<string>> => { try { @@ -14,7 +14,7 @@ export const model_location_gcs_create_geol_p = async (opts: { lat: geol_p.lat.toString(), lng: geol_p.lng.toString(), geohash: location_geohash(geol_p), - kind: opts.kind, + tag_0: opts.tag_0, } if (label) fields.label = label; const geoc_rev = await geoc.reverse({ @@ -38,9 +38,9 @@ export const model_location_gcs_create_geol_p = async (opts: { } }; -export const model_location_gcs_create_geoc_r = async (opts: { +export const model_location_gcs_create = async (opts: { label?: string; - kind: string; + tag_0?: string; geoc_r: GeocoderReverseResult; geol_p: GeolocationCoordinatesPoint; }): Promise<ILocationGcsCreateResolve<string>> => { @@ -50,7 +50,7 @@ export const model_location_gcs_create_geoc_r = async (opts: { lat: geol_p.lat.toString(), lng: geol_p.lng.toString(), geohash: location_geohash(geol_p), - kind: opts.kind, + tag_0: opts.tag_0 || undefined, gc_id: geoc_r.id.toString(), gc_name: geoc_r.name, gc_admin1_id: geoc_r.admin1_id.toString(), diff --git a/app/src/routes/(app)/farms/+page.svelte b/app/src/routes/(app)/farms/+page.svelte @@ -1,10 +1,52 @@ <script lang="ts"> import { locale, ls } from "$lib/locale/i18n"; - import { route } from "$lib/util"; + import { db, route } from "$lib/util"; import { lc_geocode } from "$lib/util/callback"; import { Farms, handle_err, type IViewFarmsData } from "@radroots/lib-app"; + import { location_gcs_to_geolocation_basis } from "@radroots/util"; + import { onMount } from "svelte"; - let data: IViewFarmsData | undefined = $state(undefined); + type LoadData = IViewFarmsData | undefined; + let data: LoadData = $state(undefined); + + onMount(async () => { + data = await load_data(); + }); + + const load_data = async (): Promise<LoadData> => { + try { + const tb_farms = await db.farm_read_list(); + if (`err` in tb_farms) return; + return { + list: await Promise.all( + tb_farms.results.map(async (i) => { + const tb_loc_gcs = await db.location_gcs_read_list({ + table: [`on_farm`, { id: i.id }], + }); + console.log( + JSON.stringify(tb_loc_gcs, null, 4), + `tb_loc_gcs`, + ); + return { + farm: { + id: i.id, + name: i.name, + }, + geolocation: + `results` in tb_loc_gcs && tb_loc_gcs.results[0] + ? location_gcs_to_geolocation_basis( + tb_loc_gcs.results[0], + ) + : undefined, + }; + }), + ), + }; + } catch (e) { + await handle_err(e, `load`); + } finally { + } + }; </script> <Farms diff --git a/app/src/routes/(app)/farms/add/+page.svelte b/app/src/routes/(app)/farms/add/+page.svelte @@ -1,11 +1,14 @@ <script> import { locale, ls } from "$lib/locale/i18n"; + import { db, route } from "$lib/util"; import { lc_geocode, lc_geop_current, lc_gui_alert, } from "$lib/util/callback"; + import { model_location_gcs_create } from "$lib/util/model/location-gcs"; import { FarmsAdd, handle_err } from "@radroots/lib-app"; + import { throw_err } from "@radroots/util"; </script> <FarmsAdd @@ -19,6 +22,36 @@ lc_submit: async ({ data_s }) => { try { console.log(JSON.stringify(data_s, null, 4), `data_s`); + + const farm_create = await db.farm_create({ + name: data_s.farm_name, + area: data_s.farm_area + ? data_s.farm_area.toString() + : undefined, + area_unit: data_s.farm_area_unit, + }); + if (`err` in farm_create) throw_err(farm_create); + if (`err_s` in farm_create) throw_err(farm_create.err_s[0]); //@todo + + const location_gcs_create = await model_location_gcs_create({ + geoc_r: data_s.geocode_result, + geol_p: data_s.geolocation_point, + }); + if (`err` in location_gcs_create) + throw_err(location_gcs_create); + if (`err_s` in location_gcs_create) + throw_err(location_gcs_create.err_s[0]); //@todo + + const farm_location_set = await db.farm_location_set({ + farm: { + id: farm_create.id, + }, + location_gcs: { + id: location_gcs_create.id, + }, + }); + if (`err` in farm_location_set) throw_err(farm_location_set); + await route(`/farms`); } catch (e) { await handle_err(e, `lc_submit`); } diff --git a/app/src/routes/(cfg)/init/+page.svelte b/app/src/routes/(cfg)/init/+page.svelte @@ -65,7 +65,6 @@ onMount(async () => { try { await init(); - view = `eula`; } catch (e) { handle_err(e, `on_mount`); } diff --git a/crates/model/src/tables/farm.rs b/crates/model/src/tables/farm.rs @@ -0,0 +1,227 @@ +use futures::TryStreamExt; +use tangle_core::{ + types::{IModelsQueryBindValueTuple, IResult, IResultList, IResultPass}, + util::{time_created_on, uuidv4}, +}; + +use crate::{error::ModelError, types::DatabaseConnection, util::parse_query_value}; + +#[derive(Debug, serde::Serialize, serde::Deserialize, sqlx::FromRow)] +pub struct Farm { + id: String, + created_at: String, + updated_at: String, + name: String, + area: Option<String>, + area_unit: Option<String>, + title: Option<String>, + description: Option<String>, +} + +#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] +pub struct IFarmFields { + pub name: String, + pub area: Option<String>, + pub area_unit: Option<String>, + pub title: Option<String>, + pub description: Option<String>, +} + +#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] +pub struct IFarmFieldsPartial { + pub name: Option<String>, + pub area: Option<String>, + pub area_unit: Option<String>, + pub title: Option<String>, + pub description: Option<String>, +} + +#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] +pub struct IFarmFieldsFilter { + pub created_at: Option<String>, + pub updated_at: Option<String>, + pub name: Option<String>, + pub area: Option<String>, + pub area_unit: Option<String>, + pub title: Option<String>, + pub description: Option<String>, +} + +#[derive(Clone, serde::Serialize, serde::Deserialize)] +#[serde(untagged)] +pub enum FarmQueryBindValues { + Id { id: String }, +} + +pub fn farm_query_bind_values(opts: FarmQueryBindValues) -> IModelsQueryBindValueTuple { + match opts { + FarmQueryBindValues::Id { id } => ("id".to_string(), id), + } +} + +fn lib_table_farm_parse_fields( + opts: IFarmFields, +) -> Result<serde_json::Map<String, serde_json::Value>, ModelError> { + let fields = serde_json::to_value(opts) + .map_err(|err| ModelError::SerializationError(err.to_string()))? + .as_object() + .ok_or_else(|| ModelError::SerializationError("Expected an object".to_string()))? + .clone(); + Ok(fields) +} + +pub type IFarmCreate = IFarmFields; +pub type IFarmCreateResolve = IResult<String>; + +pub async fn lib_model_farm_create( + db: &DatabaseConnection, + opts: IFarmCreate, +) -> Result<IFarmCreateResolve, ModelError> { + let id: String = uuidv4(); + let created_at: String = time_created_on(); + let updated_at: String = created_at.clone(); + let fields = lib_table_farm_parse_fields(opts)?; + + let query = format!( + "INSERT INTO farm (id, created_at, updated_at, {}) VALUES (?, ?, ?, {});", + fields + .keys() + .map(|k| k.to_string()) + .collect::<Vec<String>>() + .join(","), + (0..fields.len()) + .map(|_| "?") + .collect::<Vec<&str>>() + .join(",") + ); + + let mut query_builder = sqlx::query(&query); + query_builder = query_builder.bind(&id); + query_builder = query_builder.bind(&created_at); + query_builder = query_builder.bind(&updated_at); + for (_, value) in fields.iter() { + match value { + serde_json::Value::Bool(b) => { + let bool_str = if *b { "1" } else { "0" }; + query_builder = query_builder.bind(bool_str); + } + serde_json::Value::Number(n) => { + if let Some(f) = n.as_f64() { + query_builder = query_builder.bind(f); + } else if let Some(i64) = n.as_i64() { + query_builder = query_builder.bind(i64); + } else if let Some(u64) = n.as_u64() { + if u64 <= u32::MAX as u64 { + query_builder = query_builder.bind(u64 as u32); + } + } + } + serde_json::Value::String(s) => { + query_builder = query_builder.bind(s); + } + _ => { + query_builder = query_builder.bind::<Option<serde_json::Value>>(None); + } + } + } + query_builder + .execute(db) + .await + .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; + Ok(IResult { result: id }) +} + +#[derive(serde::Serialize, serde::Deserialize)] +pub struct IFarmQueryRead { + pub query: String, + pub bind_values: Vec<serde_json::Value>, +} + +pub type IFarmRead = IFarmQueryRead; +pub type IFarmReadResolve = IResultList<Farm>; + +pub async fn lib_model_farm_read( + db: &DatabaseConnection, + opts: IFarmRead, +) -> Result<IFarmReadResolve, ModelError> { + let mut query_builder = sqlx::query_as::<_, Farm>(&opts.query); + for value in opts.bind_values.iter() { + query_builder = query_builder.bind(parse_query_value(value)?); + } + let results = query_builder + .fetch(db) + .try_collect() + .await + .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; + Ok(IResultList { results }) +} + +#[derive(serde::Serialize, serde::Deserialize)] +pub struct IFarmQueryReadList { + pub query: String, + pub bind_values: Vec<serde_json::Value>, +} + +pub type IFarmReadList = IFarmQueryReadList; +pub type IFarmReadListResolve = IResultList<Farm>; + +pub async fn lib_model_farm_read_list( + db: &DatabaseConnection, + opts: IFarmReadList, +) -> Result<IFarmReadListResolve, ModelError> { + let mut query_builder = sqlx::query_as::<_, Farm>(&opts.query); + for value in opts.bind_values.iter() { + query_builder = query_builder.bind(parse_query_value(value)?); + } + let results = query_builder + .fetch(db) + .try_collect() + .await + .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; + Ok(IResultList { results }) +} + +#[derive(serde::Serialize, serde::Deserialize)] +pub struct IFarmQueryUpdate { + pub query: String, + pub bind_values: Vec<serde_json::Value>, +} + +pub type IFarmUpdate = IFarmQueryUpdate; +pub type IFarmUpdateResolve = IResultPass; + +pub async fn lib_model_farm_update( + db: &sqlx::Pool<sqlx::Sqlite>, + opts: IFarmUpdate, +) -> Result<IFarmUpdateResolve, ModelError> { + let mut query_builder = sqlx::query(&opts.query); + for value in opts.bind_values.iter() { + query_builder = query_builder.bind(parse_query_value(value)?); + } + query_builder + .execute(db) + .await + .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; + Ok(IResultPass { pass: true }) +} + +pub type IFarmDelete = FarmQueryBindValues; +pub type IFarmDeleteResolve = IResultPass; + +pub async fn lib_model_farm_delete( + db: &DatabaseConnection, + opts: IFarmDelete, +) -> Result<IFarmDeleteResolve, ModelError> { + let (bv_k, bv) = farm_query_bind_values(opts); + let query = format!("DELETE FROM farm WHERE {} = ?1;", bv_k); + let result = sqlx::query(&query) + .bind(bv) + .execute(db) + .await + .map_err(|e: sqlx::Error| ModelError::InvalidQuery(e.to_string()))?; + if result.rows_affected() > 0 { + Ok(IResultPass { pass: true }) + } else { + Err(ModelError::NotFound("model.farm.name".to_string())) + } +} diff --git a/crates/model/src/tables/farm_location.rs b/crates/model/src/tables/farm_location.rs @@ -0,0 +1,58 @@ +use super::{ + farm::{farm_query_bind_values, FarmQueryBindValues}, + location_gcs::{location_gcs_query_bind_values, LocationGcsQueryBindValues}, +}; +use crate::{error::ModelError, types::DatabaseConnection}; +use tangle_core::types::IResultPass; + +#[derive(serde::Serialize, serde::Deserialize, sqlx::FromRow)] +pub struct FarmLocation { + tb_farm: String, + tb_lg: String, +} + +#[derive(serde::Serialize, serde::Deserialize)] +pub struct IFarmLocationTables { + pub farm: FarmQueryBindValues, + pub location_gcs: LocationGcsQueryBindValues, +} + +pub type IFarmLocationRelation = IFarmLocationTables; +pub type IFarmLocationResolve = IResultPass; + +pub async fn lib_model_farm_location_set( + db: &DatabaseConnection, + opts: IFarmLocationRelation, +) -> Result<IFarmLocationResolve, ModelError> { + let (bv_farm_k, bv_farm) = farm_query_bind_values(opts.farm); + let (bv_lg_k, bv_lg) = location_gcs_query_bind_values(opts.location_gcs); + let query_vals = vec![bv_farm, bv_lg]; + let query = format!("INSERT INTO farm_location (tb_farm, tb_lg) VALUES ((SELECT id FROM farm WHERE {} = ?), (SELECT id FROM location_gcs WHERE {} = ?));", bv_farm_k, bv_lg_k); + let mut query_builder = sqlx::query(&query); + for value in query_vals.iter() { + query_builder = query_builder.bind(value); + } + query_builder + .execute(db) + .await + .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; + Ok(IResultPass { pass: true }) +} +pub async fn lib_model_farm_location_unset( + db: &DatabaseConnection, + opts: IFarmLocationRelation, +) -> Result<IFarmLocationResolve, ModelError> { + let (bv_farm_k, bv_farm) = farm_query_bind_values(opts.farm); + let (bv_lg_k, bv_lg) = location_gcs_query_bind_values(opts.location_gcs); + let query_vals = vec![bv_farm, bv_lg]; + let query = format!("DELETE FROM farm_location WHERE tb_farm = (SELECT id FROM farm WHERE {} = ?) AND tb_lg = (SELECT id FROM location_gcs WHERE {} = ?);", bv_farm_k, bv_lg_k); + let mut query_builder = sqlx::query(&query); + for value in query_vals.iter() { + query_builder = query_builder.bind(value); + } + query_builder + .execute(db) + .await + .map_err(|e| ModelError::InvalidQuery(e.to_string()))?; + Ok(IResultPass { pass: true }) +} diff --git a/crates/model/src/tables/location_gcs.rs b/crates/model/src/tables/location_gcs.rs @@ -14,7 +14,7 @@ pub struct LocationGcs { lat: f64, lng: f64, geohash: String, - kind: String, + tag_0: Option<String>, label: Option<String>, area: Option<f64>, elevation: Option<u32>, @@ -33,7 +33,7 @@ pub struct ILocationGcsFields { pub lat: f64, pub lng: f64, pub geohash: String, - pub kind: String, + pub tag_0: Option<String>, pub label: Option<String>, pub area: Option<f64>, pub elevation: Option<u32>, @@ -52,7 +52,7 @@ pub struct ILocationGcsFieldsPartial { pub lat: Option<f64>, pub lng: Option<f64>, pub geohash: Option<String>, - pub kind: Option<String>, + pub tag_0: Option<String>, pub label: Option<String>, pub area: Option<f64>, pub elevation: Option<u32>, @@ -73,7 +73,7 @@ pub struct ILocationGcsFieldsFilter { pub lat: Option<String>, pub lng: Option<String>, pub geohash: Option<String>, - pub kind: Option<String>, + pub tag_0: Option<String>, pub label: Option<String>, pub area: Option<String>, pub elevation: Option<String>, diff --git a/crates/model/src/tables/mod.rs b/crates/model/src/tables/mod.rs @@ -1,6 +1,8 @@ use crate::{error::ModelError, types::DatabaseConnection}; use tangle_core::types::IResultPass; +pub mod farm; +pub mod farm_location; pub mod location_gcs; pub mod log_error; pub mod media_image; @@ -12,7 +14,7 @@ pub mod trade_product_location; pub mod trade_product_media; pub async fn lib_model_tables_reset(db: &DatabaseConnection) -> Result<IResultPass, ModelError> { - let query = format!("DELETE FROM location_gcs; DELETE FROM trade_product; DELETE FROM nostr_profile; DELETE FROM nostr_relay; DELETE FROM media_image; DELETE FROM log_error;DELETE FROM nostr_profile_relay; DELETE FROM trade_product_location; DELETE FROM trade_product_media;"); + let query = format!("DELETE FROM location_gcs; DELETE FROM trade_product; DELETE FROM nostr_profile; DELETE FROM nostr_relay; DELETE FROM media_image; DELETE FROM log_error; DELETE FROM farm;DELETE FROM nostr_profile_relay; DELETE FROM farm_location; DELETE FROM trade_product_location; DELETE FROM trade_product_media;"); sqlx::query(&query) .execute(db) .await diff --git a/crates/tangle/icons/icon.icns b/crates/tangle/icons/icon.icns Binary files differ. diff --git a/crates/tangle/migrations/down/0007_farm.sql b/crates/tangle/migrations/down/0007_farm.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS farm; +\ No newline at end of file diff --git a/crates/tangle/migrations/down/0007_nostr_profile_relay.sql b/crates/tangle/migrations/down/0008_nostr_profile_relay.sql diff --git a/crates/tangle/migrations/down/0009_farm_location.sql b/crates/tangle/migrations/down/0009_farm_location.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS farm_location; +\ No newline at end of file diff --git a/crates/tangle/migrations/down/0008_trade_product_location.sql b/crates/tangle/migrations/down/0010_trade_product_location.sql diff --git a/crates/tangle/migrations/down/0009_trade_product_media.sql b/crates/tangle/migrations/down/0011_trade_product_media.sql diff --git a/crates/tangle/migrations/up/0001_location_gcs.sql b/crates/tangle/migrations/up/0001_location_gcs.sql @@ -5,7 +5,7 @@ CREATE TABLE IF NOT EXISTS location_gcs ( lat REAL NOT NULL, lng REAL NOT NULL, geohash TEXT, - kind TEXT NOT NULL, + tag_0 TEXT, label TEXT, area REAL, elevation INTEGER, diff --git a/crates/tangle/migrations/up/0007_farm.sql b/crates/tangle/migrations/up/0007_farm.sql @@ -0,0 +1,10 @@ +CREATE TABLE IF NOT EXISTS farm ( + id CHAR(36) PRIMARY KEY NOT NULL UNIQUE CHECK(length(id) = 36), + created_at DATETIME NOT NULL CHECK(length(created_at) = 24), + updated_at DATETIME NOT NULL CHECK(length(updated_at) = 24), + name TEXT NOT NULL, + area TEXT, + area_unit TEXT, + title TEXT, + description TEXT +); +\ No newline at end of file diff --git a/crates/tangle/migrations/up/0007_nostr_profile_relay.sql b/crates/tangle/migrations/up/0008_nostr_profile_relay.sql diff --git a/crates/tangle/migrations/up/0009_farm_location.sql b/crates/tangle/migrations/up/0009_farm_location.sql @@ -0,0 +1,7 @@ +CREATE TABLE IF NOT EXISTS farm_location ( + tb_farm CHAR(36), + tb_lg CHAR(36), + FOREIGN KEY (tb_farm) REFERENCES farm(id) ON DELETE CASCADE, + FOREIGN KEY (tb_lg) REFERENCES location_gcs(id) ON DELETE CASCADE, + PRIMARY KEY (tb_farm, tb_lg) +); +\ No newline at end of file diff --git a/crates/tangle/migrations/up/0008_trade_product_location.sql b/crates/tangle/migrations/up/0010_trade_product_location.sql diff --git a/crates/tangle/migrations/up/0009_trade_product_media.sql b/crates/tangle/migrations/up/0011_trade_product_media.sql diff --git a/crates/tangle/src/commands/model/farm.rs b/crates/tangle/src/commands/model/farm.rs @@ -0,0 +1,60 @@ +use crate::app::Tangle; +use tangle_core::types::IError; +use tangle_model::{ + tables::farm::{lib_model_farm_create, IFarmCreate, IFarmCreateResolve, lib_model_farm_read, IFarmRead, IFarmReadResolve, lib_model_farm_read_list, IFarmReadList, IFarmReadListResolve, lib_model_farm_delete, IFarmDelete, IFarmDeleteResolve, lib_model_farm_update, IFarmUpdate, IFarmUpdateResolve}, +}; + +#[tauri::command(rename_all = "snake_case")] +pub async fn model_farm_create( + state: tauri::State<'_, Tangle>, + args: IFarmCreate, +) -> Result<IFarmCreateResolve, IError> { + match lib_model_farm_create(&state.db, args).await { + Ok(result) => Ok(result), + Err(e) => Err(IError { err: e.to_string() }), + } +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn model_farm_read( + state: tauri::State<'_, Tangle>, + args: IFarmRead, +) -> Result<IFarmReadResolve, IError> { + match lib_model_farm_read(&state.db, args).await { + Ok(result) => Ok(result), + Err(e) => Err(IError { err: e.to_string() }), + } +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn model_farm_read_list( + state: tauri::State<'_, Tangle>, + args: IFarmReadList, +) -> Result<IFarmReadListResolve, IError> { + match lib_model_farm_read_list(&state.db, args).await { + Ok(result) => Ok(result), + Err(e) => Err(IError { err: e.to_string() }), + } +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn model_farm_update( + state: tauri::State<'_, Tangle>, + args: IFarmUpdate, +) -> Result<IFarmUpdateResolve, IError> { + match lib_model_farm_update(&state.db, args).await { + Ok(result) => Ok(result), + Err(e) => Err(IError { err: e.to_string() }), + } +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn model_farm_delete( + state: tauri::State<'_, Tangle>, + args: IFarmDelete, +) -> Result<IFarmDeleteResolve, IError> { + match lib_model_farm_delete(&state.db, args).await { + Ok(result) => Ok(result), + Err(e) => Err(IError { err: e.to_string() }), + } +} +\ No newline at end of file diff --git a/crates/tangle/src/commands/model/farm_location.rs b/crates/tangle/src/commands/model/farm_location.rs @@ -0,0 +1,28 @@ +use crate::app::Tangle; +use tangle_core::types::IError; +use tangle_model::tables::farm_location::{ + lib_model_farm_location_set, lib_model_farm_location_unset, + IFarmLocationRelation, IFarmLocationResolve, +}; + +#[tauri::command(rename_all = "snake_case")] +pub async fn model_farm_location_set( + state: tauri::State<'_, Tangle>, + args: IFarmLocationRelation, +) -> Result<IFarmLocationResolve, IError> { + match lib_model_farm_location_set(&state.db, args).await { + Ok(result) => Ok(result), + Err(e) => Err(IError { err: e.to_string() }), + } +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn model_farm_location_unset( + state: tauri::State<'_, Tangle>, + args: IFarmLocationRelation, +) -> Result<IFarmLocationResolve, IError> { + match lib_model_farm_location_unset(&state.db, args).await { + Ok(result) => Ok(result), + Err(e) => Err(IError { err: e.to_string() }), + } +} +\ No newline at end of file diff --git a/crates/tangle/src/commands/model/mod.rs b/crates/tangle/src/commands/model/mod.rs @@ -2,6 +2,8 @@ use crate::app::Tangle; use tangle_core::types::{IError, IResultPass}; use tangle_model::tables::lib_model_tables_reset; +pub(crate) mod farm; +pub(crate) mod farm_location; pub(crate) mod location_gcs; pub(crate) mod log_error; pub(crate) mod media_image; diff --git a/crates/tangle/src/lib.rs b/crates/tangle/src/lib.rs @@ -7,6 +7,13 @@ use commands::keys::{ keys_nostr_add, keys_nostr_delete, keys_nostr_gen, keys_nostr_keystore_reset, keys_nostr_read, keys_nostr_read_all, }; +use commands::model::farm::{ + model_farm_create, model_farm_delete, model_farm_read, + model_farm_read_list, model_farm_update, + }; +use commands::model::farm_location::{ + model_farm_location_set, model_farm_location_unset, + }; use commands::model::location_gcs::{ model_location_gcs_create, model_location_gcs_delete, model_location_gcs_read, model_location_gcs_read_list, model_location_gcs_update, @@ -84,6 +91,13 @@ pub fn run() { }) .invoke_handler(tauri::generate_handler![ // %model% + model_farm_create, + model_farm_delete, + model_farm_location_set, + model_farm_location_unset, + model_farm_read, + model_farm_read_list, + model_farm_update, model_location_gcs_create, model_location_gcs_delete, model_location_gcs_read, diff --git a/crates/tangle/src/util.rs b/crates/tangle/src/util.rs @@ -12,7 +12,7 @@ pub async fn init_db(data_dir: &PathBuf) -> DatabaseConnection { panic!("Error resolving databse directory {}", e); } }; - path.push("radroots_db2.sqlite"); + path.push("tangle.db"); let result = OpenOptions::new().create_new(true).write(true).open(&path); match result { Ok(_) => println!("Database file created"),