1import 'package:ejdb2_dart/ejdb2_dart.dart'; 2 3void main() async { 4 final db = await EJDB2.open('hello.db', truncate: true); 5 6 var q = db.createQuery('@mycoll/*'); 7 assert(q.collection == 'mycoll'); 8 9 var id = await db.put('mycoll', {'foo': 'bar'}); 10 assert(id == 1); 11 12 dynamic error; 13 try { 14 await db.put('mycoll', '{"'); 15 } on EJDB2Error catch (e) { 16 error = e; 17 assert(e.code == 86005); 18 assert(e.message == 'Unquoted JSON string (JBL_ERROR_PARSE_UNQUOTED_STRING)'); 19 } 20 assert(error != null); 21 22 var json = await db.get('mycoll', id); 23 assert(json == '{"foo":"bar"}'); 24 25 await db.put('mycoll', {'foo': 'baz'}); 26 27 final list = await db.createQuery('@mycoll/*').execute(limit: 1).toList(); 28 assert(list.length == 1); 29 30 var first = await db.createQuery('@mycoll/*').first(); 31 assert(first.isPresent); 32 assert(first.value.json == '{"foo":"baz"}'); 33 34 first = await db.createQuery('@mycoll/[zzz=bbb]').first(); 35 assert(first.isEmpty); 36 37 var firstN = await db.createQuery('@mycoll/*').firstN(5); 38 assert(firstN.length == 2); 39 assert(firstN[0].json == '{"foo":"baz"}'); 40 assert(firstN[1].json == '{"foo":"bar"}'); 41 42 firstN = await db.createQuery('@mycoll/*').firstN(1); 43 assert(firstN.length == 1); 44 45 // Query 1 46 final rbuf = <String>[]; 47 await for (final doc in q.execute()) { 48 rbuf..add(doc.id.toString())..add(doc.json); 49 } 50 assert(rbuf.toString() == '[2, {"foo":"baz"}, 1, {"foo":"bar"}]'); 51 rbuf.clear(); 52 53 // Query 2 54 await for (final doc in db.createQuery('@mycoll/[foo=zaz]').execute()) { 55 rbuf..add(doc.id.toString())..add(doc.json); 56 } 57 assert(rbuf.isEmpty); 58 59 // Query 3 60 await for (final doc in db.createQuery('/[foo=bar]', 'mycoll').execute()) { 61 rbuf..add(doc.id.toString())..add(doc.json); 62 } 63 assert(rbuf.toString() == '[1, {"foo":"bar"}]'); 64 65 error = null; 66 try { 67 await db.createQuery('@mycoll/[').execute(); 68 } on EJDB2Error catch (e) { 69 error = e; 70 assert(e.invalidQuery); 71 assert(e.message.contains('@mycoll/[ <---')); 72 } 73 assert(error != null); 74 75 var count = await db.createQuery('@mycoll/* | count').scalarInt(); 76 assert(count == 2); 77 78 count = await db.createQuery('@mycoll/* | count').scalarInt(explainCallback: (log) { 79 log.contains('[INDEX] NO [COLLECTOR] PLAIN'); 80 }); 81 assert(count == 2); 82 83 // Del 84 await db.del('mycoll', 1); 85 error = null; 86 try { 87 await db.get('mycoll', 1); 88 } on EJDB2Error catch (e) { 89 error = e; 90 assert(e.notFound); 91 assert(e.message.contains('IWKV_ERROR_NOTFOUND')); 92 } 93 assert(error != null); 94 95 count = await db.createQuery('@mycoll/* | count').scalarInt(); 96 assert(count == 1); 97 98 // Patch 99 await db.patch('mycoll', '[{"op":"add", "path":"/baz", "value":"qux"}]', 2); 100 json = await db.get('mycoll', 2); 101 assert(json == '{"foo":"baz","baz":"qux"}'); 102 103 // DB Info 104 json = await db.info(); 105 assert(json.contains('"collections":[{"name":"mycoll","dbid":3,"rnum":1,"indexes":[]}]')); 106 107 // Indexes 108 await db.ensureStringIndex('mycoll', '/foo', unique: true); 109 json = await db.info(); 110 assert(json.contains('"indexes":[{"ptr":"/foo","mode":5,"idbf":0,"dbid":4,"rnum":1}]')); 111 112 // Test JQL set 113 JBDOC? doc = await db.createQuery('@mycoll/[foo=:?]').setString(0, 'baz').execute().first; 114 assert(doc.json == '{"foo":"baz","baz":"qux"}'); 115 116 // Test explain log 117 await db.createQuery('@mycoll/[foo=:?]').setString(0, 'baz').execute(explainCallback: (log) { 118 assert( 119 log.contains("[INDEX] SELECTED UNIQUE|STR|1 /foo EXPR1: 'foo = :?' INIT: IWKV_CURSOR_EQ")); 120 }); 121 122 doc = await db 123 .createQuery('@mycoll/[foo=:?] and /[baz=:?]') 124 .setString(0, 'baz') 125 .setString(1, 'qux') 126 .execute() 127 .first; 128 assert(doc.json == '{"foo":"baz","baz":"qux"}'); 129 130 doc = await db 131 .createQuery('@mycoll/[foo=:foo] and /[baz=:baz]') 132 .setString('foo', 'baz') 133 .setString('baz', 'qux') 134 .execute() 135 .first; 136 137 doc = await db.createQuery('@mycoll/[foo re :?]').setRegExp(0, RegExp('.*')).execute().first; 138 assert(doc.json == '{"foo":"baz","baz":"qux"}'); 139 140 doc = await db.createQuery('@mycoll/* | /foo').execute().first; 141 assert(doc.json == '{"foo":"baz"}'); 142 143 await db.removeStringIndex('mycoll', '/foo', unique: true); 144 json = await db.info(); 145 assert(json.contains('"collections":[{"name":"mycoll","dbid":3,"rnum":1,"indexes":[]}]')); 146 147 // Remove collection 148 await db.removeCollection('mycoll'); 149 json = await db.info(); 150 assert(json.contains('"collections":[]')); 151 152 // Check apply 153 await db.put( 154 'apply1', {'tx_hash': 'ed36cfd14a4fe29b16c511d68a8be89e42dcc6e4ced69d04f318448a2b8fafa0'}); 155 doc = await db 156 .createQuery('/[tx_hash = :?] | apply :?', 'apply1') 157 .setString(0, 'ed36cfd14a4fe29b16c511d68a8be89e42dcc6e4ced69d04f318448a2b8fafa0') 158 .setJson(1, {'status': 'completed'}).firstRequired(); 159 assert(doc.object['status'] == 'completed'); 160 161 /// Test get limit 162 q = db.createQuery('@c1/* | limit 1'); 163 assert(q.limit == 1); 164 165 q = db.createQuery('@c1/*'); 166 assert(q.limit == 0); 167 168 id = await db.put('cc1', {'foo': 1}); 169 await db.renameCollection('cc1', 'cc2'); 170 json = await db.get('cc2', id); 171 assert(json == '{"foo":1}'); 172 173 for (var i = 0; i < 10000; ++i) { 174 await db.put('cc1', {'name': 'v${i}'}); 175 } 176 var cnt = 0; 177 await for (final _ in db.createQuery('@cc1/*').execute()) { 178 cnt++; 179 } 180 assert(cnt == 10000); 181 182 final ts0 = DateTime.now().millisecondsSinceEpoch; 183 final ts = await db.onlineBackup('hello-bkp.db'); 184 assert(ts > ts0); 185 await db.close(); 186 187 // Reopen backup image 188 final db2 = await EJDB2.open('hello-bkp.db', truncate: false); 189 doc = (await db2.createQuery('@cc1/*').first()).orNull; 190 assert(doc != null); 191 await db2.close(); 192} 193