This commit is contained in:
parent
234a6ebb4b
commit
0ae4b0ba9e
19 changed files with 140 additions and 2575 deletions
|
@ -6,8 +6,6 @@
|
|||
|
||||
# App Developers
|
||||
|
||||
- [`meta.json`](./dev/meta_json.md)
|
||||
- [API Reference](./generated/spec/meta.schema.md)
|
||||
- [App API](./dev/api.md)
|
||||
|
||||
# Core Library Developers
|
||||
|
@ -20,3 +18,4 @@
|
|||
- [Package Ecosystem](./notes/packages.md)
|
||||
- [Types](./notes/types.md)
|
||||
- [Data Integrity](./notes/integrity.md)
|
||||
- [Sled Keyspace](./notes/sledkeys.md)
|
||||
|
|
|
@ -4,4 +4,4 @@ Must include a file called `panorama_version.json` that details information abou
|
|||
|
||||
# Format v0
|
||||
|
||||
Includes an SQLite database called `vault.sqlite`.
|
||||
Includes a sled database.
|
||||
|
|
17
docs/src/notes/sledkeys.md
Normal file
17
docs/src/notes/sledkeys.md
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Sled Keyspace
|
||||
|
||||
Panorama uses [sled] as a keystore.
|
||||
|
||||
The key space looks like:
|
||||
|
||||
- nodes
|
||||
- by-uuid
|
||||
- :uuid
|
||||
- edges
|
||||
- indexes
|
||||
-
|
||||
|
||||
### Indexes
|
||||
|
||||
[sled]: https://github.com/spacejam/sled
|
||||
[cockroachdb-kv]: https://github.com/cockroachdb/cockroach/blob/master/docs/tech-notes/encoding.md
|
|
@ -1,6 +1,8 @@
|
|||
# Data types
|
||||
|
||||
close to javascript types? i guess
|
||||
close to javascript types? i guess. Apps can define these under their own
|
||||
namespace and then refer to them. You can also publish type-only apps, and there
|
||||
will also be some standard ones defined.
|
||||
|
||||
## Primitives
|
||||
|
||||
|
@ -15,8 +17,10 @@ close to javascript types? i guess
|
|||
## Special primitives
|
||||
|
||||
- DateTimeTz
|
||||
|
||||
- Timezone-aware date (internally stored as ISO8601)
|
||||
- There is no non-timezone-aware date. Please use a string type for that
|
||||
|
||||
- Unit
|
||||
- This is essentially a number with an attached unit specifier (string)
|
||||
- Each unit _type_ is distinct, and allows a number of units that can freely
|
||||
|
@ -25,8 +29,9 @@ close to javascript types? i guess
|
|||
- File size (byte, kb, mb, mib, gib, etc.)
|
||||
- Temperature (c, f, k)
|
||||
- Distance (ft, mi, m, km, etc.)
|
||||
- Custom unit conversions can be defined.
|
||||
- Currency is **NOT** considered a unit and has no semantic meaning within the
|
||||
database.
|
||||
database. Please don't add custom conversions for this
|
||||
|
||||
## Type constructors
|
||||
|
||||
|
@ -36,17 +41,11 @@ close to javascript types? i guess
|
|||
- Heterogeneous map
|
||||
- Array
|
||||
- Record
|
||||
- basically matches interface in typescript
|
||||
- Records are not allowed to be fully self-recursive (eg. `record Foo { foo: Foo }`)
|
||||
- Enum
|
||||
- Allowed to be self-recursive, but needs at least one terminating variant
|
||||
|
||||
## Complex type constructors
|
||||
|
||||
- JSON schema
|
||||
|
||||
# Interfaces
|
||||
|
||||
Interfaces approximately match traits in rust, comprised of
|
||||
|
||||
- Associated types
|
||||
- Functions
|
||||
|
||||
TODO: Generics?
|
||||
|
|
|
@ -81,6 +81,8 @@
|
|||
"${pkgs.harfbuzz.dev}/lib/pkgconfig"
|
||||
"${pkgs.at-spi2-atk.dev}/lib/pkgconfig"
|
||||
];
|
||||
|
||||
GIO_MODULE_DIR = "${pkgs.glib-networking}/lib/gio/modules";
|
||||
} // prisma-env);
|
||||
|
||||
ci = pkgs.mkShell { packages = with pkgs; [ bash mdbook nodejs ]; };
|
||||
|
|
1
prisma/.gitignore
vendored
1
prisma/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
/dev.db*
|
|
@ -1,75 +0,0 @@
|
|||
-- CreateTable
|
||||
CREATE TABLE "Node" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"label" TEXT
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Interface" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Edge" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"label" TEXT,
|
||||
"appId" TEXT NOT NULL,
|
||||
"appKey" TEXT NOT NULL,
|
||||
"fromId" TEXT NOT NULL,
|
||||
"toId" TEXT NOT NULL,
|
||||
CONSTRAINT "Edge_appId_fkey" FOREIGN KEY ("appId") REFERENCES "App" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
|
||||
CONSTRAINT "Edge_fromId_fkey" FOREIGN KEY ("fromId") REFERENCES "Node" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
|
||||
CONSTRAINT "Edge_toId_fkey" FOREIGN KEY ("toId") REFERENCES "Node" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "NodeMeta" (
|
||||
"nodeId" TEXT NOT NULL,
|
||||
"appId" TEXT NOT NULL,
|
||||
"appKey" TEXT NOT NULL,
|
||||
"value" BLOB NOT NULL,
|
||||
|
||||
PRIMARY KEY ("nodeId", "appId", "appKey"),
|
||||
CONSTRAINT "NodeMeta_nodeId_fkey" FOREIGN KEY ("nodeId") REFERENCES "Node" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
|
||||
CONSTRAINT "NodeMeta_appId_fkey" FOREIGN KEY ("appId") REFERENCES "App" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "NodeImplements" (
|
||||
"nodeId" TEXT NOT NULL,
|
||||
"interfaceId" TEXT NOT NULL,
|
||||
|
||||
PRIMARY KEY ("nodeId", "interfaceId"),
|
||||
CONSTRAINT "NodeImplements_nodeId_fkey" FOREIGN KEY ("nodeId") REFERENCES "Node" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
|
||||
CONSTRAINT "NodeImplements_interfaceId_fkey" FOREIGN KEY ("interfaceId") REFERENCES "Interface" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "App" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"localName" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"installed" DATETIME NOT NULL
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Patterns" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"pattern" TEXT NOT NULL,
|
||||
"type" TEXT NOT NULL,
|
||||
"appId" TEXT NOT NULL,
|
||||
"functionName" TEXT NOT NULL,
|
||||
CONSTRAINT "Patterns_appId_fkey" FOREIGN KEY ("appId") REFERENCES "App" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Edge_appId_appKey_idx" ON "Edge"("appId", "appKey");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Edge_fromId_toId_key" ON "Edge"("fromId", "toId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "NodeMeta_appId_appKey_idx" ON "NodeMeta"("appId", "appKey");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "App_localName_key" ON "App"("localName");
|
|
@ -1,14 +0,0 @@
|
|||
-- RedefineTables
|
||||
PRAGMA foreign_keys=OFF;
|
||||
CREATE TABLE "new_App" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"localName" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"installed" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
INSERT INTO "new_App" ("id", "installed", "localName", "title") SELECT "id", "installed", "localName", "title" FROM "App";
|
||||
DROP TABLE "App";
|
||||
ALTER TABLE "new_App" RENAME TO "App";
|
||||
CREATE UNIQUE INDEX "App_localName_key" ON "App"("localName");
|
||||
PRAGMA foreign_key_check;
|
||||
PRAGMA foreign_keys=ON;
|
|
@ -1,18 +0,0 @@
|
|||
-- RedefineTables
|
||||
PRAGMA foreign_keys=OFF;
|
||||
CREATE TABLE "new_NodeMeta" (
|
||||
"nodeId" TEXT NOT NULL,
|
||||
"appId" TEXT NOT NULL,
|
||||
"appKey" TEXT NOT NULL,
|
||||
"value" BLOB NOT NULL,
|
||||
|
||||
PRIMARY KEY ("nodeId", "appId", "appKey"),
|
||||
CONSTRAINT "NodeMeta_nodeId_fkey" FOREIGN KEY ("nodeId") REFERENCES "Node" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT "NodeMeta_appId_fkey" FOREIGN KEY ("appId") REFERENCES "App" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||
);
|
||||
INSERT INTO "new_NodeMeta" ("appId", "appKey", "nodeId", "value") SELECT "appId", "appKey", "nodeId", "value" FROM "NodeMeta";
|
||||
DROP TABLE "NodeMeta";
|
||||
ALTER TABLE "new_NodeMeta" RENAME TO "NodeMeta";
|
||||
CREATE INDEX "NodeMeta_appId_appKey_idx" ON "NodeMeta"("appId", "appKey");
|
||||
PRAGMA foreign_key_check;
|
||||
PRAGMA foreign_keys=ON;
|
|
@ -1,3 +0,0 @@
|
|||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (i.e. Git)
|
||||
provider = "sqlite"
|
2365
src-tauri/Cargo.lock
generated
2365
src-tauri/Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -7,10 +7,6 @@ license = ""
|
|||
repository = ""
|
||||
edition = "2021"
|
||||
|
||||
[workspace]
|
||||
members = ["prisma-cli"]
|
||||
resolver = "2"
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "1.3", features = [] }
|
||||
|
||||
|
@ -18,17 +14,10 @@ tauri-build = { version = "1.3", features = [] }
|
|||
tauri = { version = "1.3", features = ["shell-open"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
# TODO: L @ prisma-client-rust not updating to 0.25.x of the sqlite lib
|
||||
sqlx = { version = "0.5", features = ["runtime-tokio-rustls", "sqlite"] }
|
||||
tokio = { version = "1.28.2", features = ["full"] }
|
||||
anyhow = "1.0.71"
|
||||
dirs = "5.0.1"
|
||||
|
||||
[dependencies.prisma-client-rust]
|
||||
git = "https://github.com/Brendonovich/prisma-client-rust"
|
||||
tag = "0.6.8"
|
||||
default-features = false
|
||||
features = ["sqlite"]
|
||||
sled = { version = "0.34.7", features = ["compression"] }
|
||||
|
||||
[features]
|
||||
# this feature is used for production builds or when `devPath` points to the filesystem
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
[package]
|
||||
name = "prisma-cli"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies.prisma-client-rust-cli]
|
||||
git = "https://github.com/Brendonovich/prisma-client-rust"
|
||||
tag = "0.6.8"
|
||||
default-features = false
|
||||
features = ["sqlite"]
|
|
@ -1,3 +0,0 @@
|
|||
fn main() {
|
||||
prisma_client_rust_cli::run();
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
generator client {
|
||||
provider = "cargo prisma"
|
||||
output = "../src/prisma.rs"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "sqlite"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
model Node {
|
||||
id String @id @default(uuid())
|
||||
label String?
|
||||
implements NodeImplements[]
|
||||
|
||||
fromNodes Edge[] @relation(name: "fromNode")
|
||||
toNodes Edge[] @relation(name: "toNode")
|
||||
|
||||
metadata NodeMeta[]
|
||||
}
|
||||
|
||||
model Interface {
|
||||
id String @id @default(uuid())
|
||||
implementors NodeImplements[]
|
||||
}
|
||||
|
||||
model Edge {
|
||||
id String @id @default(uuid())
|
||||
label String?
|
||||
|
||||
/// The app that created this edge
|
||||
app App @relation(fields: [appId], references: [id])
|
||||
appId String
|
||||
|
||||
appKey String
|
||||
|
||||
fromId String
|
||||
fromNode Node @relation(name: "fromNode", fields: [fromId], references: [id])
|
||||
|
||||
toId String
|
||||
toNode Node @relation(name: "toNode", fields: [toId], references: [id])
|
||||
|
||||
directional Boolean
|
||||
|
||||
@@unique([fromId, toId])
|
||||
@@index([appId, appKey])
|
||||
}
|
||||
|
||||
model NodeMeta {
|
||||
nodeId String
|
||||
node Node @relation(fields: [nodeId], references: [id], onDelete: Cascade)
|
||||
|
||||
/// The app that created this metadata field
|
||||
app App @relation(fields: [appId], references: [id])
|
||||
appId String
|
||||
|
||||
appKey String
|
||||
|
||||
value Bytes
|
||||
|
||||
@@id([nodeId, appId, appKey])
|
||||
@@index([appId, appKey])
|
||||
}
|
||||
|
||||
model NodeImplements {
|
||||
nodeId String
|
||||
node Node @relation(fields: [nodeId], references: [id])
|
||||
|
||||
interfaceId String
|
||||
interface Interface @relation(fields: [interfaceId], references: [id])
|
||||
|
||||
@@id([nodeId, interfaceId])
|
||||
}
|
||||
|
||||
model App {
|
||||
id String @id @default(uuid())
|
||||
|
||||
localName String @unique
|
||||
title String
|
||||
|
||||
installed DateTime @default(now())
|
||||
|
||||
patterns Patterns[]
|
||||
metaKeys NodeMeta[]
|
||||
edges Edge[]
|
||||
}
|
||||
|
||||
/// Regular expressions table
|
||||
model Patterns {
|
||||
id String @id @default(uuid())
|
||||
|
||||
pattern String
|
||||
|
||||
/// Pattern type, see docs for details
|
||||
type String
|
||||
|
||||
appId String
|
||||
app App @relation(fields: [appId], references: [id])
|
||||
|
||||
functionName String
|
||||
}
|
||||
|
||||
/// Index table, for keeping track of indexes to build and take down when the database first starts
|
||||
model Indices {
|
||||
id String @id @default(uuid())
|
||||
command String
|
||||
|
||||
// TODO: Does sqlite avoid making duplicate indexes automatically?
|
||||
}
|
|
@ -3,9 +3,6 @@ pub mod meta;
|
|||
use std::{collections::HashMap, env, path::PathBuf};
|
||||
|
||||
use anyhow::Result;
|
||||
use sqlx::SqlitePool;
|
||||
|
||||
use crate::prisma::PrismaClient;
|
||||
|
||||
pub struct Handler {}
|
||||
|
||||
|
@ -16,17 +13,14 @@ pub enum Event {
|
|||
}
|
||||
|
||||
pub struct AppManager {
|
||||
prisma: PrismaClient,
|
||||
apps: Vec<App>,
|
||||
key_handlers: HashMap<(String, Event), Handler>,
|
||||
}
|
||||
|
||||
impl AppManager {
|
||||
pub async fn new() -> Result<Self> {
|
||||
let prisma = PrismaClient::_builder().build().await?;
|
||||
let apps = vec![];
|
||||
Ok(Self {
|
||||
prisma,
|
||||
apps,
|
||||
key_handlers: HashMap::default(),
|
||||
})
|
||||
|
@ -51,9 +45,7 @@ impl AppManager {
|
|||
}
|
||||
|
||||
/// Figure out which indices are required by the set of known apps
|
||||
pub async fn compute_indices(&self) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
pub async fn compute_indices(&self) -> Result<()> { Ok(()) }
|
||||
}
|
||||
|
||||
pub struct App {
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
use sqlx::SqlitePool;
|
||||
use tauri::State;
|
||||
|
||||
pub struct Db(pub SqlitePool);
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct QueryOptions {}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn query(
|
||||
state: State<'_, Db>,
|
||||
options: QueryOptions,
|
||||
) -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
22
src-tauri/src/db.rs
Normal file
22
src-tauri/src/db.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
use anyhow::Result;
|
||||
use sled::Tree;
|
||||
|
||||
pub struct Db {
|
||||
db: sled::Db,
|
||||
node_tree: Tree,
|
||||
}
|
||||
|
||||
impl Db {
|
||||
pub fn create_node(&self) -> Result<()> {
|
||||
let id = self.db.generate_id()?;
|
||||
|
||||
/*
|
||||
self.db.transaction(|tx_db| {
|
||||
tx_db.insert("nodes", &id.to_be_bytes())?;
|
||||
Ok(())
|
||||
})?;
|
||||
*/
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -5,11 +5,9 @@
|
|||
extern crate serde;
|
||||
|
||||
pub mod apps;
|
||||
pub mod dal;
|
||||
pub mod prisma;
|
||||
pub mod db;
|
||||
|
||||
use anyhow::Result;
|
||||
use prisma::PrismaClient;
|
||||
|
||||
use crate::apps::AppManager;
|
||||
|
||||
|
@ -17,22 +15,16 @@ pub use crate::apps::meta::AppMetadata;
|
|||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
// Open database
|
||||
let client = PrismaClient::_builder().build().await?;
|
||||
|
||||
// Register apps
|
||||
let mut app_manager = AppManager::new().await?;
|
||||
app_manager.register().await?;
|
||||
|
||||
// Read indexes
|
||||
let indexes_from_apps = app_manager.compute_indices().await?;
|
||||
let indexes_from_db = client.indices().find_many(vec![]).exec().await?;
|
||||
println!("indexes: {:?}", indexes_from_db);
|
||||
|
||||
tauri::Builder::default()
|
||||
.manage(app_manager)
|
||||
.manage(client)
|
||||
.invoke_handler(tauri::generate_handler![dal::query])
|
||||
.invoke_handler(tauri::generate_handler![])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
|
||||
|
|
Loading…
Reference in a new issue