Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
iberflow committed Oct 20, 2016
1 parent 2388978 commit c90ff05
Show file tree
Hide file tree
Showing 12 changed files with 552 additions and 2 deletions.
4 changes: 4 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"presets": ["es2015"],
"plugins": ["transform-runtime"]
}
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/**
dist/**
22 changes: 22 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module.exports = {
root: true,
parserOptions: {
sourceType: 'module',
ecmaFeatures: {
experimentalObjectRestSpread: true
}
},
env: {
browser: true,
node: true
},
extends: 'standard',
'rules': {
// allow paren-less arrow functions
'arrow-parens': 0,
// allow async-await
'generator-star-spacing': 0,
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
}
}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.DS_Store
node_modules
.idea
112 changes: 110 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,110 @@
# dexie-relationships
Dexie relationship plugin
Dexie.js relationship plugin
========

Dexie.js is a wrapper library for indexedDB - the standard database in the browser.

Dexie relationship plugin provides an API to ease the loading of relational data from foreign tables

Installation
========

npm:
```
npm install dexie-relationships --save
```

bower:
```
bower install dexie-relationships --save
```

API Example
========

#### Schema
Note the use of `->` which sets the foreign keys.

```javascript
db.version(1).stores({
projects: '++id',
project_settings: '++id, project_id -> projects.id',
project_members: '++id, project_id -> projects.id'
})
```

#### Seed the data

```javascript
db.projects.add({name: 'Project #1'})
db.projects.add({name: 'Project #2'})

db.project_settings.add({name: 'Setting #1', project_id: 1})
db.project_settings.add({name: 'Setting #2', project_id: 2})
db.project_settings.add({name: 'Setting #3', project_id: 1})

db.project_members.add({name: 'Member #1', project_id: 1})
db.project_members.add({name: 'Member #2', project_id: 2})
db.project_members.add({name: 'Member #3', project_id: 1})
```

#### Usage

```javascript
db.with({
'settings': 'project_settings',
'members': 'project_members'
}).then(rows => console.log(rows))
```

#### Result

```json
[
{
"name":"Project #1",
"id":1,
"settings":[
{
"name":"Setting #1",
"project_id":1,
"id":1
},
{
"name":"Setting #3",
"project_id":1,
"id":3
}
],
"members":[
{
"name":"Member #1",
"project_id":1,
"id":1
},
{
"name":"Member #3",
"project_id":1,
"id":3
}
]
},
{
"name":"Project #2",
"id":2,
"settings":[
{
"name":"Setting #2",
"project_id":2,
"id":2
}
],
"members":[
{
"name":"Member #2",
"project_id":2,
"id":2
}
]
}
]
```
15 changes: 15 additions & 0 deletions bower.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "dexie-relationships",
"description": "Dexie relationship plugin",
"main": "dist/dexie-relationships.js",
"authors": [
"Ignas Bernotas"
],
"license": "MIT",
"keywords": [
"dexie",
"relationships",
"plugin"
],
"homepage": "https://github.com/ignasbernotas/dexie-relationships"
}
122 changes: 122 additions & 0 deletions dist/dexie-relationships.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
'use strict';

var _promise = require('babel-runtime/core-js/promise');

var _promise2 = _interopRequireDefault(_promise);

var _keys = require('babel-runtime/core-js/object/keys');

var _keys2 = _interopRequireDefault(_keys);

var _dexie = require('dexie');

var _dexie2 = _interopRequireDefault(_dexie);

var _schemaParser = require('./schema-parser');

var _schemaParser2 = _interopRequireDefault(_schemaParser);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var Relationships = function Relationships(db) {
/**
* Iterate through all items and collect related records
*
* @param relationships
*
* @returns {Dexie.Promise}
*/
db.Table.prototype.with = function (relationships) {
return this.toCollection().with(relationships);
};

/**
* Iterate through all items and collect related records
*
* @param relationships
*
* @returns {Dexie.Promise}
*/
db.Collection.prototype.with = function (relationships) {
var self = this;
var baseTable = this._ctx.table.name;
var databaseTables = db._allTables;

// this holds tables that have foreign keys pointing at the current table
var usableForeignTables = {};

// validate target tables and add them into our usable tables object
(0, _keys2.default)(relationships).forEach(function (column) {
var table = relationships[column];

if (!databaseTables.hasOwnProperty(table)) {
throw new Error('Relationship table ' + table + ' doesn\'t exist.');
}

if (!databaseTables[table].schema.hasOwnProperty('foreignKeys')) {
throw new Error('Relationship table ' + table + ' doesn\'t have foreign keys set.');
}

// remove the foreign keys that don't link to the base table
var columns = databaseTables[table].schema.foreignKeys.filter(function (column) {
return column.targetTable === baseTable;
});

if (columns.length > 0) {
usableForeignTables[table] = {
column: column,
foreign: columns[0]
};
}
});

return new _dexie2.default.Promise(function (resolve) {
self.toArray().then(function (rows) {
var queue = [];

// loop through all rows and collect all data from the related table
rows.forEach(function (row) {
var tables = (0, _keys2.default)(usableForeignTables);

tables.forEach(function (table) {
var relatedTable = usableForeignTables[table];

var promise = databaseTables[table].where(relatedTable.foreign.index).equals(row[relatedTable.foreign.targetIndex]).toArray().then(function (relations) {
row[relatedTable.column] = relations;
});

queue.push(promise);
});
});

// we need to wait until all data is retrieved
// once it's there we can resolve the promise
_promise2.default.all(queue).then(function () {
resolve(rows);
});
});
});
};

db.Version.prototype._parseStoresSpec = _dexie2.default.override(db.Version.prototype._parseStoresSpec, function (parseStoresSpec) {
return function (storesSpec, outDbSchema) {
var parser = new _schemaParser2.default(storesSpec);

var foreignKeys = parser.getForeignKeys();
// call the original method
var rv = parseStoresSpec.call(this, parser.getCleanedSchema(), outDbSchema);

// set foreign keys into database table objects
// to use later in 'with' method
(0, _keys2.default)(outDbSchema).forEach(function (table) {
if (foreignKeys.hasOwnProperty(table)) {
outDbSchema[table].foreignKeys = foreignKeys[table];
}
});

return rv;
};
});
};

_dexie2.default.addons.push(Relationships);
47 changes: 47 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "dexie-relationships",
"version": "1.0.0",
"description": "Dexie relationship plugin",
"main": "dist/dexie-relationships.js",
"directories": {
"test": "tests"
},
"dependencies": {
},
"devDependencies": {
"babel-cli": "^6.16.0",
"babel-loader": "^6.2.5",
"babel-preset-es2015": "^6.16.0",
"chai": "^3.5.0",
"eslint": "^3.8.1",
"eslint-config-standard": "^6.2.0",
"eslint-plugin-promise": "^3.3.0",
"eslint-plugin-standard": "^2.0.1",
"mocha": "^3.1.2",
"webpack": "^1.13.2"
},
"scripts": {
"build": "babel --presets es2015 src/index.js -o dist/dexie-relationships.js",
"test": "npm run eslint && npm run mocha",
"eslint": "eslint src",
"mocha": "./node_modules/.bin/mocha --compilers js:babel-core/register --reporter spec"
},
"babel": {
"presets": ["es2015"]
},
"repository": {
"type": "git",
"url": "git+https://github.com/ignasbernotas/dexie-relationships.git"
},
"keywords": [
"dexie",
"relationships",
"plugin"
],
"author": "Ignas Bernotas",
"license": "MIT",
"bugs": {
"url": "https://github.com/ignasbernotas/dexie-relationships/issues"
},
"homepage": "https://github.com/ignasbernotas/dexie-relationships#readme"
}
Loading

0 comments on commit c90ff05

Please sign in to comment.