Compare commits

...

3 Commits

Author SHA1 Message Date
2d6620faa6 implemented get_path_by_id and get_all_paths 2025-10-27 21:30:57 +01:00
8c9b735d75 init devenv 2025-10-27 19:46:35 +01:00
7e34770ae6 add gitigonore 2025-10-27 19:46:18 +01:00
15 changed files with 448 additions and 4 deletions

10
.envrc Normal file
View File

@@ -0,0 +1,10 @@
export DIRENV_WARN_TIMEOUT=20s
eval "$(devenv direnvrc)"
# `use devenv` supports the same options as the `devenv shell` command.
#
# To silence the output, use `--quiet`.
#
# Example usage: use devenv --quiet --impure --option services.postgres.enable:bool true
use devenv

10
.gitignore vendored
View File

@@ -22,3 +22,13 @@ dist-ssr
*.njsproj
*.sln
*.sw?
# Devenv
.devenv*
devenv.local.nix
devenv.local.yaml
# direnv
.direnv
# pre-commit
.pre-commit-config.yaml

103
devenv.lock Normal file
View File

@@ -0,0 +1,103 @@
{
"nodes": {
"devenv": {
"locked": {
"dir": "src/modules",
"lastModified": 1761343822,
"owner": "cachix",
"repo": "devenv",
"rev": "679d2951cee2d09da3c732d00b320ce752d21ee0",
"type": "github"
},
"original": {
"dir": "src/modules",
"owner": "cachix",
"repo": "devenv",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1747046372,
"owner": "edolstra",
"repo": "flake-compat",
"rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"git-hooks": {
"inputs": {
"flake-compat": "flake-compat",
"gitignore": "gitignore",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1760663237,
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "ca5b894d3e3e151ffc1db040b6ce4dcc75d31c37",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "git-hooks.nix",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"git-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1758532697,
"owner": "cachix",
"repo": "devenv-nixpkgs",
"rev": "207a4cb0e1253c7658c6736becc6eb9cace1f25f",
"type": "github"
},
"original": {
"owner": "cachix",
"ref": "rolling",
"repo": "devenv-nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"devenv": "devenv",
"git-hooks": "git-hooks",
"nixpkgs": "nixpkgs",
"pre-commit-hooks": [
"git-hooks"
]
}
}
},
"root": "root",
"version": 7
}

32
devenv.nix Normal file
View File

@@ -0,0 +1,32 @@
{
pkgs,
lib,
config,
...
}:
{
# https://devenv.sh/languages/
languages = {
rust.enable = true;
javascript.enable = true;
};
# https://devenv.sh/packages/
packages = [
pkgs.nodejs
pkgs.yarn
pkgs.wabt # Wasm dependencies for Tauri
pkgs.glib
pkgs.gtk3
pkgs.webkitgtk_4_1
pkgs.zed-editor
pkgs.openssl_3
# pkgs.webkitgtk # Linux Tauri dependency (Webview2 is the one used on Widnows)
];
enterShell = ''
zsh
exit
'';
}

15
devenv.yaml Normal file
View File

@@ -0,0 +1,15 @@
# yaml-language-server: $schema=https://devenv.sh/devenv.schema.json
inputs:
nixpkgs:
url: github:cachix/devenv-nixpkgs/rolling
# If you're using non-OSS software, you can set allowUnfree to true.
# allowUnfree: true
# If you're willing to use a package that's vulnerable
# permittedInsecurePackages:
# - "openssl-1.1.1w"
# If you have more than one devenv you can merge them
#imports:
# - ./backend

100
flake.lock generated Normal file
View File

@@ -0,0 +1,100 @@
{
"nodes": {
"fenix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"rust-analyzer-src": "rust-analyzer-src"
},
"locked": {
"lastModified": 1756795219,
"narHash": "sha256-tKBQtz1JLKWrCJUxVkHKR+YKmVpm0KZdJdPWmR2slQ8=",
"owner": "nix-community",
"repo": "fenix",
"rev": "80dbdab137f2809e3c823ed027e1665ce2502d74",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "fenix",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1756819007,
"narHash": "sha256-12V64nKG/O/guxSYnr5/nq1EfqwJCdD2+cIGmhz3nrE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "aaff8c16d7fc04991cac6245bee1baa31f72b1e1",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"fenix": "fenix",
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
},
"rust-analyzer-src": {
"flake": false,
"locked": {
"lastModified": 1756597274,
"narHash": "sha256-wfaKRKsEVQDB7pQtAt04vRgFphkVscGRpSx3wG1l50E=",
"owner": "rust-lang",
"repo": "rust-analyzer",
"rev": "21614ed2d3279a9aa1f15c88d293e65a98991b30",
"type": "github"
},
"original": {
"owner": "rust-lang",
"ref": "nightly",
"repo": "rust-analyzer",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

111
flake.nix Normal file
View File

@@ -0,0 +1,111 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
flake-utils.url = "github:numtide/flake-utils";
fenix.url = "github:nix-community/fenix";
fenix.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = {
self,
nixpkgs,
flake-utils,
fenix,
}:
flake-utils.lib.eachDefaultSystem (system: let
pkgs = import nixpkgs {
system = system;
config.allowUnfree = true;
# config.android_sdk.accept_license = true;
};
# android_sdk =
# (pkgs.androidenv.composeAndroidPackages {
# platformVersions = ["34"];
# ndkVersions = ["26.3.11579264"];
# includeNDK = true;
# useGoogleAPIs = false;
# useGoogleTVAddOns = false;
# includeEmulator = false;
# includeSystemImages = false;
# includeSources = false;
# })
# .androidsdk;
packages = with pkgs; [
curl
wget
pkg-config
nodejs_20
# typescript-language-server
# vtsls
# vue-language-server
zed-editor
# (vscode-with-extensions.override {
# # vscode = vscodium;
# vscodeExtensions = with vscode-extensions; [
# vscodevim.vim
# vue.volar
# catppuccin.catppuccin-vsc
# github.copilot
# github.copilot-chat
# tauri-apps.tauri-vscode
# rust-lang.rust-analyzer
# ] ++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [
# # {
# # name = "vscode-arduino-community";
# # publisher = "vscode-arduino";
# # version = "0.7.2";
# # sha256 = "/HdPJ6LBnyPhz7jeJ0MLRXO2L3bcAzM7J65nKsXsacY=";
# # }
# ];
# })
(with fenix.packages.${system};
combine [
complete.rustc
complete.cargo
complete.clippy
# targets.aarch64-linux-android.latest.rust-std
# targets.armv7-linux-androideabi.latest.rust-std
# targets.i686-linux-android.latest.rust-std
targets.x86_64-linux-android.latest.rust-std
])
rust-analyzer
sqlx-cli
# android_sdk
jdk
];
libraries = with pkgs; [
gtk3
libsoup_3
webkitgtk_4_1
cairo
gdk-pixbuf
glib
dbus
openssl
librsvg
];
in {
devShell = pkgs.mkShell {
buildInputs = packages ++ libraries;
shellHook = ''
zsh
exit
'';
LD_LIBRARY_PATH = "${pkgs.lib.makeLibraryPath libraries}:$LD_LIBRARY_PATH";
XDG_DATA_DIRS = "${pkgs.gsettings-desktop-schemas}/share/gsettings-schemas/${pkgs.gsettings-desktop-schemas.name}:${pkgs.gtk3}/share/gsettings-schemas/${pkgs.gtk3.name}:$XDG_DATA_DIRS";
# ANDROID_HOME = "${android_sdk}/libexec/android-sdk";
# NDK_HOME = "${android_sdk}/libexec/android-sdk/ndk/26.3.11579264";
# GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${android_sdk}/libexec/android-sdk/build-tools/34.0.0/aapt2";
};
});
}

View File

@@ -2,6 +2,9 @@
use sqlx::{migrate::MigrateDatabase, sqlite::SqlitePoolOptions, Pool, Sqlite};
use tauri::{App, Manager};
mod repositories;
mod models;
// #[tauri::command]
// fn greet(name: &str) -> String {
// format!("Hello, {}! You've been greeted from Rust!", name)
@@ -69,7 +72,7 @@ pub fn run() {
])
.setup(|app| {
tauri::async_runtime::block_on(async move {
let db = setup_db(&app).await;
let db = setup_db(app).await;
app.manage(AppState { db });
});

View File

@@ -0,0 +1,6 @@
pub struct Exercise {
id: u16,
ex_type: String,
content: String,
node_id: u32
}

View File

@@ -0,0 +1,3 @@
pub mod path;
pub mod node;
pub mod exercise;

View File

@@ -0,0 +1,6 @@
pub struct Node {
id: u32,
title: String,
description: String,
path_id: String
}

View File

@@ -0,0 +1,12 @@
#[derive(Debug, sqlx::FromRow)]
pub struct Path {
id: String,
title: String,
description: String,
}
pub struct PathVersions {
path_id: String,
version_number: String,
}

View File

@@ -0,0 +1 @@
pub mod path_repository;

View File

@@ -1,11 +1,43 @@
use sqlx::sqlite::{SqlitePool};
use sqlx::{pool, sqlite::SqlitePool, FromRow};
use crate::models::path::Path;
pub struct PathRepository<'a> {
pub pool: &'a SqlitePool,
}
impl<'a> PathRepository<'a> {
pub fn get_path_by_id(&self, id: i32) -> Result<Path>{
pub async fn get_path_by_id(&self, id: i32) -> Result<Path, String> {
let result = sqlx::query("SELECT * FROM path WHERE id = ?")
.bind(id)
.fetch_all(self.pool)
.await
.map_err(|e| format!("ERROR: Failed to query Path db: {} ", e))
.unwrap();
if result.len() > 1 {
return Err(format!("ERROR: Multiple paths for ID {} found", id));
} else if result.is_empty(){
return Err(format!("ERROR: No Path with ID {} found", id));
}
let path = match result.first() {
Some(p) => match Path::from_row(p) {
Ok(p) => {p},
Err(e) => {return Err(format!("ERROR: Could not parse Path: {}", e));},
},
None => return Err(format!("ERROR: No path for ID {} found", id)),
};
Ok(path)
}
}
pub async fn get_all_paths(&self) -> Result<Vec<Path>, String> {
let rows = sqlx::query_as::<_, Path>("SELECT * FROM paths")
.fetch_all(self.pool)
.await
.map_err(|e| e.to_string())?;
Ok(rows)
}
}

View File