A personal finance tracker
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Initial Commit

+370
+2
.cargo/config.toml
··· 1 + [env] 2 + CC = "gcc"
+1
.gitignore
··· 1 + target/*
+265
Cargo.lock
··· 1 + # This file is automatically @generated by Cargo. 2 + # It is not intended for manual editing. 3 + version = 4 4 + 5 + [[package]] 6 + name = "bitflags" 7 + version = "2.10.0" 8 + source = "registry+https://github.com/rust-lang/crates.io-index" 9 + checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" 10 + 11 + [[package]] 12 + name = "bumpalo" 13 + version = "3.19.1" 14 + source = "registry+https://github.com/rust-lang/crates.io-index" 15 + checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" 16 + 17 + [[package]] 18 + name = "cc" 19 + version = "1.2.51" 20 + source = "registry+https://github.com/rust-lang/crates.io-index" 21 + checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203" 22 + dependencies = [ 23 + "find-msvc-tools", 24 + "shlex", 25 + ] 26 + 27 + [[package]] 28 + name = "cfg-if" 29 + version = "1.0.4" 30 + source = "registry+https://github.com/rust-lang/crates.io-index" 31 + checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" 32 + 33 + [[package]] 34 + name = "fallible-iterator" 35 + version = "0.3.0" 36 + source = "registry+https://github.com/rust-lang/crates.io-index" 37 + checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" 38 + 39 + [[package]] 40 + name = "fallible-streaming-iterator" 41 + version = "0.1.9" 42 + source = "registry+https://github.com/rust-lang/crates.io-index" 43 + checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" 44 + 45 + [[package]] 46 + name = "find-msvc-tools" 47 + version = "0.1.6" 48 + source = "registry+https://github.com/rust-lang/crates.io-index" 49 + checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff" 50 + 51 + [[package]] 52 + name = "foldhash" 53 + version = "0.2.0" 54 + source = "registry+https://github.com/rust-lang/crates.io-index" 55 + checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" 56 + 57 + [[package]] 58 + name = "hashbrown" 59 + version = "0.16.1" 60 + source = "registry+https://github.com/rust-lang/crates.io-index" 61 + checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" 62 + dependencies = [ 63 + "foldhash", 64 + ] 65 + 66 + [[package]] 67 + name = "hashlink" 68 + version = "0.11.0" 69 + source = "registry+https://github.com/rust-lang/crates.io-index" 70 + checksum = "ea0b22561a9c04a7cb1a302c013e0259cd3b4bb619f145b32f72b8b4bcbed230" 71 + dependencies = [ 72 + "hashbrown", 73 + ] 74 + 75 + [[package]] 76 + name = "hisab" 77 + version = "0.1.0" 78 + dependencies = [ 79 + "rusqlite", 80 + ] 81 + 82 + [[package]] 83 + name = "js-sys" 84 + version = "0.3.83" 85 + source = "registry+https://github.com/rust-lang/crates.io-index" 86 + checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" 87 + dependencies = [ 88 + "once_cell", 89 + "wasm-bindgen", 90 + ] 91 + 92 + [[package]] 93 + name = "libsqlite3-sys" 94 + version = "0.36.0" 95 + source = "registry+https://github.com/rust-lang/crates.io-index" 96 + checksum = "95b4103cffefa72eb8428cb6b47d6627161e51c2739fc5e3b734584157bc642a" 97 + dependencies = [ 98 + "cc", 99 + "pkg-config", 100 + "vcpkg", 101 + ] 102 + 103 + [[package]] 104 + name = "once_cell" 105 + version = "1.21.3" 106 + source = "registry+https://github.com/rust-lang/crates.io-index" 107 + checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 108 + 109 + [[package]] 110 + name = "pkg-config" 111 + version = "0.3.32" 112 + source = "registry+https://github.com/rust-lang/crates.io-index" 113 + checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" 114 + 115 + [[package]] 116 + name = "proc-macro2" 117 + version = "1.0.104" 118 + source = "registry+https://github.com/rust-lang/crates.io-index" 119 + checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0" 120 + dependencies = [ 121 + "unicode-ident", 122 + ] 123 + 124 + [[package]] 125 + name = "quote" 126 + version = "1.0.42" 127 + source = "registry+https://github.com/rust-lang/crates.io-index" 128 + checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" 129 + dependencies = [ 130 + "proc-macro2", 131 + ] 132 + 133 + [[package]] 134 + name = "rusqlite" 135 + version = "0.38.0" 136 + source = "registry+https://github.com/rust-lang/crates.io-index" 137 + checksum = "f1c93dd1c9683b438c392c492109cb702b8090b2bfc8fed6f6e4eb4523f17af3" 138 + dependencies = [ 139 + "bitflags", 140 + "fallible-iterator", 141 + "fallible-streaming-iterator", 142 + "hashlink", 143 + "libsqlite3-sys", 144 + "smallvec", 145 + "sqlite-wasm-rs", 146 + ] 147 + 148 + [[package]] 149 + name = "rustversion" 150 + version = "1.0.22" 151 + source = "registry+https://github.com/rust-lang/crates.io-index" 152 + checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" 153 + 154 + [[package]] 155 + name = "shlex" 156 + version = "1.3.0" 157 + source = "registry+https://github.com/rust-lang/crates.io-index" 158 + checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 159 + 160 + [[package]] 161 + name = "smallvec" 162 + version = "1.15.1" 163 + source = "registry+https://github.com/rust-lang/crates.io-index" 164 + checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" 165 + 166 + [[package]] 167 + name = "sqlite-wasm-rs" 168 + version = "0.5.1" 169 + source = "registry+https://github.com/rust-lang/crates.io-index" 170 + checksum = "05e98301bf8b0540c7de45ecd760539b9c62f5772aed172f08efba597c11cd5d" 171 + dependencies = [ 172 + "cc", 173 + "hashbrown", 174 + "js-sys", 175 + "thiserror", 176 + "wasm-bindgen", 177 + ] 178 + 179 + [[package]] 180 + name = "syn" 181 + version = "2.0.112" 182 + source = "registry+https://github.com/rust-lang/crates.io-index" 183 + checksum = "21f182278bf2d2bcb3c88b1b08a37df029d71ce3d3ae26168e3c653b213b99d4" 184 + dependencies = [ 185 + "proc-macro2", 186 + "quote", 187 + "unicode-ident", 188 + ] 189 + 190 + [[package]] 191 + name = "thiserror" 192 + version = "2.0.17" 193 + source = "registry+https://github.com/rust-lang/crates.io-index" 194 + checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" 195 + dependencies = [ 196 + "thiserror-impl", 197 + ] 198 + 199 + [[package]] 200 + name = "thiserror-impl" 201 + version = "2.0.17" 202 + source = "registry+https://github.com/rust-lang/crates.io-index" 203 + checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" 204 + dependencies = [ 205 + "proc-macro2", 206 + "quote", 207 + "syn", 208 + ] 209 + 210 + [[package]] 211 + name = "unicode-ident" 212 + version = "1.0.22" 213 + source = "registry+https://github.com/rust-lang/crates.io-index" 214 + checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" 215 + 216 + [[package]] 217 + name = "vcpkg" 218 + version = "0.2.15" 219 + source = "registry+https://github.com/rust-lang/crates.io-index" 220 + checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 221 + 222 + [[package]] 223 + name = "wasm-bindgen" 224 + version = "0.2.106" 225 + source = "registry+https://github.com/rust-lang/crates.io-index" 226 + checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" 227 + dependencies = [ 228 + "cfg-if", 229 + "once_cell", 230 + "rustversion", 231 + "wasm-bindgen-macro", 232 + "wasm-bindgen-shared", 233 + ] 234 + 235 + [[package]] 236 + name = "wasm-bindgen-macro" 237 + version = "0.2.106" 238 + source = "registry+https://github.com/rust-lang/crates.io-index" 239 + checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" 240 + dependencies = [ 241 + "quote", 242 + "wasm-bindgen-macro-support", 243 + ] 244 + 245 + [[package]] 246 + name = "wasm-bindgen-macro-support" 247 + version = "0.2.106" 248 + source = "registry+https://github.com/rust-lang/crates.io-index" 249 + checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" 250 + dependencies = [ 251 + "bumpalo", 252 + "proc-macro2", 253 + "quote", 254 + "syn", 255 + "wasm-bindgen-shared", 256 + ] 257 + 258 + [[package]] 259 + name = "wasm-bindgen-shared" 260 + version = "0.2.106" 261 + source = "registry+https://github.com/rust-lang/crates.io-index" 262 + checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" 263 + dependencies = [ 264 + "unicode-ident", 265 + ]
+7
Cargo.toml
··· 1 + [package] 2 + name = "hisab" 3 + version = "0.1.0" 4 + edition = "2024" 5 + 6 + [dependencies] 7 + rusqlite = { version = "0.38.0", features = ["bundled"] }
+95
src/main.rs
··· 1 + use std::env; 2 + use rusqlite::{params, Connection, Result}; 3 + 4 + fn main() -> Result<()> { 5 + let args: Vec<String> = env::args().collect(); 6 + println!("{args:#?}"); 7 + let mut conn = Connection::open("storage.db")?; 8 + 9 + Ok(()) 10 + } 11 + 12 + fn create_database(conn: &Connection) -> Result<()> { 13 + conn.execute( 14 + "CREATE TABLE IF NOT EXISTS accounts ( 15 + id INTEGER PRIMARY KEY AUTOINCREMENT, 16 + name TEXT NOT NULL, 17 + balance REAL NOT NULL, 18 + tags TEXT 19 + )", 20 + [], 21 + )?; 22 + conn.execute( 23 + "CREATE TABLE IF NOT EXISTS transactions ( 24 + id INTEGER PRIMARY KEY AUTOINCREMENT, 25 + sender_id INTEGER NOT NULL, 26 + receiver_id INTEGER NOT NULL, 27 + amount REAL NOT NULL, 28 + timestamp TEXT NOT NULL, 29 + FOREIGN KEY(sender_id) REFERENCES accounts(id), 30 + FOREIGN KEY(receiver_id) REFERENCES accounts(id) 31 + )", 32 + [], 33 + )?; 34 + 35 + 36 + Ok(()) 37 + } 38 + 39 + fn create_account(conn: &Connection, name: &str, tags: Vec<String>) -> Result<()> { 40 + let tags = if tags.is_empty() { 41 + None 42 + } else { 43 + Some(tags.join(",")) 44 + }; 45 + 46 + conn.execute( 47 + "INSERT INTO accounts (name, balance, tags) VALUES (?1, 0.0, ?2)", 48 + params![name, tags], 49 + )?; 50 + 51 + Ok(()) 52 + } 53 + 54 + fn create_transaction( 55 + conn: &mut Connection, 56 + sender_id: i64, 57 + receiver_id: i64, 58 + amount: f64, 59 + ) -> Result<()> { 60 + let tx = conn.transaction()?; 61 + 62 + // 1. Ensure sender has sufficient balance 63 + let sender_balance: f64 = tx.query_row( 64 + "SELECT balance FROM accounts WHERE id = ?1", 65 + params![sender_id], 66 + |row| row.get(0), 67 + )?; 68 + 69 + if sender_balance < amount { 70 + // Any error causes rollback 71 + return Err(rusqlite::Error::ExecuteReturnedResults); 72 + } 73 + 74 + // 2. Insert transaction record 75 + tx.execute( 76 + "INSERT INTO transactions (sender_id, receiver_id, amount, timestamp) 77 + VALUES (?1, ?2, ?3, datetime('now'))", 78 + params![sender_id, receiver_id, amount], 79 + )?; 80 + 81 + // 3. Debit sender 82 + tx.execute( 83 + "UPDATE accounts SET balance = balance - ?1 WHERE id = ?2", 84 + params![amount, sender_id], 85 + )?; 86 + 87 + // 4. Credit receiver 88 + tx.execute( 89 + "UPDATE accounts SET balance = balance + ?1 WHERE id = ?2", 90 + params![amount, receiver_id], 91 + )?; 92 + 93 + tx.commit()?; 94 + Ok(()) 95 + }
storage.db

This is a binary file and will not be displayed.