1import 'dart:async'; 2 3import 'package:json_at/json_at.dart'; 4import 'package:ejdb2_example/utils/assertions.dart'; 5import 'package:ejdb2_flutter/ejdb2_flutter.dart'; 6import 'package:flutter/material.dart'; 7 8void main() => runApp(MyApp()); 9 10class MyApp extends StatefulWidget { 11 @override 12 _MyAppState createState() => _MyAppState(); 13} 14 15class _MyAppState extends State<MyApp> { 16 String _result = ''; 17 18 @override 19 void initState() { 20 super.initState(); 21 _initTesting(); 22 } 23 24 Future<void> _doTest() async { 25 String dbpath; 26 27 var db = await (EJDB2Builder('test.db') 28 ..truncate = true 29 ..walEnabled = true) 30 .open(); 31 try { 32 var id = await db.put('mycoll', {'foo': 'bar'}); 33 assertEqual(id, 1); 34 35 JBDOC doc = await db.get('mycoll', id); 36 assertDeepEqual(doc.object, {'foo': 'bar'}); 37 38 id = await db.put('mycoll', {'foo': 'baz'}, id); 39 assertEqual(id, 1); 40 41 doc = await db.get('mycoll', id); 42 assertDeepEqual(doc.object, {'foo': 'baz'}); 43 44 dynamic error; 45 try { 46 await db.put('mycoll', '{"'); 47 } catch (e) { 48 error = e; 49 } 50 assertNotNull(error); 51 assertTrue(error is EJDB2Error); 52 assertEqual(error.code, '@ejdb IWRC:86005'); 53 54 assertTrue('${error.message}'.contains('Unquoted JSON string (JBL_ERROR_PARSE_UNQUOTED_STRING)')); 55 56 id = await db.put('mycoll', {'foo': 'bar'}); 57 assertEqual(id, 2); 58 59 var list = await db.createQuery('@mycoll/*').list(); 60 assertEqual(list.toString(), '[JBDOC: 2 {"foo":"bar"}, JBDOC: 1 {"foo":"baz"}]'); 61 62 JBDOC first = await db.createQuery('@mycoll/*').execute().first; 63 assertEqual('$first', 'JBDOC: 2 {"foo":"bar"}'); 64 65 first = (await db.createQuery('@mycoll/*').first()).orNull; 66 assertEqual('$first', 'JBDOC: 2 {"foo":"bar"}'); 67 68 first = (await db.createQuery('@mycoll/[zzz=bbb]').first()).orNull; 69 assertNull(first); 70 71 list = await db.createQuery('@mycoll/*').firstN(5); 72 assertEqual('$list', '[JBDOC: 2 {"foo":"bar"}, JBDOC: 1 {"foo":"baz"}]'); 73 74 doc = await db 75 .createQuery('@mycoll/[foo=:? and foo=:bar]') 76 .setString(0, 'baz') 77 .setString('bar', 'baz') 78 .execute() 79 .first; 80 assertEqual('$doc', 'JBDOC: 1 {"foo":"baz"}'); 81 82 list = await (db.createQuery('@mycoll/[foo != :?]').setString(0, 'zaz')..skip = 1) 83 .execute() 84 .toList(); 85 assertEqual('$list', '[JBDOC: 1 {"foo":"baz"}]'); 86 87 error = null; 88 try { 89 await db['@mycoll/['].execute(); 90 } catch (e) { 91 error = e; 92 } 93 assertNull(error); // Note: null error 94 95 error = null; 96 try { 97 await db.createQuery('@mycoll/[').executeTouch(); 98 } catch (e) { 99 error = e; 100 } 101 assertNotNull(error); // Note: non null error 102 assertTrue(error is EJDB2Error); 103 assertTrue((error as EJDB2Error).isInvalidQuery()); 104 105 final count = await db['@mycoll/* | count'].executeScalarInt(); 106 assertEqual(count, 2); 107 108 await db.patch('mycoll', '[{"op":"add", "path":"/baz", "value":"qux"}]', 1); 109 doc = await db.get('mycoll', 1); 110 assertDeepEqual(doc.object, {'foo': 'baz', 'baz': 'qux'}); 111 112 var info = await db.info(); 113 assertEqual(jsonAt(info, '/size').orNull, 8192); 114 assertEqual(jsonAt(info, '/collections/0/rnum').orNull, 2); 115 assertNull(jsonAt(info, '/collections/0/indexes/0').orNull); 116 117 await db.ensureStringIndex('mycoll', '/foo', true); 118 info = await db.info(); 119 assertEqual(jsonAt(info, '/collections/0/indexes/0/ptr').orNull, '/foo'); 120 assertEqual(jsonAt(info, '/collections/0/indexes/0/mode').orNull, 5); 121 assertEqual(jsonAt(info, '/collections/0/indexes/0/rnum').orNull, 2); 122 123 await db.removeStringIndex('mycoll', '/foo', true); 124 info = await db.info(); 125 assertNull(jsonAt(info, '/collections/0/indexes/0').orNull); 126 127 doc = await db['@mycoll/[foo re :?]'].setRegexp(0, RegExp('.*')).firstRequired(); 128 assertEqual('$doc', 'JBDOC: 2 {"foo":"bar"}'); 129 130 await db.removeCollection('mycoll'); 131 info = await db.info(); 132 assertNull(jsonAt(info, '/collections/0').orNull); 133 134 error = null; 135 try { 136 await db['@mycoll/*'].firstRequired(); 137 } catch (e) { 138 error = e; 139 } 140 assertNotNull(error); // Note: non null error 141 assertTrue(error is EJDB2Error); 142 assertTrue((error as EJDB2Error).isNotFound()); 143 144 id = await db.put('cc1', {'foo': 1}); 145 doc = await db.get('cc1', id); 146 assertEqual('$doc', 'JBDOC: 1 {"foo":1}'); 147 148 await db.renameCollection('cc1', 'cc2'); 149 doc = await db.get('cc2', id); 150 assertEqual('$doc', 'JBDOC: 1 {"foo":1}'); 151 152 var opt = await db.getOptional('cc2', id); 153 assertTrue(opt.isPresent); 154 155 opt = await db.getOptional('cc2', 122); 156 assertTrue(opt.isNotPresent); 157 158 159 var i = 0; 160 for (i = 0; i < 1023; ++i) { 161 await db.put('load', {'name': 'v${i}'}); 162 } 163 164 i = 0; 165 await for (final doc in db.createQuery('@load/* | inverse').execute()) { 166 final v = doc.object; 167 assertEqual(v['name'], 'v${i}'); 168 ++i; 169 } 170 171 dbpath = jsonAt(info, '/file').orNull as String; 172 assertNotNull(dbpath); 173 174 final ts0 = DateTime.now().millisecondsSinceEpoch; 175 final ts = await db.onlineBackup('${dbpath}.bkp'); 176 assertTrue(ts0 < ts); 177 178 } catch(e, st) { 179 print('$e\n$st'); 180 rethrow; 181 } finally { 182 await db.close(); 183 } 184 185 db = await EJDB2Builder('${dbpath}.bkp').open(); 186 final doc = await db.get('cc2', 1); 187 assertEqual('${doc}', 'JBDOC: 1 {"foo":1}'); 188 await db.close(); 189 } 190 191 Future<void> _initTesting() async { 192 if (!mounted) return; 193 try { 194 await _doTest(); 195 setState(() { 196 _result = 'Success'; 197 }); 198 } catch (e, s) { 199 print('Error $e, $s'); 200 setState(() { 201 _result = 'Fail: ${e}'; 202 }); 203 } 204 } 205 206 @override 207 Widget build(BuildContext context) { 208 return MaterialApp( 209 home: Scaffold( 210 body: Center( 211 child: _result == 'Success' 212 ? const Text( 213 'Success', 214 key: Key('success'), 215 ) 216 : Text( 217 _result == '' ? '' : 'Fail: ${_result}', 218 key: const Key('fail'), 219 ), 220 ), 221 ), 222 ); 223 } 224} 225