diff --git a/package-lock.json b/package-lock.json index dbc66a11..0de6c1fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2473,418 +2473,6 @@ } } }, - "node_modules/@radix-ui/react-popover": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.0.tgz", - "integrity": "sha512-2wdgj6eKNVoFNFtYv2xwkzhIJPlJ5L2aV0eKTZHi5dUVrGy+MhgoV8IyyeFpkZQrwwFzbFlnWl1bwyjVBCNapQ==", - "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-dismissable-layer": "1.1.0", - "@radix-ui/react-focus-guards": "1.1.0", - "@radix-ui/react-focus-scope": "1.1.0", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-popper": "1.2.0", - "@radix-ui/react-portal": "1.1.0", - "@radix-ui/react-presence": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-slot": "1.1.0", - "@radix-ui/react-use-controllable-state": "1.1.0", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.5.7" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/primitive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", - "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==" - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-arrow": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz", - "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==", - "dependencies": { - "@radix-ui/react-primitive": "2.0.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", - "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-context": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", - "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz", - "integrity": "sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==", - "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-escape-keydown": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-focus-guards": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz", - "integrity": "sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-focus-scope": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz", - "integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-callback-ref": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-id": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", - "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", - "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-popper": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz", - "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==", - "dependencies": { - "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0", - "@radix-ui/react-use-rect": "1.1.0", - "@radix-ui/react-use-size": "1.1.0", - "@radix-ui/rect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-portal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.0.tgz", - "integrity": "sha512-0tXZ5O6qAVvuN9SWP0X+zadHf9hzHiMf/vxOU+kXO+fbtS8lS57MXa6EmikDxk9s/Bmkk80+dcxgbvisIyeqxg==", - "dependencies": { - "@radix-ui/react-primitive": "2.0.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-presence": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz", - "integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", - "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", - "dependencies": { - "@radix-ui/react-slot": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-slot": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", - "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-callback-ref": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", - "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-controllable-state": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", - "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", - "dependencies": { - "@radix-ui/react-use-callback-ref": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-escape-keydown": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz", - "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==", - "dependencies": { - "@radix-ui/react-use-callback-ref": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-layout-effect": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", - "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-rect": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz", - "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==", - "dependencies": { - "@radix-ui/rect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-size": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", - "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", - "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/rect": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz", - "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==" - }, - "node_modules/@radix-ui/react-popover/node_modules/react-remove-scroll": { - "version": "2.5.7", - "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz", - "integrity": "sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==", - "dependencies": { - "react-remove-scroll-bar": "^2.3.4", - "react-style-singleton": "^2.2.1", - "tslib": "^2.1.0", - "use-callback-ref": "^1.3.0", - "use-sidecar": "^1.1.2" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-popper": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz", @@ -5042,19 +4630,6 @@ } } }, - "node_modules/cmdk": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.0.0.tgz", - "integrity": "sha512-gDzVf0a09TvoJ5jnuPvygTB77+XdOSwEmJ88L6XPFPlv7T3RxbP9jgenfylrAMD0+Le1aO0nVjQUzl2g+vjz5Q==", - "dependencies": { - "@radix-ui/react-dialog": "1.0.5", - "@radix-ui/react-primitive": "1.0.3" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, "node_modules/codemirror": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz", diff --git a/src-tauri/src/db/mod.rs b/src-tauri/src/db/mod.rs index c2383cdc..b7939e61 100644 --- a/src-tauri/src/db/mod.rs +++ b/src-tauri/src/db/mod.rs @@ -2,6 +2,7 @@ pub mod notes; pub mod notes_tags; pub mod settings; pub mod tags; +pub mod queries; use rusqlite::{params, Connection, Result}; diff --git a/src-tauri/src/db/notes.rs b/src-tauri/src/db/notes.rs index b16c91d1..cc3212b7 100644 --- a/src-tauri/src/db/notes.rs +++ b/src-tauri/src/db/notes.rs @@ -1,3 +1,9 @@ +use crate::db::queries::{ + DELETE_FTS_NOTE, DELETE_NOTE, DELETE_NOTE_TAGS, DELETE_TRASHED_NOTE, GET_NOTE, INSERT_FTS_NOTE, + INSERT_NOTE, LIST_ALL_NOTES, LIST_ALL_NOTES_BY_TAG, LIST_ALL_TRASHED_NOTES, + LIST_ALL_TRASHED_NOTES_BY_TAG, SEARCH_NOTES, TRASH_NOTE, TRASH_NOTE_TAGS, UPDATE_FTS_NOTE, + UPDATE_NOTE, +}; use crate::models::{CreateNoteRequest, ListNotesRequest, Note, UpdateNoteRequest}; use crate::utils::parse_datetime; use rusqlite::{params, Connection, Result}; // Import the Note struct @@ -8,12 +14,11 @@ use super::list_tags_for_note; pub fn create_note(conn: &Connection, create_note_request: &CreateNoteRequest) -> Result { let now = Utc::now().to_rfc3339(); - let sql = "INSERT INTO notes (content, created_at, modified_at) VALUES (?1, ?2, ?3)"; + let sql = INSERT_NOTE; conn.execute(sql, params![&create_note_request.content, &now, &now,]) .unwrap(); let rowid = conn.last_insert_rowid(); - let sql_fts5 = - "INSERT INTO notes_fts (rowid, content, created_at, modified_at) VALUES (?1, ?2, ?3, ?4)"; + let sql_fts5 = INSERT_FTS_NOTE; conn.execute( sql_fts5, params![rowid, &create_note_request.content, &now, &now,], @@ -52,14 +57,10 @@ pub fn list_all_notes( if tag_id != -1 { // If tag_id is valid, add it to the parameters vector params_vec.push(&tag_id); - stmt = conn.prepare( - "SELECT n.id, n.content, n.created_at, n.modified_at FROM notes n JOIN notes_tags nt ON n.id = nt.note_id WHERE nt.tag_id = ?3 ORDER BY n.modified_at DESC LIMIT ?1 OFFSET ?2", - )?; + stmt = conn.prepare(LIST_ALL_NOTES_BY_TAG)?; } else { // No need to add parameters if tag_id is -1 - stmt = conn.prepare( - "SELECT id, content, created_at, modified_at FROM notes ORDER BY modified_at DESC LIMIT ?1 OFFSET ?2", - )?; + stmt = conn.prepare(LIST_ALL_NOTES)?; } // TODO: search with active tag @@ -68,9 +69,7 @@ pub fn list_all_notes( if search != "" { params_vec.push(&search); - stmt = conn.prepare( - "SELECT rowid, content, created_at, modified_at FROM notes_fts WHERE notes_fts MATCH ?3 ORDER BY modified_at DESC LIMIT ?1 OFFSET ?2", - )?; + stmt = conn.prepare(SEARCH_NOTES)?; } println!("search: {}", search); @@ -97,8 +96,7 @@ pub fn list_all_notes( } pub fn get_note_by_id(conn: &Connection, note_id: &i64) -> Result { - let mut stmt = - conn.prepare("SELECT id, content, created_at, modified_at FROM notes WHERE id = ?1")?; + let mut stmt = conn.prepare(GET_NOTE)?; stmt.query_row(params![note_id], |row| { let created_at: String = row.get(2)?; let modified_at: String = row.get(3)?; @@ -113,7 +111,7 @@ pub fn get_note_by_id(conn: &Connection, note_id: &i64) -> Result { } pub fn update_note(conn: &Connection, update_note_request: &UpdateNoteRequest) -> Result { - let sql = "UPDATE notes SET content = ?1, modified_at = ?2 WHERE id = ?3"; + let sql = UPDATE_NOTE; conn.execute( sql, params![ @@ -124,7 +122,7 @@ pub fn update_note(conn: &Connection, update_note_request: &UpdateNoteRequest) - ) .unwrap(); - let sql_fts5 = "UPDATE notes_fts SET content = ?1, modified_at = ?2 WHERE rowid = ?3"; + let sql_fts5 = UPDATE_FTS_NOTE; conn.execute( sql_fts5, params![ @@ -139,7 +137,7 @@ pub fn update_note(conn: &Connection, update_note_request: &UpdateNoteRequest) - } pub fn delete_note(conn: &Connection, note_id: &i64) -> () { - let sql = "DELETE FROM trashed_notes WHERE id = ?1"; + let sql = DELETE_TRASHED_NOTE; conn.execute(sql, params![note_id]).unwrap(); } @@ -147,8 +145,7 @@ pub fn trash_note(conn: &Connection, note_id: &i64) -> () { let now = Utc::now().to_rfc3339(); match get_note_by_id(&conn, ¬e_id) { Ok(note) => { - let sql = - "INSERT INTO trashed_notes (note_id, content, created_at, trashed_at) VALUES (?1, ?2, ?3, ?4)"; + let sql = TRASH_NOTE; conn.execute( sql, params![note.id, note.content, note.created_at.to_rfc3339(), &now,], @@ -158,19 +155,17 @@ pub fn trash_note(conn: &Connection, note_id: &i64) -> () { match list_tags_for_note(&conn, ¬e_id) { Ok(tags) => { tags.iter().for_each(|tag_id| { - let sql = - "INSERT INTO trashed_notes_tags (trashed_note_id, tag_id) VALUES (?1, ?2)"; - conn.execute(sql, params![trashed_note_id, tag_id]) - .unwrap(); + let sql = TRASH_NOTE_TAGS; + conn.execute(sql, params![trashed_note_id, tag_id]).unwrap(); }); - let sql = "DELETE FROM notes_tags WHERE note_id = ?1"; + let sql = DELETE_NOTE_TAGS; conn.execute(sql, params![note_id]).unwrap(); } Err(e) => (), } - let sql = "DELETE FROM notes WHERE id = ?1"; + let sql = DELETE_NOTE; conn.execute(sql, params![note_id]).unwrap(); - let sql_fts5 = "DELETE FROM notes_fts WHERE rowid = ?1"; + let sql_fts5 = DELETE_FTS_NOTE; conn.execute(sql_fts5, params![note_id]).unwrap(); } Err(e) => (), @@ -191,14 +186,10 @@ pub fn list_trashed_notes( if tag_id != -1 { // If tag_id is valid, add it to the parameters vector params_vec.push(&tag_id); - stmt = conn.prepare( - "SELECT an.id, an.note_id, an.content, an.created_at, an.trashed_at FROM trashed_notes an JOIN trashed_notes_tags ant ON an.id = ant.note_id WHERE ant.tag_id = ?1 ORDER BY an.trashed_at DESC", - )?; + stmt = conn.prepare(LIST_ALL_TRASHED_NOTES_BY_TAG)?; } else { // No need to add parameters if tag_id is -1 - stmt = conn.prepare( - "SELECT id, note_id, content, created_at, trashed_at FROM trashed_notes ORDER BY trashed_at DESC", - )?; + stmt = conn.prepare(LIST_ALL_TRASHED_NOTES)?; } // Use params_vec.as_slice() when you need to pass the parameters diff --git a/src-tauri/src/db/notes_tags.rs b/src-tauri/src/db/notes_tags.rs index f8d7d969..fcfeb395 100644 --- a/src-tauri/src/db/notes_tags.rs +++ b/src-tauri/src/db/notes_tags.rs @@ -1,3 +1,7 @@ +use crate::db::queries::{ + TAG_NOTE, LIST_TAGS_FOR_NOTE, LIST_NOTES_FOR_TAG, UNTAG_NOTE +}; + use rusqlite::{params, Connection, Result}; use crate::models::TagNoteRequest; @@ -6,13 +10,13 @@ use crate::models::TagNoteRequest; pub fn tag_note(conn: &Connection, tag_note_request: &TagNoteRequest) -> Result { let note_id = tag_note_request.note_id; let tag_id = tag_note_request.tag_id; - let sql = "INSERT INTO notes_tags (note_id, tag_id) VALUES (?1, ?2)"; + let sql = TAG_NOTE; conn.execute(sql, params![note_id, tag_id]) } // Function to list all tags for a given note_id pub fn list_tags_for_note(conn: &Connection, note_id: &i64) -> Result> { - let mut stmt = conn.prepare("SELECT tag_id FROM notes_tags WHERE note_id = ?1")?; + let mut stmt = conn.prepare(LIST_TAGS_FOR_NOTE)?; let tag_iter = stmt.query_map(params![note_id], |row| row.get(0))?; tag_iter.collect() @@ -20,7 +24,7 @@ pub fn list_tags_for_note(conn: &Connection, note_id: &i64) -> Result> // Function to list all notes for a given tag_id pub fn list_notes_for_tag(conn: &Connection, tag_id: &i64) -> Result> { - let mut stmt = conn.prepare("SELECT note_id FROM notes_tags WHERE tag_id = ?1")?; + let mut stmt = conn.prepare(LIST_NOTES_FOR_TAG)?; let note_iter = stmt.query_map(params![tag_id], |row| row.get(0))?; note_iter.collect() @@ -30,6 +34,6 @@ pub fn list_notes_for_tag(conn: &Connection, tag_id: &i64) -> Result> { pub fn untag_note(conn: &Connection, tag_note_request: &TagNoteRequest) -> Result { let note_id = tag_note_request.note_id; let tag_id = tag_note_request.tag_id; - let sql = "DELETE FROM notes_tags WHERE note_id = ?1 AND tag_id = ?2"; + let sql = UNTAG_NOTE; conn.execute(sql, params![note_id, tag_id]) } diff --git a/src-tauri/src/db/queries.rs b/src-tauri/src/db/queries.rs new file mode 100644 index 00000000..f34e779a --- /dev/null +++ b/src-tauri/src/db/queries.rs @@ -0,0 +1,38 @@ +//Notes Queries +pub const INSERT_NOTE: &str = "INSERT INTO notes (content, created_at, modified_at) VALUES (?1, ?2, ?3)"; +pub const INSERT_FTS_NOTE: &str = "INSERT INTO notes_fts (rowid, content, created_at, modified_at) VALUES (?1, ?2, ?3, ?4)"; +pub const LIST_ALL_NOTES: &str = "SELECT id, content, created_at, modified_at FROM notes ORDER BY modified_at DESC LIMIT ?1 OFFSET ?2"; +pub const LIST_ALL_NOTES_BY_TAG: &str = "SELECT n.id, n.content, n.created_at, n.modified_at FROM notes n JOIN notes_tags nt ON n.id = nt.note_id WHERE nt.tag_id = ?3 ORDER BY n.modified_at DESC LIMIT ?1 OFFSET ?2"; +pub const SEARCH_NOTES: &str = "SELECT rowid, content, created_at, modified_at FROM notes_fts WHERE notes_fts MATCH ?3 ORDER BY modified_at DESC LIMIT ?1 OFFSET ?2"; +pub const GET_NOTE: &str = "SELECT id, content, created_at, modified_at FROM notes WHERE id = ?1"; +pub const UPDATE_NOTE: &str = "UPDATE notes SET content = ?1, modified_at = ?2 WHERE id = ?3"; +pub const UPDATE_FTS_NOTE: &str = "UPDATE notes_fts SET content = ?1, modified_at = ?2 WHERE rowid = ?3"; +pub const DELETE_TRASHED_NOTE: &str = "DELETE FROM trashed_notes WHERE id = ?1"; +pub const TRASH_NOTE: &str = "INSERT INTO trashed_notes (note_id, content, created_at, trashed_at) VALUES (?1, ?2, ?3, ?4)"; +pub const TRASH_NOTE_TAGS: &str = "INSERT INTO trashed_notes_tags (trashed_note_id, tag_id) VALUES (?1, ?2)"; +pub const DELETE_NOTE_TAGS: &str = "DELETE FROM notes_tags WHERE note_id = ?1"; +pub const DELETE_NOTE: &str = "DELETE FROM notes WHERE id = ?1"; +pub const DELETE_FTS_NOTE: &str = "DELETE FROM notes_fts WHERE rowid = ?1"; +pub const LIST_ALL_TRASHED_NOTES: &str = "SELECT id, note_id, content, created_at, trashed_at FROM trashed_notes ORDER BY trashed_at DESC"; +pub const LIST_ALL_TRASHED_NOTES_BY_TAG: &str = "SELECT an.id, an.note_id, an.content, an.created_at, an.trashed_at FROM trashed_notes an JOIN trashed_notes_tags ant ON an.id = ant.note_id WHERE ant.tag_id = ?1 ORDER BY an.trashed_at DESC"; + +//Tags Queries +pub const INSERT_TAG: &str = "INSERT INTO tags (name, color, icon, created_at) VALUES (?1, ?2, ?3, ?4)"; +pub const GET_TAG: &str = "SELECT id, name, color, icon, created_at FROM tags WHERE id = ?1"; +pub const GET_TAG_BY_NAME: &str = "SELECT id, name, color, icon, created_at FROM tags WHERE name = ?1"; +pub const LIST_ALL_TAGS: &str = "SELECT t.id, t.name, t.color, t.icon, t.created_at FROM tags t JOIN notes_tags nt ON t.id = nt.tag_id WHERE nt.note_id = ?1 ORDER BY t.name ASC"; +pub const LIST_ALL_TAGS_BY_NOTE: &str = "SELECT id, name, color, icon, created_at FROM tags ORDER BY name ASC"; +pub const UPDATE_TAG: &str = "UPDATE tags SET name = ?1, color = ?2, icon = ?3 WHERE id = ?4"; +pub const DELETE_TAG: &str = "DELETE FROM tags WHERE id = ?1"; + +//Notes Tags Queries +pub const TAG_NOTE: &str = "INSERT INTO notes_tags (note_id, tag_id) VALUES (?1, ?2)"; +pub const LIST_TAGS_FOR_NOTE: &str = "SELECT tag_id FROM notes_tags WHERE note_id = ?1"; +pub const LIST_NOTES_FOR_TAG: &str = "SELECT note_id FROM notes_tags WHERE tag_id = ?1"; +pub const UNTAG_NOTE: &str = "DELETE FROM notes_tags WHERE note_id = ?1 AND tag_id = ?2"; + +//Settings Queries +pub const INSERT_SETTING: &str = "INSERT OR IGNORE INTO settings (key, value) VALUES (?, ?)"; +pub const GET_SETTING: &str = "SELECT value FROM settings WHERE key = ?1"; +pub const SET_SETTING: &str = "INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)"; +pub const LIST_SETTINGS: &str = "SELECT key, value FROM settings"; \ No newline at end of file diff --git a/src-tauri/src/db/settings.rs b/src-tauri/src/db/settings.rs index d93bb40e..84a292fc 100644 --- a/src-tauri/src/db/settings.rs +++ b/src-tauri/src/db/settings.rs @@ -1,3 +1,7 @@ +use crate::db::queries::{ + INSERT_SETTING, GET_SETTING, SET_SETTING, LIST_SETTINGS +}; + use std::collections::HashMap; use rusqlite::{params, Connection, Result}; // Import the Note struct @@ -31,7 +35,7 @@ pub fn insert_initial_settings(conn: &Connection) -> Result<()> { for (key, value) in initial_settings { conn.execute( - "INSERT OR IGNORE INTO settings (key, value) VALUES (?, ?)", + INSERT_SETTING, params![key, value], )?; } @@ -40,13 +44,13 @@ pub fn insert_initial_settings(conn: &Connection) -> Result<()> { } pub fn get_setting(conn: &Connection, key: &str) -> Result { - let mut stmt = conn.prepare("SELECT value FROM settings WHERE key = ?1")?; + let mut stmt = conn.prepare(GET_SETTING)?; stmt.query_row(params![key], |row| Ok(row.get(0)?)) } pub fn set_setting(conn: &Connection, key: &str, value: &str) -> Result<()> { conn.execute( - "INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)", + SET_SETTING, params![key, value], )?; @@ -54,7 +58,7 @@ pub fn set_setting(conn: &Connection, key: &str, value: &str) -> Result<()> { } pub fn get_all_settings(conn: &Connection) -> Result> { - let mut stmt = conn.prepare("SELECT key, value FROM settings")?; + let mut stmt = conn.prepare(LIST_SETTINGS)?; let settings_iter = stmt.query_map(params![], |row| { let key: String = row.get(0)?; let value: String = row.get(1)?; diff --git a/src-tauri/src/db/tags.rs b/src-tauri/src/db/tags.rs index e8036e65..bc39f26f 100644 --- a/src-tauri/src/db/tags.rs +++ b/src-tauri/src/db/tags.rs @@ -1,13 +1,16 @@ +use crate::db::queries::{ + GET_TAG, GET_TAG_BY_NAME, INSERT_TAG, LIST_ALL_TAGS, LIST_ALL_TAGS_BY_NOTE, UPDATE_TAG, DELETE_TAG +}; use crate::{ models::{CreateTagRequest, ListTagsRequest, Tag, UpdateTagRequest}, utils::parse_datetime, }; use chrono::Utc; -use rusqlite::{params, Connection, Result}; // Assuming you have a Tag struct defined in your models +use rusqlite::{params, Connection, Result}; pub fn create_tag(conn: &Connection, create_tag_request: &CreateTagRequest) -> Result { let now = Utc::now().to_rfc3339(); - let sql = "INSERT INTO tags (name, color, icon, created_at) VALUES (?1, ?2, ?3, ?4)"; + let sql = INSERT_TAG; conn.execute( sql, params![ @@ -21,7 +24,7 @@ pub fn create_tag(conn: &Connection, create_tag_request: &CreateTagRequest) -> R } pub fn get_tag_by_id(conn: &Connection, tag_id: i64) -> Result { - let mut stmt = conn.prepare("SELECT id, name, color, icon, created_at FROM tags WHERE id = ?1")?; + let mut stmt = conn.prepare(GET_TAG)?; stmt.query_row(params![tag_id], |row| { let created_at: String = row.get(4)?; Ok(Tag { @@ -35,7 +38,7 @@ pub fn get_tag_by_id(conn: &Connection, tag_id: i64) -> Result { } pub fn get_tag_by_name(conn: &Connection, tag_name: &str) -> Result { - let mut stmt = conn.prepare("SELECT id, name, color, icon, created_at FROM tags WHERE name = ?1")?; + let mut stmt = conn.prepare(GET_TAG_BY_NAME)?; stmt.query_row(params![tag_name], |row| { let created_at: String = row.get(4)?; Ok(Tag { @@ -64,12 +67,12 @@ pub fn list_all_tags( // If note_id is valid, add it to the parameters vector params_vec.push(¬e_id); stmt = conn.prepare( - "SELECT t.id, t.name, t.color, t.icon, t.created_at FROM tags t JOIN notes_tags nt ON t.id = nt.tag_id WHERE nt.note_id = ?1 ORDER BY t.name ASC", + LIST_ALL_TAGS, )?; } else { // No need to add parameters if note_id is -1 stmt = conn.prepare( - "SELECT id, name, color, icon, created_at FROM tags ORDER BY name ASC", + LIST_ALL_TAGS_BY_NOTE, )?; } @@ -94,7 +97,7 @@ pub fn list_all_tags( } pub fn update_tag(conn: &Connection, update_tag_request: &UpdateTagRequest) -> Result { - let sql = "UPDATE tags SET name = ?1, color = ?2, icon = ?3 WHERE id = ?4"; + let sql = UPDATE_TAG; conn.execute( sql, params![ @@ -107,6 +110,6 @@ pub fn update_tag(conn: &Connection, update_tag_request: &UpdateTagRequest) -> R } pub fn delete_tag(conn: &Connection, tag_id: &i64) -> () { - let sql = "DELETE FROM tags WHERE id = ?1"; + let sql = DELETE_TAG; conn.execute(sql, params![tag_id]).unwrap(); }