Skip to content
This repository has been archived by the owner on Oct 6, 2019. It is now read-only.

Commit

Permalink
Implemented initial version (#1)
Browse files Browse the repository at this point in the history
* First commit

* Port to ES6

* Added tests

* Added tests

* Added first version of documentation
  • Loading branch information
zhenyab authored and roll committed Jan 25, 2017
1 parent 5aca269 commit 3932110
Show file tree
Hide file tree
Showing 16 changed files with 612 additions and 2 deletions.
20 changes: 20 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"presets": [
"es2015"
],
"plugins": [
"transform-es2015-arrow-functions",
"transform-es2015-for-of",
"transform-es2015-literals",
"transform-es2015-shorthand-properties",
"transform-es2015-modules-commonjs",
"transform-es2015-classes",
[
"transform-es2015-template-literals",
{
"loose": true,
"spec": true
}
]
]
}
48 changes: 48 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
extends:
airbnb
environment:
es6
env:
node: true
browser: true
parserOptions:
sourceType: module
rules:
quotes:
- 2
- single
- avoid-escape
semi:
- 2
- never
comma-style:
- 2
- first
comma-dangle:
- 2
- never
no-empty:
- 2
- allowEmptyCatch: true
no-use-before-define:
- 2
- nofunc
one-var:
- 1
- var: always
let: always
const: always
eqeqeq:
- 1
- smart
no-unused-vars:
- 1
no-param-reassign:
- 1
no-cond-assign:
- 2
- except-parens
arrow-parens:
- 2
- as-needed
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ coverage

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

lib/
dist/
# Dependency directories
node_modules
jspm_packages
Expand All @@ -35,3 +36,6 @@ jspm_packages

# Optional REPL history
.node_repl_history

# Files of IDE
.idea/
90 changes: 89 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,90 @@
# jsontableschema-orm-js
An (object relational) mapper based on JSON Table Schema descriptors.
An (object relational) mapper based on JSON Table Schema descriptors.
This library created to be used together with the [jsontableschema-js](https://github.com/frictionlessdata/jsontableschema-js) to simplify working with data.

## Installation
`npm install jsontableschema-models`

### Model
Represents the row of the data in the given table. It instantiated via define method, and returns `Promise` and inside resolved Promise model object is available,
but this object should be loaded by the `Storage` (see below) to be able to work with it.

##### Config object:
* `tableName` - name of the collection
* `resource` - URL or path to the resource with data
* `descriptor` - JSON table schema descriptor
* `instanceMethods` - custom methods to work with data will be available on every instance of the model (see example below)

##### Methods:
There is only 1 method possible to use on model and inside instance methods:
* `keyed` - map of values to headers of the data row

### Storage
Component which take care of loading data of the model into memory and keep it under the collection, which has same name as `model table name`.
Available methods:
* `add(tableName: string, items: any[])` - Add to collection. If collection does not exists, creates new.
* `all(tableName: string)` - Get all data from table. Returns model for each row
* `load(model)` - Load data of model into memory

## Usage
1. First need to create model definition:
```javascript
import jtsModels from 'path/to/lib'

const model = jtsModels.define({
tableName: 'cases',
resource: 'http://url/to/csv/file/with/data',
descriptor: {
"fields": [
{
"name": "id",
"title": "",
"description": "",
"type": "integer",
"format": "default"
},
{
"name": "name",
"title": "",
"description": "",
"type": "string",
"format": "default"
}
]
},
instanceMethods: {
proceed: function() {
const data = this.keyed()
let type = 'odd'
if(data.id % 2 === 0) {
type = 'even'
}
return {
type: type,
name: data.name
}
}
}
})
```

2. Load model by the storage:
```javascript
model().then(model => {
// load data of the model to memory
jtsModels.Storage.load(model).then(() => {
// get all data from table. Returns model for each row
const models = jtm.Storage.all(model.tableName)
const result = []
// ... iterate through all the models in collection and do something with data
models.forEach(model => {
// call instance method from config of the model
result.push(model.proceed());
})
}, error => {
// error in case if storage can't load model
});
}, error => {
// do something in case error if model definition is broke
});
```
5 changes: 5 additions & 0 deletions data/example1.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
id,capital,url
1,39.00$,http://www.test.com
2,23.00$,http://www.test.de
3,36.00$,http://www.test.uk
4,28.00$,http://www.test.co.il
25 changes: 25 additions & 0 deletions data/schema_example1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"fields": [
{
"name": "id",
"title": "",
"description": "",
"type": "integer",
"format": "default"
},
{
"name": "capital",
"title": "",
"description": "",
"type": "number",
"format": "currency"
},
{
"name": "url",
"title": "",
"description": "",
"type": "string",
"format": "uri"
}
]
}
87 changes: 87 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
{
"name": "jsontableschema-models-js",
"version": "0.0.1",
"description": "An (object relational) mapper based on JSON Table Schema descriptors.",
"keywords": [
"data package",
"json table schema",
"frictionless data",
"open data",
"open knowledge"
],
"engines": {
"node": ">=4"
},
"main": "lib/index.js",
"dependencies": {
"babel-cli": "^6.22.2",
"babel-loader": "^6.2.10",
"babel-plugin-transform-es2015-arrow-functions": "^6.22.0",
"babel-plugin-transform-es2015-classes": "^6.22.0",
"babel-plugin-transform-es2015-for-of": "^6.22.0",
"babel-plugin-transform-es2015-literals": "^6.22.0",
"babel-plugin-transform-es2015-modules-commonjs": "^6.22.0",
"babel-plugin-transform-es2015-shorthand-properties": "^6.22.0",
"babel-plugin-transform-es2015-template-literals": "^6.22.0",
"babel-polyfill": "^6.22.0",
"babel-preset-es2015": "^6.22.0",
"jsontableschema": "^0.2.1",
"lodash": "^4.17.4",
"webpack": "^1.14.0"
},
"devDependencies": {
"babel": "^6.5.2",
"babel-cli": "^6.8.0",
"babel-istanbul": "^0.8.0",
"babel-loader": "^6.2.1",
"babel-plugin-transform-es2015-arrow-functions": "^6.8.0",
"babel-plugin-transform-es2015-classes": "^6.8.0",
"babel-plugin-transform-es2015-for-of": "^6.8.0",
"babel-plugin-transform-es2015-literals": "^6.8.0",
"babel-plugin-transform-es2015-modules-commonjs": "^6.8.0",
"babel-plugin-transform-es2015-shorthand-properties": "^6.8.0",
"babel-plugin-transform-es2015-template-literals": "^6.8.0",
"babel-polyfill": "^6.3.14",
"babel-preset-es2015": "^6.6.0",
"chai": "^2.3.0",
"chai-spies": "^0.6.0",
"mocha": "^2.4.5",
"webpack": "^1.12.11",
"webpack-dev-server": "^1.14.1"
},
"scripts": {
"build:lib": "babel src --out-dir lib",
"build:dist": "webpack --config webpack.config.development.js",
"build:dist:min": "webpack --config webpack.config.production.js",
"build": "npm run build:lib && npm run build:dist && npm run build:dist:min",
"prepublish": "npm run build",
"review": "eslint src/**",
"fix": "eslint --fix src/**",
"test": "mocha",
"coverage": "node_modules/.bin/babel-node node_modules/.bin/babel-istanbul cover node_modules/.bin/_mocha -- test/*.js"
},
"files": [
"lib",
"dist",
"src"
],
"author": {
"name": "Open Knowledge",
"email": "[email protected]",
"url": "https://okfn.org/"
},
"contributors": [
{
"name": "Eugene Bogomolny",
"email": "[email protected]",
"url": "http://zhenyab.me"
}
],
"homepage": "https://github.com/frictionlessdata/jsontableschema-models-js",
"bugs": "https://github.com/frictionlessdata/jsontableschema-models-js/issues",
"repository": {
"type": "git",
"url": "https://github.com/frictionlessdata/jsontableschema-models-js.git"
},
"license": "MIT"
}
74 changes: 74 additions & 0 deletions src/define.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import _ from 'lodash'
import jts from 'jsontableschema'

/**
* @param config
* @constructor
*/
class Model {
constructor(config, descriptor) {
if (!config || !config.tableName) {
throw new Error('Table name is required')
}

this.tableName = config.tableName
this.resource = config.resource
this.config = config
this.row = null

const self = this
, methods = ['clone', 'keyed']

if (_.isPlainObject(config.instanceMethods)) {
_.forOwn(config.instanceMethods, (value, key) => {
if (methods.indexOf(key) === -1) {
self[key] = value.bind(self)
}
})
}

if (!descriptor) {
return new Promise((resolve, reject) => {
(new jts.Schema(config.descriptor)).then(schema => {
self.descriptor = schema
resolve(self)
}).catch(error => {
reject(error)
})
})
}
self.descriptor = descriptor
return this
}

get data() {
return this.row
}

set data(row) {
this.row = row
}

/**
* Return object with map of values to headers of the row of values
* @returns {Object}
*/
keyed() {
if (!this.row) {
return {}
}
const result = {}
, row = this.row

_.forEach(this.descriptor.headers, (header, index) => {
result[header] = row[index]
})
return result
}

clone() {
return new Model(this.config, this.descriptor)
}
}

export default config => new Model(config)
7 changes: 7 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Storage from './storage'
import define from './define'

module.exports = {
Storage
, define
}
Loading

0 comments on commit 3932110

Please sign in to comment.