⍝ Test script for ddb:
⍝
⍝ test'ddb' ⍝ run test: no news → good news.
⍝ 1 test'ddb' ⍝ run test, showing progress.
⍝---------------------------------------------------⍝ general tests:
(ddb.remove'ddb test')/'Old file removed!' ⍝ ensure file removed.
defns←('name' 80 20)('age' 83)('shape' 83 3) ⍝ field definitions.
disp defns
┌→───────────┬────────┬────────────┐
│┌→───┬──┬──┐│┌→──┬──┐│┌→────┬──┬─┐│
││name│80│20│││age│83│││shape│83│3││
│└───→┴~─┴~─┘│└──→┴~─┘│└────→┴~─┴─┘│
└───────────→┴───────→┴───────────→┘
{}'ddb test' ddb.create defns ⍝ create table (show size).
disp ddb.defs 'ddb test' ⍝ field defs from table,
┌→───────────┬────────┬────────────┐
│┌→───┬──┬──┐│┌→──┬──┐│┌→────┬──┬─┐│
││name│80│20│││age│83│││shape│83│3││
│└───→┴~─┴~─┘│└──→┴~─┘│└────→┴~─┴─┘│
└───────────→┴───────→┴───────────→┘
disp ddb.defs ddb.open 'ddb test' ⍝ ... or table handle.
┌→───────────┬────────┬────────────┐
│┌→───┬──┬──┐│┌→──┬──┐│┌→────┬──┬─┐│
││name│80│20│││age│83│││shape│83│3││
│└───→┴~─┴~─┘│└──→┴~─┘│└────→┴~─┴─┘│
└───────────→┴───────→┴───────────→┘
+'ddb test' ddb.append 'john' 56 (38 42 46) ⍝ append row to table.
72
block←(↑'pete' 'jessica')(55 23)(↑(44 32 34)(48 24 36))
disp block ⍝ block of rows.
┌→──────┬─────┬────────┐
│pete │55 23│44 32 34│
│jessica↓ │48 24 36↓
└──────→┴~───→┴~──────→┘
+'ddb test' ddb.append block ⍝ append block of rows.
120
tab←ddb.open 'ddb test' ⍝ handle for table.
tab ddb.get 'name' ⍝ get field from table.
john
pete
jessica
disp tab ddb.get 'name' 'age' 'shape' ⍝ get all fields.
┌→───────────────────┬────────┬────────┐
│john │ │38 42 46│
│pete │56 55 23│44 32 34│
│jessica ↓ │48 24 36↓
└───────────────────→┴~──────→┴~──────→┘
disp tab ddb.get (1 1 1)('name' 'age' 'shape') ⍝ test mask vector.
┌→───────────────────┬────────┬────────┐
│john │ │38 42 46│
│pete │56 55 23│44 32 34│
│jessica ↓ │48 24 36↓
└───────────────────→┴~──────→┴~──────→┘
disp tab ddb.get 1('name' 'age' 'shape') ⍝ test mask scalar.
┌→───────────────────┬────────┬────────┐
│john │ │38 42 46│
│pete │56 55 23│44 32 34│
│jessica ↓ │48 24 36↓
└───────────────────→┴~──────→┴~──────→┘
{}⎕ex'tab' ⍝ remove mapping handle.
disp (ddb.open'ddb test')ddb.get'age' 'shape' ⍝ use transient handle.
┌→───────┬────────┐
│ │38 42 46│
│56 55 23│44 32 34│
│ │48 24 36↓
└~──────→┴~──────→┘
disp 'ddb test' ddb.get 'age' 'shape' ⍝ use table name.
┌→───────┬────────┐
│ │38 42 46│
│56 55 23│44 32 34│
│ │48 24 36↓
└~──────→┴~──────→┘
⎕dr 'ddb test' ddb.put 'age' (88 77 21) ⍝ replace age values.
83
'ddb test' ddb.get 'age' ⍝ check update.
88 77 21
tab←'w' ddb.open 'ddb test' ⍝ open table for write.
jays←^/∨\'j'=tab ddb.get 'name' ⍝ names starting with 'j'.
tab ddb.get jays 'shape' ⍝ shapes of .. ..
38 42 46
48 24 36
+tab ddb.put jays 'age' (66 22) ⍝ replace selected ages.
66 22
tab ddb.get 'age' ⍝ check update.
66 77 22
+⎕ex'tab' ⍝ release table.
1
+'ddb test' ddb.retain jays ⍝ retain only j-names.
96
'ddb test' ddb.get 'name' ⍝ compressed table.
john
jessica
disp ddb.(get∘⊃¨∘defs∘⊃⍨∘⊂∘open)'ddb test' ⍝ open and get all fields.
┌→───────────────────┬─────┬────────┐
│john │66 22│38 42 46│
│jessica ↓ │48 24 36↓
└───────────────────→┴~───→┴~──────→┘
disp ddb.(get∘(⊃¨∘defs)⍨∘open)'ddb test' ⍝ open and get all fields.
┌→───────────────────┬─────┬────────┐
│john │66 22│38 42 46│
│jessica ↓ │48 24 36↓
└───────────────────→┴~───→┴~──────→┘
tab←'w'ddb.open 'ddb test' ⍝ reopen table for write.
⍝ to check for demote probs,
disp tab ddb.put 'age' 'shape'{⍺⍵}(,\2 3)⍴¨0 ⍝ set all numbers to 0.
┌→──┬─────┐
│0 0│0 0 0│
│ │0 0 0↓
└~─→┴~───→┘
disp ddb.(get∘⊃¨∘defs∘⊃⍨∘⊂)tab ⍝ get all fields.
┌→───────────────────┬───┬─────┐
│john │0 0│0 0 0│
│jessica ↓ │0 0 0↓
└───────────────────→┴~─→┴~───→┘
{}⎕ex'tab' ⍝ release table.
get←ddb.((open'ddb test')∘get) ⍝ bind handle with get fn.
disp get(∨/'o'=get'name')('age' 'shape') ⍝ compound selection.
┌→┬─────┐
│0│0 0 0↓
└→┴~───→┘
{}⎕ex'get' ⍝ release and
+ddb.remove 'ddb test' ⍝ remove table.
1
⍝---------------------------------------------------⍝ test single field table:
tab←'ddb test' ddb.create 'single' 323 ⍝ create table.
+tab ddb.append ⍳10 ⍝ append some values
68
tab ddb.get 'single' ⍝ retrieve values.
1 2 3 4 5 6 7 8 9 10
+ddb.remove tab ⍝ remove table.
1
⍝---------------------------------------------------⍝ test higher ranks (simple)
defs←('vec' 83)('mat' 83 3)('cube' 83 3 4)('hype' 83 3 4 5)
tab←'ddb test' ddb.create defs ⍝ create table.
+tab ddb.append (,\2 3 4 5)⍴¨⊂⍳120 ⍝ append some values.
228
disp ddb.(get∘(⊃¨)∘defs)⍨tab ⍝ retrieve values.
┌→──┬─────┬───────────┬───────────────────┐
│ │ │ │ 1 2 3 4 5│
│ │ │ │ 6 7 8 9 10│
│ │ │ │ 11 12 13 14 15│
│ │ │ │ 16 17 18 19 20│
│ │ │ │ │
│ │ │ │ 21 22 23 24 25│
│ │ │ │ 26 27 28 29 30│
│ │ │ │ 31 32 33 34 35│
│ │ │ │ 36 37 38 39 40│
│ │ │ │ │
│ │ │ │ 41 42 43 44 45│
│ │ │ 1 2 3 4│ 46 47 48 49 50│
│ │ │ 5 6 7 8│ 51 52 53 54 55│
│ │ │ 9 10 11 12│ 56 57 58 59 60│
│1 2│1 2 3│ │ │
│ │4 5 6│13 14 15 16│ │
│ │ │17 18 19 20│ 61 62 63 64 65│
│ │ │21 22 23 24│ 66 67 68 69 70│
│ │ │ │ 71 72 73 74 75│
│ │ │ │ 76 77 78 79 80│
│ │ │ │ │
│ │ │ │ 81 82 83 84 85│
│ │ │ │ 86 87 88 89 90│
│ │ │ │ 91 92 93 94 95│
│ │ │ │ 96 97 98 99 100│
│ │ │ │ │
│ │ │ │101 102 103 104 105│
│ │ │ │106 107 108 109 110│
│ │ │ │111 112 113 114 115│
│ │ ↓ ⍒116 117 118 119 120⍒
└~─→┴~───→┴~─────────→┴~─────────────────→┘
+ddb.remove tab ⍝ remove table.
1
⍝---------------------------------------------------⍝ test higher ranks (nested)
defs←('vecs' 83 ¯3)('mats' 83 ¯3 ¯4)('cubes' 83 ¯3 ¯4 ¯5)
tab←'ddb test' ddb.create defs ⍝ create table.
vals ← {+⌿¨1⊂[⎕io]⍵}¨1↓(,\2 3 4 5)⍴¨⊂⍳×/2 3 4 5
+tab ddb.append vals ⍝ append some values.
243
disp tab ddb.get tab.names ⍝ retrieve values.
┌→────────────┬────────────────────────┬────────────────────────────────────┐
│ │ │┌→─────────────┬───────────────────┐│
│ │ ││ 1 2 3 4 5│ 61 62 63 64 65││
│ │ ││ 6 7 8 9 10│ 66 67 68 69 70││
│ │ ││11 12 13 14 15│ 71 72 73 74 75││
│ │ ││16 17 18 19 20│ 76 77 78 79 80││
│ │┌→─────────┬───────────┐││ │ ││
│┌→────┬─────┐││1 2 3 4│13 14 15 16│││21 22 23 24 25│ 81 82 83 84 85││
││1 2 3│4 5 6│││5 6 7 8│17 18 19 20│││26 27 28 29 30│ 86 87 88 89 90││
│└~───→┴~───→┘││9 10 11 12↓21 22 23 24↓││31 32 33 34 35│ 91 92 93 94 95││
│ │└~────────→┴~─────────→┘││36 37 38 39 40│ 96 97 98 99 100││
│ │ ││ │ ││
│ │ ││41 42 43 44 45│101 102 103 104 105││
│ │ ││46 47 48 49 50│106 107 108 109 110││
│ │ ││51 52 53 54 55│111 112 113 114 115││
│ │ ││56 57 58 59 60⍒116 117 118 119 120⍒│
│ │ │└~────────────→┴~─────────────────→┘│
└────────────→┴───────────────────────→┴───────────────────────────────────→┘
+ddb.remove tab ⍝ remove table.
1
⍝---------------------------------------------------⍝ test char vex:
defs←('vex' 80 ¯10)('mat' 80 10) ⍝ matrix and vectors.
tab←'ddb test' ddb.create defs ⍝ create table.
vex←'one' 'two' 'and three' ⍝ data vectors.
mat←↑vex
+tab ddb.append vex mat ⍝ append some values.
105
disp tab ddb.get 'mat' 'vex' ⍝ retrieve values.
┌→─────────┬────────────────────┐
│one │┌→──┬───┬──────────┐│
│two ││one│two│and three││
│and three↓└──→┴──→┴─────────→┘│
└─────────→┴───────────────────→┘
⎕dr tab ddb.put 'vex' ('un' 'deux' 'trois') ⍝ replace values.
326
disp tab ddb.get tab.names ⍝ retrieve new values.
┌→──────────────┬──────────┐
│┌→─┬────┬─────┐│one │
││un│deux│trois││two │
│└─→┴───→┴────→┘│and three↓
└──────────────→┴─────────→┘
+ddb.remove tab ⍝ remove table.
1
⍝---------------------------------------------------⍝ test numeric vex:
defs←('vex' 83 ¯4)('mat' 83 4) ⍝ matrix and vectors.
tab←'ddb test' ddb.create defs ⍝ create table.
vex←⍳¨⍳4 ⍝ data vectors.
mat←↑vex
+tab ddb.append vex mat ⍝ append some values.
81
disp tab ddb.get 'mat' 'vex' ⍝ retrieve values.
┌→──────┬─────────────────────┐
│1 0 0 0│┌→┬───┬─────┬───────┐│
│1 2 0 0││1│1 2│1 2 3│1 2 3 4││
│1 2 3 0│└→┴~─→┴~───→┴~─────→┘│
│1 2 3 4↓ │
└~─────→┴────────────────────→┘
⎕dr tab ddb.put (0 1 0 1) 'vex' (↓11×2 2⍴⍳4) ⍝ replace some values.
326
disp tab ddb.get tab.names ⍝ retrieve new values.
┌→────────────────────┬───────┐
│┌→┬─────┬─────┬─────┐│1 0 0 0│
││1│11 22│1 2 3│33 44││1 2 0 0│
│└→┴~───→┴~───→┴~───→┘│1 2 3 0│
│ │1 2 3 4↓
└────────────────────→┴~─────→┘
+ddb.remove tab ⍝ remove table.
1
⍝---------------------------------------------------⍝ test nested cases
mats ← {⍵++\(¯1+⍳⍴⍵)*2}{⍵ ⍵⍴⍳⍵×⍵}¨⍳5 ⍝ nested matrices.
disp mats
┌→┬───┬────────┬───────────┬──────────────┐
│ │ │ │15 16 17 18│31 32 33 34 35│
│ │2 3│ 6 7 8│19 20 21 22│36 37 38 39 40│
│1│4 5│ 9 10 11│23 24 25 26│41 42 43 44 45│
│ │ │12 13 14│27 28 29 30│46 47 48 49 50│
│ ↓ ↓ ↓ ↓51 52 53 54 55↓
└→┴~─→┴~──────→┴~─────────→┴~────────────→┘
⍝---------------------------------------------------⍝ simple simple
tab←'ddb test' ddb.create 'mats' 83 5 5
tab ddb.append ↑mats
175
disp tab ddb.get 'mats'
1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
2 3 0 0 0
4 5 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
6 7 8 0 0
9 10 11 0 0
12 13 14 0 0
0 0 0 0 0
0 0 0 0 0
15 16 17 18 0
19 20 21 22 0
23 24 25 26 0
27 28 29 30 0
0 0 0 0 0
31 32 33 34 35
36 37 38 39 40
41 42 43 44 45
46 47 48 49 50
51 52 53 54 55
(↑mats) ≡ tab ddb.get 'mats'
1
{}⎕ex'tab'
ddb.remove'ddb test'
1
⍝---------------------------------------------------⍝ simple nested
tab←'ddb test' ddb.create 'mats' 83 5 ¯5
tab ddb.append mats
182
disp tab ddb.get 'mats'
┌→┬───┬────────┬───────────┬──────────────┐
│1│2 3│ 6 7 8│15 16 17 18│31 32 33 34 35│
│0│4 5│ 9 10 11│19 20 21 22│36 37 38 39 40│
│0│0 0│12 13 14│23 24 25 26│41 42 43 44 45│
│0│0 0│ 0 0 0│27 28 29 30│46 47 48 49 50│
│0↓0 0↓ 0 0 0↓ 0 0 0 0↓51 52 53 54 55↓
└→┴~─→┴~──────→┴~─────────→┴~────────────→┘
(5↑[1]¨mats) ≡ tab ddb.get 'mats'
1
{}⎕ex'tab'
ddb.remove'ddb test'
1
⍝---------------------------------------------------⍝ nested simple
tab←'ddb test' ddb.create 'mats' 83 ¯5 5
tab ddb.append mats
182
disp tab ddb.get 'mats'
┌→────────┬─────────┬────────────┬─────────────┬──────────────┐
│ │ │ │15 16 17 18 0│31 32 33 34 35│
│ │2 3 0 0 0│ 6 7 8 0 0│19 20 21 22 0│36 37 38 39 40│
│1 0 0 0 0│4 5 0 0 0│ 9 10 11 0 0│23 24 25 26 0│41 42 43 44 45│
│ │ │12 13 14 0 0│27 28 29 30 0│46 47 48 49 50│
│ ↓ ↓ ↓ ↓51 52 53 54 55↓
└~───────→┴~───────→┴~──────────→┴~───────────→┴~────────────→┘
(5↑[2]¨mats) ≡ tab ddb.get 'mats'
1
{}⎕ex'tab'
ddb.remove'ddb test'
1
⍝---------------------------------------------------⍝ nested nested
tab←'ddb test' ddb.create 'mats' 83 ¯5 ¯5
tab ddb.append mats
189
disp tab ddb.get 'mats'
┌→┬───┬────────┬───────────┬──────────────┐
│ │ │ │15 16 17 18│31 32 33 34 35│
│ │2 3│ 6 7 8│19 20 21 22│36 37 38 39 40│
│1│4 5│ 9 10 11│23 24 25 26│41 42 43 44 45│
│ │ │12 13 14│27 28 29 30│46 47 48 49 50│
│ ↓ ↓ ↓ ↓51 52 53 54 55↓
└→┴~─→┴~──────→┴~─────────→┴~────────────→┘
mats ≡ tab ddb.get 'mats'
1
{}⎕ex'tab'
ddb.remove'ddb test'
1
⍝---------------------------------------------------⍝ test large fields:
defs←('nest' 80 ¯2 ¯300 ¯2)('simp' 80 2 300 2) ⍝ nested and simple.
tab←'ddb test' ddb.create defs ⍝ create table.
nest←3⍴⊂1 11 1⍴'hello world' ⍝ nested values.
simp←↑nest ⍝ simple values.
+tab ddb.append nest simp ⍝ append values.
9624
nest≡tab ddb.get'nest' ⍝ check nested.
1
(tab ddb.get'simp')≡(3,¯3↑⊃⌽ddb.defs tab)↑simp ⍝ check simple.
1
nest←3⍴⊂2 300 2⍴'hello world' ⍝ full nested values.
simp←↑nest ⍝ full simple values.
+tab ddb.append nest simp ⍝ check full data.
16842
+ddb.remove tab ⍝ remove table.
1
⍝---------------------------------------------------⍝ test errors:
defs←('nest' 80 ¯5)('simp' 80 5) ⍝ nested and simple fields.
nest←'hello' 'world' ⍝ nested values.
simp←↑nest ⍝ simple values.
ddb.open 'ddb test' ⍝ non-existent table.
22::BAD TABLE NAME
'ddb test' ddb.create defs,⊂'bad' 84 ⍝ bad field type.
11::BAD FIELD TYPE
tab←'ddb test' ddb.create defs ⍝ create good table.
'ddb test' ddb.create defs ⍝ table already exists.
22::BAD TABLE NAME
+tab ddb.append nest simp ⍝ append values.
66
tab ddb.get 'Nest' ⍝ mis-spelled field name.
6::BAD NAME "Nest"
tab ddb.append 'too' 'many' 'fields' ⍝ wrong number of fields.
5::LENGTH ERROR
tab ddb.append nest 's' ⍝ scalar val for vector fld.
4::BAD RANK in "simp"
tab ddb.append (↑,↓nest) simp ⍝ matrix val for vector fld.
4::BAD RANK in "nest"
tab ddb.append 'vect' (2 3) ⍝ numeric val for char fld.
11::BAD TYPE in "simp"
tab ddb.append 'vect' 'too long' ⍝ data truncated.
10::BAD SIZE in "simp"
tab ddb.append 'vect' (simp simp) ⍝ nested val for char fld.
11::BAD DEPTH in "simp"
tab ddb.get (1 0 1) tab.names ⍝ wrong length mask.
5::LENGTH ERROR
{}⎕ex'tab' ⍝ release and
tab←ddb.open 'ddb test' ⍝ reopen table (read-only).
tab ddb.append nest simp ⍝ attempt append.
19::READ-ONLY TABLE
tab ddb.put nest simp ⍝ attempt put.
19::READ-ONLY TABLE
tab ddb.retain 0 0 ⍝ attempt to remove rows.
19::READ-ONLY TABLE
⍝ try remove using file name
ddb.remove 'ddb test' ⍝ while handle "tab" exists.
19::TABLE OPEN
{}⎕ex'tab' ⍝ expunge handle, then
+ddb.remove'ddb test' ⍝ remove table using name.
1
⍬≡⎕nnums ⍝ check no file ties.
1
⍝---------------------------------------------------⍝ regression tests.
{}'ddb test'ddb.create'prob' 80 ¯10
'ddb test'ddb.append 'reopen' 'failed'
55
disp 'ddb test'ddb.get'prob'
┌→─────┬──────┐
│reopen│failed│
└─────→┴─────→┘
+ddb.remove'ddb test'
1
tab←'ddb test'ddb.create'ret' 80 3 ⍝ Access error corrupted table.
tab ddb.append↑'tab' 'not' 'bad' ⍝ append three rows.
36
'ddb test'ddb.retain 1 0 1 ⍝ table already open: fails.
19::TABLE OPEN
tab ddb.get'ret' ⍝ table not changed.
tab
not
bad
tab ddb.retain 0 1 1 ⍝ OK if handle used.
33
tab ddb.get'ret' ⍝ retain succeeds.
not
bad
+ddb.remove'ddb test'{⍺}⎕ex'tab' ⍝ remove handle and table.
1
⍝---------------------------------------------------⍝ finished!
⍝
⍝ Back to: Contents