Skip to content

Commit

Permalink
Implement find and filter
Browse files Browse the repository at this point in the history
  • Loading branch information
markwylde committed Nov 17, 2022
1 parent 6e9886c commit 3f255fe
Show file tree
Hide file tree
Showing 6 changed files with 491 additions and 398 deletions.
41 changes: 29 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,41 @@ npm install --save doubledb
- [x] replace
- [x] patch
- [x] remove
- [ ] find
- [x] find
- [x] filter
- [ ] query

## Usage
```javascript
const createDoubled = require('doubledb')
const doubled = doubled('./data')
import createDoubledb from 'doubledb';
const doubledb = createDoubledb('./data');

doubled.insert({
doubledb.insert({
id: undefined, // defaults to uuid, must be unique
firstName: 'Joe',
lastName: 'Bloggs'
})
lastName: 'Bloggs',
stats: {
wins: 10,
loses: 5
},
skills: ['cooking', 'running']
});

doubledb.get(record.id);
doubledb.find('firstName', 'Joe');
doubledb.find('stats.wins', 10);
doubledb.find('skills', 'cooking');
doubledb.find('firstName', v => v.startsWith('J'));
doubledb.filter('firstName', 'Joe');
doubledb.filter('firstName', v => v.startsWith('J'));
doubledb.replace(record.id, { firstName: 'Joe', lastName: 'Bloggs' });
doubledb.patch(record.id, { firstName: 'Bob' });
doubledb.remove(record.id);
```

const record = doubled.find({
### Proposed Query
```javascript
const record = doubledb.query({
location: 'London',
category: 'b',

Expand All @@ -43,8 +64,4 @@ const record = doubled.find({
}
}
})

doubled.replace(record.id, { firstName: 'Joe', lastName: 'Bloggs' })
doubled.patch(record.id, { firstName: 'Bob' })
doubled.remove(record.id)
```
```
67 changes: 60 additions & 7 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const fs = require('fs').promises;
const { Level } = require('level');
const uuid = require('uuid').v4;
import { promises as fs } from 'fs';
import { Level } from 'level';
import { v4 as uuid } from 'uuid';

function notFoundToUndefined (error) {
if (error.code === 'LEVEL_NOT_FOUND') {
Expand All @@ -10,18 +10,29 @@ function notFoundToUndefined (error) {
throw error;
}

const isObject = thing => thing instanceof Object && !Array.isArray(thing);

async function createDoubleDb (dataDirectory) {
await fs.mkdir(dataDirectory, { recursive: true });

const db = new Level(dataDirectory);

async function addToIndexes (id, object, prefix = '') {
const promises = Object.keys(object).map(key => {
if (typeof object[key] === 'object') {
return addToIndexes(id, object[key], prefix + '.' + key);
if (isObject(object[key])) {
addToIndexes(id, object[key], prefix + '.' + key);
return null;
}

if (Array.isArray(object[key])) {
for (const index in object[key]) {
db.put('indexes' + prefix + '.' + key + '.' + id + '=' + object[key][index], id);
}
return null;
}

return db.put('indexes' + prefix + '.' + key + '.' + id + '=' + object[key], id);
db.put('indexes' + prefix + '.' + key + '.' + id + '=' + object[key], id);
return null;
});

return Promise.all(promises);
Expand Down Expand Up @@ -123,6 +134,46 @@ async function createDoubleDb (dataDirectory) {
return JSON.parse(document);
}

async function findOrFilter (type, key, valueOrFunction) {
const lookupType = valueOrFunction instanceof Function ? 'function' : 'value';

const promises = [];
for await (const [ckey, id] of db.iterator({
gt: `indexes.${key}.`,
lt: `indexes.${key}~`
})) {
const [, lvalue] = ckey.split('=');
if (lookupType === 'value' && lvalue == valueOrFunction) {
promises.push(read(id));
if (type === 'find') {
break;
}
}

if (lookupType === 'function' && valueOrFunction(lvalue)) {
promises.push(read(id));
if (type === 'find') {
break;
}
}
}

const results = await Promise.all(promises);
if (type === 'filter') {
return results;
} else {
return results[0];
}
}

async function find (key, valueOrFunction) {
return findOrFilter('find', key, valueOrFunction);
}

async function filter (key, valueOrFunction) {
return findOrFilter('filter', key, valueOrFunction);
}

async function remove (id) {
if (!id) {
throw new Error('doubledb.remove: no id was supplied to replace function');
Expand All @@ -140,6 +191,8 @@ async function createDoubleDb (dataDirectory) {

return {
_level: db,
find,
filter,
insert,
replace,
patch,
Expand All @@ -149,4 +202,4 @@ async function createDoubleDb (dataDirectory) {
};
}

module.exports = createDoubleDb;
export default createDoubleDb;
Loading

0 comments on commit 3f255fe

Please sign in to comment.