jsql-neo 4.0.2 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,455 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "android_system_properties"
7
+ version = "0.1.5"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
10
+ dependencies = [
11
+ "libc",
12
+ ]
13
+
14
+ [[package]]
15
+ name = "autocfg"
16
+ version = "1.5.1"
17
+ source = "registry+https://github.com/rust-lang/crates.io-index"
18
+ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
19
+
20
+ [[package]]
21
+ name = "bincode"
22
+ version = "1.3.3"
23
+ source = "registry+https://github.com/rust-lang/crates.io-index"
24
+ checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
25
+ dependencies = [
26
+ "serde",
27
+ ]
28
+
29
+ [[package]]
30
+ name = "bumpalo"
31
+ version = "3.20.3"
32
+ source = "registry+https://github.com/rust-lang/crates.io-index"
33
+ checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
34
+
35
+ [[package]]
36
+ name = "cc"
37
+ version = "1.4.0"
38
+ source = "registry+https://github.com/rust-lang/crates.io-index"
39
+ checksum = "5add81bb678e6cb321aff7fa0dc7689ad82b112dbc032cea19f91d6b8e3582b9"
40
+ dependencies = [
41
+ "find-msvc-tools",
42
+ "shlex",
43
+ ]
44
+
45
+ [[package]]
46
+ name = "cfg-if"
47
+ version = "1.0.4"
48
+ source = "registry+https://github.com/rust-lang/crates.io-index"
49
+ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
50
+
51
+ [[package]]
52
+ name = "chrono"
53
+ version = "0.4.45"
54
+ source = "registry+https://github.com/rust-lang/crates.io-index"
55
+ checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327"
56
+ dependencies = [
57
+ "iana-time-zone",
58
+ "js-sys",
59
+ "num-traits",
60
+ "wasm-bindgen",
61
+ "windows-link",
62
+ ]
63
+
64
+ [[package]]
65
+ name = "core-foundation-sys"
66
+ version = "0.8.7"
67
+ source = "registry+https://github.com/rust-lang/crates.io-index"
68
+ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
69
+
70
+ [[package]]
71
+ name = "crc32fast"
72
+ version = "1.5.0"
73
+ source = "registry+https://github.com/rust-lang/crates.io-index"
74
+ checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
75
+ dependencies = [
76
+ "cfg-if",
77
+ ]
78
+
79
+ [[package]]
80
+ name = "equivalent"
81
+ version = "1.0.2"
82
+ source = "registry+https://github.com/rust-lang/crates.io-index"
83
+ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
84
+
85
+ [[package]]
86
+ name = "find-msvc-tools"
87
+ version = "0.1.9"
88
+ source = "registry+https://github.com/rust-lang/crates.io-index"
89
+ checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
90
+
91
+ [[package]]
92
+ name = "futures-core"
93
+ version = "0.3.33"
94
+ source = "registry+https://github.com/rust-lang/crates.io-index"
95
+ checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7"
96
+
97
+ [[package]]
98
+ name = "futures-task"
99
+ version = "0.3.33"
100
+ source = "registry+https://github.com/rust-lang/crates.io-index"
101
+ checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109"
102
+
103
+ [[package]]
104
+ name = "futures-util"
105
+ version = "0.3.33"
106
+ source = "registry+https://github.com/rust-lang/crates.io-index"
107
+ checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa"
108
+ dependencies = [
109
+ "futures-core",
110
+ "futures-task",
111
+ "pin-project-lite",
112
+ "slab",
113
+ ]
114
+
115
+ [[package]]
116
+ name = "hashbrown"
117
+ version = "0.17.1"
118
+ source = "registry+https://github.com/rust-lang/crates.io-index"
119
+ checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
120
+
121
+ [[package]]
122
+ name = "iana-time-zone"
123
+ version = "0.1.65"
124
+ source = "registry+https://github.com/rust-lang/crates.io-index"
125
+ checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
126
+ dependencies = [
127
+ "android_system_properties",
128
+ "core-foundation-sys",
129
+ "iana-time-zone-haiku",
130
+ "js-sys",
131
+ "log",
132
+ "wasm-bindgen",
133
+ "windows-core",
134
+ ]
135
+
136
+ [[package]]
137
+ name = "iana-time-zone-haiku"
138
+ version = "0.1.2"
139
+ source = "registry+https://github.com/rust-lang/crates.io-index"
140
+ checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
141
+ dependencies = [
142
+ "cc",
143
+ ]
144
+
145
+ [[package]]
146
+ name = "indexmap"
147
+ version = "2.14.0"
148
+ source = "registry+https://github.com/rust-lang/crates.io-index"
149
+ checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
150
+ dependencies = [
151
+ "equivalent",
152
+ "hashbrown",
153
+ ]
154
+
155
+ [[package]]
156
+ name = "itoa"
157
+ version = "1.0.18"
158
+ source = "registry+https://github.com/rust-lang/crates.io-index"
159
+ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
160
+
161
+ [[package]]
162
+ name = "js-sys"
163
+ version = "0.3.103"
164
+ source = "registry+https://github.com/rust-lang/crates.io-index"
165
+ checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102"
166
+ dependencies = [
167
+ "cfg-if",
168
+ "futures-util",
169
+ "wasm-bindgen",
170
+ ]
171
+
172
+ [[package]]
173
+ name = "jsql-neo-core"
174
+ version = "0.1.0"
175
+ dependencies = [
176
+ "bincode",
177
+ "chrono",
178
+ "crc32fast",
179
+ "itoa",
180
+ "js-sys",
181
+ "rustc-hash",
182
+ "ryu",
183
+ "serde",
184
+ "serde_json",
185
+ "wasm-bindgen",
186
+ ]
187
+
188
+ [[package]]
189
+ name = "libc"
190
+ version = "0.2.189"
191
+ source = "registry+https://github.com/rust-lang/crates.io-index"
192
+ checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
193
+
194
+ [[package]]
195
+ name = "log"
196
+ version = "0.4.33"
197
+ source = "registry+https://github.com/rust-lang/crates.io-index"
198
+ checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad"
199
+
200
+ [[package]]
201
+ name = "memchr"
202
+ version = "2.8.3"
203
+ source = "registry+https://github.com/rust-lang/crates.io-index"
204
+ checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
205
+
206
+ [[package]]
207
+ name = "num-traits"
208
+ version = "0.2.19"
209
+ source = "registry+https://github.com/rust-lang/crates.io-index"
210
+ checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
211
+ dependencies = [
212
+ "autocfg",
213
+ ]
214
+
215
+ [[package]]
216
+ name = "once_cell"
217
+ version = "1.21.4"
218
+ source = "registry+https://github.com/rust-lang/crates.io-index"
219
+ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
220
+
221
+ [[package]]
222
+ name = "pin-project-lite"
223
+ version = "0.2.17"
224
+ source = "registry+https://github.com/rust-lang/crates.io-index"
225
+ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
226
+
227
+ [[package]]
228
+ name = "proc-macro2"
229
+ version = "1.0.107"
230
+ source = "registry+https://github.com/rust-lang/crates.io-index"
231
+ checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
232
+ dependencies = [
233
+ "unicode-ident",
234
+ ]
235
+
236
+ [[package]]
237
+ name = "quote"
238
+ version = "1.0.47"
239
+ source = "registry+https://github.com/rust-lang/crates.io-index"
240
+ checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
241
+ dependencies = [
242
+ "proc-macro2",
243
+ ]
244
+
245
+ [[package]]
246
+ name = "rustc-hash"
247
+ version = "2.1.3"
248
+ source = "registry+https://github.com/rust-lang/crates.io-index"
249
+ checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d"
250
+
251
+ [[package]]
252
+ name = "rustversion"
253
+ version = "1.0.23"
254
+ source = "registry+https://github.com/rust-lang/crates.io-index"
255
+ checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
256
+
257
+ [[package]]
258
+ name = "ryu"
259
+ version = "1.0.23"
260
+ source = "registry+https://github.com/rust-lang/crates.io-index"
261
+ checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
262
+
263
+ [[package]]
264
+ name = "serde"
265
+ version = "1.0.229"
266
+ source = "registry+https://github.com/rust-lang/crates.io-index"
267
+ checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
268
+ dependencies = [
269
+ "serde_core",
270
+ "serde_derive",
271
+ ]
272
+
273
+ [[package]]
274
+ name = "serde_core"
275
+ version = "1.0.229"
276
+ source = "registry+https://github.com/rust-lang/crates.io-index"
277
+ checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
278
+ dependencies = [
279
+ "serde_derive",
280
+ ]
281
+
282
+ [[package]]
283
+ name = "serde_derive"
284
+ version = "1.0.229"
285
+ source = "registry+https://github.com/rust-lang/crates.io-index"
286
+ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
287
+ dependencies = [
288
+ "proc-macro2",
289
+ "quote",
290
+ "syn 3.0.3",
291
+ ]
292
+
293
+ [[package]]
294
+ name = "serde_json"
295
+ version = "1.0.151"
296
+ source = "registry+https://github.com/rust-lang/crates.io-index"
297
+ checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
298
+ dependencies = [
299
+ "indexmap",
300
+ "itoa",
301
+ "memchr",
302
+ "serde",
303
+ "serde_core",
304
+ "zmij",
305
+ ]
306
+
307
+ [[package]]
308
+ name = "shlex"
309
+ version = "2.0.1"
310
+ source = "registry+https://github.com/rust-lang/crates.io-index"
311
+ checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
312
+
313
+ [[package]]
314
+ name = "slab"
315
+ version = "0.4.12"
316
+ source = "registry+https://github.com/rust-lang/crates.io-index"
317
+ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
318
+
319
+ [[package]]
320
+ name = "syn"
321
+ version = "2.0.119"
322
+ source = "registry+https://github.com/rust-lang/crates.io-index"
323
+ checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
324
+ dependencies = [
325
+ "proc-macro2",
326
+ "quote",
327
+ "unicode-ident",
328
+ ]
329
+
330
+ [[package]]
331
+ name = "syn"
332
+ version = "3.0.3"
333
+ source = "registry+https://github.com/rust-lang/crates.io-index"
334
+ checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
335
+ dependencies = [
336
+ "proc-macro2",
337
+ "quote",
338
+ "unicode-ident",
339
+ ]
340
+
341
+ [[package]]
342
+ name = "unicode-ident"
343
+ version = "1.0.24"
344
+ source = "registry+https://github.com/rust-lang/crates.io-index"
345
+ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
346
+
347
+ [[package]]
348
+ name = "wasm-bindgen"
349
+ version = "0.2.126"
350
+ source = "registry+https://github.com/rust-lang/crates.io-index"
351
+ checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4"
352
+ dependencies = [
353
+ "cfg-if",
354
+ "once_cell",
355
+ "rustversion",
356
+ "wasm-bindgen-macro",
357
+ "wasm-bindgen-shared",
358
+ ]
359
+
360
+ [[package]]
361
+ name = "wasm-bindgen-macro"
362
+ version = "0.2.126"
363
+ source = "registry+https://github.com/rust-lang/crates.io-index"
364
+ checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1"
365
+ dependencies = [
366
+ "quote",
367
+ "wasm-bindgen-macro-support",
368
+ ]
369
+
370
+ [[package]]
371
+ name = "wasm-bindgen-macro-support"
372
+ version = "0.2.126"
373
+ source = "registry+https://github.com/rust-lang/crates.io-index"
374
+ checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e"
375
+ dependencies = [
376
+ "bumpalo",
377
+ "proc-macro2",
378
+ "quote",
379
+ "syn 2.0.119",
380
+ "wasm-bindgen-shared",
381
+ ]
382
+
383
+ [[package]]
384
+ name = "wasm-bindgen-shared"
385
+ version = "0.2.126"
386
+ source = "registry+https://github.com/rust-lang/crates.io-index"
387
+ checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24"
388
+ dependencies = [
389
+ "unicode-ident",
390
+ ]
391
+
392
+ [[package]]
393
+ name = "windows-core"
394
+ version = "0.62.2"
395
+ source = "registry+https://github.com/rust-lang/crates.io-index"
396
+ checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
397
+ dependencies = [
398
+ "windows-implement",
399
+ "windows-interface",
400
+ "windows-link",
401
+ "windows-result",
402
+ "windows-strings",
403
+ ]
404
+
405
+ [[package]]
406
+ name = "windows-implement"
407
+ version = "0.60.2"
408
+ source = "registry+https://github.com/rust-lang/crates.io-index"
409
+ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
410
+ dependencies = [
411
+ "proc-macro2",
412
+ "quote",
413
+ "syn 2.0.119",
414
+ ]
415
+
416
+ [[package]]
417
+ name = "windows-interface"
418
+ version = "0.59.3"
419
+ source = "registry+https://github.com/rust-lang/crates.io-index"
420
+ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
421
+ dependencies = [
422
+ "proc-macro2",
423
+ "quote",
424
+ "syn 2.0.119",
425
+ ]
426
+
427
+ [[package]]
428
+ name = "windows-link"
429
+ version = "0.2.1"
430
+ source = "registry+https://github.com/rust-lang/crates.io-index"
431
+ checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
432
+
433
+ [[package]]
434
+ name = "windows-result"
435
+ version = "0.4.1"
436
+ source = "registry+https://github.com/rust-lang/crates.io-index"
437
+ checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
438
+ dependencies = [
439
+ "windows-link",
440
+ ]
441
+
442
+ [[package]]
443
+ name = "windows-strings"
444
+ version = "0.5.1"
445
+ source = "registry+https://github.com/rust-lang/crates.io-index"
446
+ checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
447
+ dependencies = [
448
+ "windows-link",
449
+ ]
450
+
451
+ [[package]]
452
+ name = "zmij"
453
+ version = "1.0.23"
454
+ source = "registry+https://github.com/rust-lang/crates.io-index"
455
+ checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
@@ -9,7 +9,7 @@ use std::collections::{HashMap, HashSet};
9
9
  use std::fs;
10
10
  use std::path::{Path, PathBuf};
11
11
 
12
- use crate::engine::{Engine, MemoryEngine, Table};
12
+ use crate::engine::{validate_table_name, Engine, MemoryEngine, Table};
13
13
  use crate::types::{FieldSchema, TableDefinition};
14
14
  use serde::{Deserialize, Serialize};
15
15
 
@@ -60,7 +60,12 @@ impl HybridEngine {
60
60
  }
61
61
 
62
62
  /// 打开磁盘存储目录(mode: 'hybrid' | 'disk' | 'memory';memory 或空目录忽略)
63
+ /// 每次 open 重置引擎状态,避免多个库目录/实例间残留表数据
63
64
  pub fn open(&mut self, dir: &str, mode: &str) -> Result<(), String> {
65
+ self.mem.borrow_mut().clear();
66
+ self.meta.borrow_mut().clear();
67
+ self.dirty.borrow_mut().clear();
68
+ self.last_access.borrow_mut().clear();
64
69
  if dir.is_empty() || mode == "memory" {
65
70
  self.store_dir = None;
66
71
  return Ok(());
@@ -180,7 +185,7 @@ impl HybridEngine {
180
185
  f
181
186
  }
182
187
  };
183
- let dir = self.store_dir.as_ref().unwrap();
188
+ let dir = match &self.store_dir { Some(d) => d, None => return Ok(()) };
184
189
  let tmp = dir.join(format!("{}.tmp", file));
185
190
  fs::write(&tmp, json).map_err(|e| format!("write {}: {}", tmp.display(), e))?;
186
191
  let final_path = self.table_path(name, &file);
@@ -252,19 +257,19 @@ impl HybridEngine {
252
257
  0 => crate::engine::FieldValue::Null,
253
258
  1 => {
254
259
  if *off + 8 > buf.len() { return Err("truncated int".into()); }
255
- let n = i64::from_le_bytes(buf[*off..*off+8].try_into().unwrap());
260
+ let n = i64::from_le_bytes([buf[*off], buf[*off+1], buf[*off+2], buf[*off+3], buf[*off+4], buf[*off+5], buf[*off+6], buf[*off+7]]);
256
261
  *off += 8;
257
262
  crate::engine::FieldValue::Int(n)
258
263
  }
259
264
  2 => {
260
265
  if *off + 8 > buf.len() { return Err("truncated float".into()); }
261
- let n = f64::from_le_bytes(buf[*off..*off+8].try_into().unwrap());
266
+ let n = f64::from_le_bytes([buf[*off], buf[*off+1], buf[*off+2], buf[*off+3], buf[*off+4], buf[*off+5], buf[*off+6], buf[*off+7]]);
262
267
  *off += 8;
263
268
  crate::engine::FieldValue::Float(n)
264
269
  }
265
270
  3 => {
266
271
  if *off + 4 > buf.len() { return Err("truncated len".into()); }
267
- let len = u32::from_le_bytes(buf[*off..*off+4].try_into().unwrap()) as usize;
272
+ let len = u32::from_le_bytes([buf[*off], buf[*off+1], buf[*off+2], buf[*off+3]]) as usize;
268
273
  *off += 4;
269
274
  if *off + len > buf.len() { return Err("truncated str".into()); }
270
275
  let s = std::str::from_utf8(&buf[*off..*off+len]).map_err(|_| "bad utf8")?.to_string();
@@ -278,7 +283,7 @@ impl HybridEngine {
278
283
  }
279
284
  5 => {
280
285
  if *off + 4 > buf.len() { return Err("truncated i32".into()); }
281
- let n = i32::from_le_bytes(buf[*off..*off+4].try_into().unwrap()) as i64;
286
+ let n = i32::from_le_bytes([buf[*off], buf[*off+1], buf[*off+2], buf[*off+3]]) as i64;
282
287
  *off += 4;
283
288
  crate::engine::FieldValue::Int(n)
284
289
  }
@@ -306,6 +311,7 @@ impl Default for HybridEngine {
306
311
 
307
312
  impl Engine for HybridEngine {
308
313
  fn create_table(&mut self, def: TableDefinition) -> Result<(), String> {
314
+ validate_table_name(&def.name)?;
309
315
  if self.mem.borrow().tables.contains_key(&def.name) || self.meta.borrow().contains_key(&def.name) {
310
316
  return Err(format!("table '{}' already exists", def.name));
311
317
  }
@@ -1,20 +1,33 @@
1
1
  use std::collections::HashMap;
2
2
  use crate::engine::table::Table;
3
- use crate::engine::Engine;
3
+ use crate::engine::{validate_table_name, Engine};
4
4
  use crate::types::{Row, TableDefinition};
5
5
 
6
6
  pub struct MemoryEngine {
7
7
  pub tables: HashMap<String, Table>,
8
+ txs: HashMap<String, HashMap<String, Table>>,
9
+ next_tx_id: u64,
8
10
  }
9
11
 
10
12
  impl MemoryEngine {
11
13
  pub fn new() -> Self {
12
- Self { tables: HashMap::new() }
14
+ Self { tables: HashMap::new(), txs: HashMap::new(), next_tx_id: 1 }
15
+ }
16
+
17
+ pub fn clear(&mut self) {
18
+ self.tables.clear();
19
+ self.txs.clear();
20
+ self.next_tx_id = 1;
21
+ }
22
+
23
+ fn snapshot(&self) -> HashMap<String, Table> {
24
+ self.tables.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
13
25
  }
14
26
  }
15
27
 
16
28
  impl Engine for MemoryEngine {
17
29
  fn create_table(&mut self, def: TableDefinition) -> Result<(), String> {
30
+ validate_table_name(&def.name)?;
18
31
  if self.tables.contains_key(&def.name) {
19
32
  return Err(format!("table '{}' already exists", def.name));
20
33
  }
@@ -134,14 +147,22 @@ impl Engine for MemoryEngine {
134
147
  }
135
148
 
136
149
  fn begin_tx(&mut self) -> Result<String, String> {
137
- Err("transactions not supported on MemoryEngine directly".into())
150
+ let tx_id = format!("tx{}", self.next_tx_id);
151
+ self.next_tx_id += 1;
152
+ self.txs.insert(tx_id.clone(), self.snapshot());
153
+ Ok(tx_id)
138
154
  }
139
155
 
140
- fn commit_tx(&mut self, _tx_id: &str) -> Result<(), String> {
141
- Err("transactions not supported on MemoryEngine directly".into())
156
+ fn commit_tx(&mut self, tx_id: &str) -> Result<(), String> {
157
+ self.txs.remove(tx_id)
158
+ .map(|_| ())
159
+ .ok_or_else(|| format!("transaction '{}' not found", tx_id))
142
160
  }
143
161
 
144
- fn rollback_tx(&mut self, _tx_id: &str) -> Result<(), String> {
145
- Err("transactions not supported on MemoryEngine directly".into())
162
+ fn rollback_tx(&mut self, tx_id: &str) -> Result<(), String> {
163
+ let snap = self.txs.remove(tx_id)
164
+ .ok_or_else(|| format!("transaction '{}' not found", tx_id))?;
165
+ self.tables = snap;
166
+ Ok(())
146
167
  }
147
168
  }
@@ -6,7 +6,28 @@ pub mod hybrid;
6
6
  pub use memory::MemoryEngine;
7
7
  #[cfg(not(feature = "wasm"))]
8
8
  pub use hybrid::HybridEngine;
9
- pub use table::{Table, RowStore, FieldValue};
9
+ pub use table::{Table, RowStore, FieldValue, default_value};
10
+
11
+ pub fn validate_table_name(name: &str) -> Result<(), String> {
12
+ if name.is_empty() {
13
+ return Err("table name must not be empty".to_string());
14
+ }
15
+ if name.len() > 64 {
16
+ return Err("table name too long (max 64 chars)".to_string());
17
+ }
18
+ if name == "." || name == ".." {
19
+ return Err(format!("invalid table name '{}'", name));
20
+ }
21
+ for (i, c) in name.chars().enumerate() {
22
+ if c.is_ascii_control() || c == '/' || c == '\\' {
23
+ return Err(format!("invalid character in table name '{}'", name));
24
+ }
25
+ if c == '.' && (i > 0 && name.as_bytes()[i - 1] == b'.') {
26
+ return Err(format!("invalid table name '{}' ('..' sequences are not allowed)", name));
27
+ }
28
+ }
29
+ Ok(())
30
+ }
10
31
 
11
32
  use std::collections::HashMap;
12
33
  use crate::types::{Row, TableDefinition};