• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * Sample React Native App
3 * https://github.com/facebook/react-native
4 *
5 * @format
6 * @flow
7 */
8
9import React, { Component } from 'react';
10import { Button, StyleSheet, Text, View } from 'react-native';
11import { EJDB2, JBE } from 'ejdb2_react_native';
12
13const { assert } = require('chai');
14const t = {
15  true: a => assert.isTrue(a),
16  is: (a, b) => assert.equal(a, b),
17  throwsAsync: (a, b) => a.catch(e => assert.deepInclude(e, b)),
18  deepEqual: (a, b) => assert.deepEqual(a, b),
19};
20
21export default class App extends Component {
22  constructor(props) {
23    super(props);
24    this.state = {
25      status: 0,
26    }
27  }
28
29  async test() {
30
31    const db = await EJDB2.open('hello.db', { truncate: true });
32
33    await db.createQuery('@mycoll/*').use(q => {
34      t.true(q != null);
35      t.is(q.collection, 'mycoll');
36      t.true(q.db != null);
37    });
38
39    let id = await db.put('mycoll', { 'foo': 'bar' });
40    t.is(id, 1);
41
42    await t.throwsAsync(db.put('mycoll', '{"'), {
43      code: '76005',
44      message: 'com.softmotions.ejdb2.EJDB2Exception: @ejdb IWRC:76005 errno:0 Unquoted JSON string (JBL_ERROR_PARSE_UNQUOTED_STRING)'
45    });
46
47    let doc = await db.get('mycoll', 1);
48    t.deepEqual(doc, { foo: 'bar' });
49
50    await db.put('mycoll', { 'foo': 'baz' });
51
52    const list = await db.createQuery('@mycoll/*').use(q => q.list({ limit: 1 }));
53    t.is(list.length, 1);
54
55    let first = await db.createQuery('@mycoll/*').use(q => q.first());
56    t.true(first != null);
57    t.deepEqual(first.json, { foo: 'baz' });
58    t.is(first._raw, null);
59
60
61    first = await db.createQuery('@mycoll/[zzz=bbb]').use(q => q.first());
62    t.is(first, undefined);
63
64    let firstN = await db.createQuery('@mycoll/*').use(q => q.firstN(5));
65    t.true(firstN != null && firstN.length == 2);
66    t.deepEqual(firstN[0].json, { foo: 'baz' });
67    t.deepEqual(firstN[1].json, { foo: 'bar' });
68
69    firstN = await db.createQuery('@mycoll/*').use(q => q.firstN(1));
70    t.true(firstN != null && firstN.length == 1);
71    t.deepEqual(firstN[0].json, { foo: 'baz' });
72
73    // Query 1
74    const rbuf = [];
75    await db.createQuery('@mycoll/*').withLimit(10).useExecute((doc) => {
76      rbuf.push(doc.id);
77      rbuf.push(doc._raw);
78    });
79    t.is(rbuf.toString(), '2,{"foo":"baz"},1,{"foo":"bar"}');
80
81    // Query 2
82    rbuf.length = 0;
83    await db.createQuery('@mycoll/[foo=:? and foo=:bar]')
84      .setString(0, 'baz')
85      .setString('bar', 'baz')
86      .useExecute((doc) => {
87        rbuf.push(doc.id);
88        rbuf.push(doc._raw);
89      });
90    t.is(rbuf.toString(), '2,{"foo":"baz"}');
91
92
93    let error = null;
94    try {
95      await db.createQuery('@mycoll/[').useExecute();
96    } catch (e) {
97      error = e;
98      t.true(JBE.isInvalidQuery(e));
99    }
100    t.true(error != null);
101    error = null;
102
103    let q = await db.createQuery('@mycoll/*');
104    q.close();
105
106    try {
107      await q.useExecute();
108    } catch (e) {
109      error = e;
110      t.true(e.toString().indexOf('IllegalStateException') != -1);
111    }
112    t.true(error != null);
113    error = null;
114
115    let count = await db.createQuery('@mycoll/* | count').use(q => q.scalarInt());
116    t.is(count, 2);
117
118    await db.del('mycoll', 1);
119
120    error = null;
121    try {
122      await db.get('mycoll', 1);
123    } catch (e) {
124      error = e;
125      t.true(JBE.isNotFound(e));
126    }
127    t.true(error != null);
128    error = null;
129
130    count = await db.createQuery('@mycoll/* | count').use(q => q.scalarInt());
131    t.is(count, 1);
132
133    // Patch
134    await db.patch('mycoll', '[{"op":"add", "path":"/baz", "value":"qux"}]', 2);
135    doc = await db.get('mycoll', 2);
136    t.deepEqual(doc, { foo: 'baz', baz: 'qux' });
137
138    // DB Info
139    doc = await db.info();
140    assert.deepNestedInclude(doc, {
141      'collections[0]': {
142        name: 'mycoll',
143        rnum: 1,
144        dbid: 3,
145        indexes: []
146      }
147    });
148
149    // Indexes
150    await db.ensureStringIndex('mycoll', '/foo', true);
151    doc = await db.info();
152    assert.deepNestedInclude(doc, {
153      'collections[0].indexes[0]': {
154        ptr: '/foo',
155        mode: 5,
156        idbf: 0,
157        dbid: 4,
158        rnum: 1
159      }
160    });
161
162    // Test JQL set
163    doc = await db.createQuery('@mycoll/[foo=:?]')
164      .setString(0, 'baz').use(q => q.first());
165    assert.deepInclude(doc.json, {
166      foo: 'baz',
167      baz: 'qux'
168    });
169
170    // Test explain log
171    let log;
172    q = await db.createQuery('@mycoll/[foo=:?]')
173      .setString(0, 'baz')
174      .withExplain();
175    await q.useExecute();
176    log = q.explainLog;
177    t.true(log.indexOf('[INDEX] MATCHED  UNIQUE|STR|1 /foo EXPR1: \'foo = :?\' INIT: IWKV_CURSOR_EQ') != -1);
178
179
180    await db.createQuery('@mycoll/[foo=:?]')
181      .setString(0, 'baz')
182      .useExecute((jbdoc, jql) => {
183        t.true(jql != null);
184        q.explainLog;
185        t.true(log.indexOf('[INDEX] MATCHED  UNIQUE|STR|1 /foo EXPR1: \'foo = :?\' INIT: IWKV_CURSOR_EQ') != -1);
186      });
187
188    doc = await db.createQuery('@mycoll/[foo=:?] and /[baz=:?]')
189      .setString(0, 'baz')
190      .setString(1, 'qux')
191      .use(q => q.first());
192
193    assert.deepInclude(doc.json, {
194      foo: 'baz',
195      baz: 'qux'
196    });
197
198
199    doc = await db.createQuery('@mycoll/[foo re :?]').setRegexp(0, '.*').use(q => q.first());
200    assert.deepInclude(doc.json, {
201      foo: 'baz',
202      baz: 'qux'
203    });
204
205    doc = await db.createQuery('@mycoll/[foo re :?]').setRegexp(0, /.*/).use(q => q.first());
206    assert.deepInclude(doc.json, {
207      foo: 'baz',
208      baz: 'qux'
209    });
210
211    doc = await db.createQuery('@mycoll/* | /foo').use(q => q.first());
212    assert.deepEqual(doc.json, { foo: 'baz' });
213
214    await db.removeStringIndex('mycoll', '/foo', true);
215    doc = await db.info();
216
217    const dbfile = doc.file;
218    t.true(typeof dbfile == 'string');
219
220    assert.deepNestedInclude(doc, {
221      'collections[0].indexes': []
222    });
223
224    await db.removeCollection('mycoll');
225    doc = await db.info();
226    assert.deepNestedInclude(doc, {
227      'collections': []
228    });
229
230    q = db.createQuery('@c1/* | limit 2 skip 3');
231    t.is(q.limit, 2);
232    t.is(q.skip, 3);
233    q.close();
234
235    // Rename collection
236    id = await db.put('cc1', { 'foo': 1 });
237    t.true(id > 0);
238    doc = await db.get('cc1', id);
239    t.deepEqual(doc, { 'foo': 1 });
240
241    await db.renameCollection('cc1', 'cc2');
242    doc = await db.get('cc2', id);
243    t.deepEqual(doc, { 'foo': 1 });
244
245
246    let i = 0;
247    for (i = 0; i < 1023; ++i) {
248      await db.put('load', { 'name': `v${i}` });
249    }
250
251    i = 0;
252    await db.createQuery('@load/* | inverse').useExecute(((jbdoc) => {
253      const json = jbdoc.json;
254      t.is(json.name, `v${i}`);
255      i++;
256    }));
257    t.is(i, 1023);
258
259    const ts0 = +new Date();
260    const ts = await db.onlineBackup(`${dbfile}.bkp`);
261    t.true(ts0 < ts);
262
263    await db.close();
264
265    // Restore from backup
266    const db2 = await EJDB2.open('hello.db.bkp', { truncate: false });
267    doc = await db2.get('cc2', id);
268    t.deepEqual(doc, { 'foo': 1 });
269    await db2.close();
270  }
271
272  render() {
273    return (
274      <View style={styles.container}>
275        {this.state.status
276          ? <Text testID="status">{this.state.status}</Text>
277          : <Button testID="run" title="Run tests" onPress={e => this.run()}></Button>}
278      </View>
279    );
280  }
281
282  async run() {
283    try {
284      this.setState({ status: 'Testing' });
285
286      await this.test();
287
288      this.setState({ status: 'OK' });
289    } catch (e) {
290      console.log('Error ', e);
291      this.setState({ status: `${e.code || ''} ${e}` });
292      throw e;
293    }
294  }
295}
296
297const styles = StyleSheet.create({
298  container: {
299    flex: 1,
300    justifyContent: 'center',
301    alignItems: 'center',
302    backgroundColor: '#F5FCFF',
303  },
304});
305