Bring up the schema loading from json docs

This commit is contained in:
Raymond Feng 2013-05-20 16:05:59 -07:00
parent 347147a36b
commit 184c190223
7 changed files with 256 additions and 4 deletions

15
examples/jdb-schemas.json Normal file
View File

@ -0,0 +1,15 @@
{
"title": {
"type": "String"
},
"author": {
"type": "String",
"default": "Raymond"
},
"body": "String",
"date": {
"type": "Date"
},
"hidden": "Boolean",
"comments": ["String"]
}

19
examples/load-schemas.js Normal file
View File

@ -0,0 +1,19 @@
var path = require('path');
var loadSchemasSync = require('../lib/adl-loader').loadSchemasSync;
var models = loadSchemasSync(path.join(__dirname, 'jdb-schemas.json'));
for (var s in models) {
var m = models[s];
// console.dir(m);
console.log(new m());
}
models = loadSchemasSync(path.join(__dirname, 'schemas.json'));
for (var s in models) {
var m = models[s];
// console.dir(m);
console.log(new m());
}

83
examples/schemas.json Normal file
View File

@ -0,0 +1,83 @@
[
{
"name": "Address",
"properties": {
"label": "string",
"street": "string",
"city": "string",
"zipCode": "string"
}
},
{
"name": "Account",
"properties": {
"id": "string",
"customer": {
"type": "Customer",
"association": {
"type": "belongsTo",
"inverse": "account"
}
},
"balance": "number"
}
},
{
"name": "Customer",
"options": {
"oracle": {
"owner": "STRONGLOOP",
"table": "CUSTOMER"
}
},
"properties": {
"id": {
"type": "number",
"id": true,
"doc": "Customer ID"
},
"firstName": {
"type": "string",
"trim": true,
"required": true,
"oracle": {
"column": "FNAME",
"type": "VARCHAR",
"length": 32
}
},
"lastName": {
"type": "string",
"trim": true,
"required": true,
"oracle": {
"column": "LNAME",
"type": "VARCHAR",
"length": 32
}
},
"vip": {
"type": "boolean",
"doc": "indicate if the customer is a VIP",
"oracle": {
"column": "VIP",
"type": "CHAR",
"length": 1
}
},
"emails": [
{
"type": "string",
"trim": true
}
],
"address": {
"type": "Address"
},
"account": "Account"
}
}
]

125
lib/adl-loader.js Normal file
View File

@ -0,0 +1,125 @@
var fs = require('fs')
, DataSource = require('./datasource').DataSource;
// Built-in data types
var builtinTypes = {
'string': String,
'number': Number,
'date': Date,
'buffer': Buffer,
'binary': Buffer,
'boolean': Boolean,
'any': DataSource.Any,
'array': Array
}
/**
* Resolve the type to be a function
* @param type
* @returns {*}
*/
function getSchemaType(type) {
if (!type) {
return type;
}
if (Array.isArray(type) && type.length > 0) {
var itemType = getSchemaType(type[0]);
if (typeof itemType === 'function') {
return [itemType];
}
else return itemType;
}
if (typeof type === 'string') {
var schemaType = builtinTypes[type.toLowerCase()];
if (schemaType) {
return schemaType;
} else {
return type;
}
} else if (type.constructor.name == 'Object') {
if (type.type) {
return getSchemaType(type.type);
} else {
throw new Error('Missing type property');
}
}
}
/**
*
* @param name
* @param properties
* @param associations
* @returns {*}
*/
function buildSchema(name, properties, associations) {
for (var p in properties) {
console.log(name + "." + p + ": " + properties[p]);
var type = getSchemaType(properties[p]);
if (typeof type === 'string') {
console.log('Association: ' + type);
associations.push({
source: name,
target: type,
relation: Array.isArray(properties[p]) ? 'hasMany' : 'belongsTo',
as: p
});
delete properties[p];
} else {
properties[p] = type;
}
}
return properties;
}
/**
* Load ADL schemas from a json doc
* @param schemaFile The schema json file
* @returns A map of schemas keyed by name
*/
function loadSchemasSync(schemaFile, dataSource) {
if(!dataSource) {
dataSource = new DataSource('memory');
}
var models = {};
var schemas = JSON.parse(fs.readFileSync(schemaFile));
if (Array.isArray(schemas)) {
// An array already
} else if (schemas.properties && schemas.name) {
schemas = [schemas];
} else {
schemas = [
{
name: 'Anonymous',
properties: schemas
}
];
}
var associations = [];
for (var s in schemas) {
var name = schemas[s].name;
console.log('Loading ' + name);
var jdbSchema = buildSchema(name, schemas[s].properties, associations);
console.dir(jdbSchema);
var model = dataSource.define(name, jdbSchema);
console.dir(model);
models[name.toLowerCase()] = model;
}
for (var i = 0; i < associations.length; i++) {
var association = associations[i];
var sourceModel = models[association.source.toLowerCase()];
var targetModel = models[association.target.toLowerCase()];
if (sourceModel && targetModel) {
sourceModel[association.relation](targetModel, {as: association.as});
}
}
return models;
}
exports.loadSchemasSync = loadSchemasSync;

View File

@ -2,7 +2,7 @@
* Module dependencies * Module dependencies
*/ */
var ModelBaseClass = require('./model.js'); var ModelBaseClass = require('./model.js');
var DataAccessObject = require('./dao.js'); // var DataAccessObject = require('./dao.js');
var List = require('./list.js'); var List = require('./list.js');
var EventEmitter = require('events').EventEmitter; var EventEmitter = require('events').EventEmitter;
var util = require('util'); var util = require('util');
@ -15,7 +15,7 @@ var existsSync = fs.existsSync || path.existsSync;
* Export public API * Export public API
*/ */
exports.Schema = Schema; exports.Schema = Schema;
exports.ADL= new Schema();
// exports.ModelBaseClass = ModelBaseClass; // exports.ModelBaseClass = ModelBaseClass;
/** /**
@ -25,6 +25,7 @@ var slice = Array.prototype.slice;
Schema.Text = function Text() {}; Schema.Text = function Text() {};
Schema.JSON = function JSON() {}; Schema.JSON = function JSON() {};
Schema.Any = function Any() {};
Schema.types = {}; Schema.types = {};
Schema.registerType = function (type) { Schema.registerType = function (type) {
@ -33,6 +34,14 @@ Schema.registerType = function (type) {
Schema.registerType(Schema.Text); Schema.registerType(Schema.Text);
Schema.registerType(Schema.JSON); Schema.registerType(Schema.JSON);
Schema.registerType(Schema.Any);
Schema.registerType(String);
Schema.registerType(Number);
Schema.registerType(Boolean);
Schema.registerType(Date);
Schema.registerType(Buffer);
Schema.registerType(Array);
/** /**
@ -321,3 +330,4 @@ function defineReadonlyProp(obj, key, value) {
}); });
} }
exports.ADL = new Schema();

View File

@ -6,7 +6,7 @@ exports.Hookable = Hookable;
/** /**
* Hooks mixins for ./model.js * Hooks mixins for ./model.js
*/ */
var Hookable = require('./dao.js'); var Hookable = require('./model.js');
/** /**
* List of hooks available * List of hooks available

View File

@ -8,7 +8,7 @@ module.exports = ModelBaseClass;
*/ */
var util = require('util'); var util = require('util');
var List = require('./list.js'); var List = require('./list.js');
require('./hooks.js');
var BASE_TYPES = ['String', 'Boolean', 'Number', 'Date', 'Text']; var BASE_TYPES = ['String', 'Boolean', 'Number', 'Date', 'Text'];