Comparing version 0.0.9 to 0.1.0
@@ -58,7 +58,12 @@ #!/usr/bin/env node | ||
cfg.connectString = m[4]; | ||
cfg.naming = options.naming; | ||
require('sqb-connect-' + cfg.dialect); | ||
sqb.use(require('sqb-connect-' + cfg.dialect)); | ||
const db = sqb.pool(cfg); | ||
const exporter = new uniqorm.MetadataExporter(db, includeSchemas, includeTables, excludeTables); | ||
const exporter = new uniqorm.MetadataExporter(db, { | ||
includeSchemas, | ||
includeTables, | ||
excludeTables | ||
}); | ||
@@ -133,7 +138,7 @@ //exporter.on('process', | ||
chalk.yellow(' Output filename') | ||
) | ||
.option('-s, --schema [schema]', 'Comma seperated schema names to be included in export list. All schemas will be exported if not specified') | ||
.option('-i, --include [table]', 'Comma seperated table names to be included in export list. All tables will be exported if not specified') | ||
.option('-s, --schema <schema>', 'Comma seperated schema names to be included in export list. All schemas will be exported if not specified') | ||
.option('-i, --include <table>', 'Comma seperated table names to be included in export list. All tables will be exported if not specified') | ||
.option('-e, --exclude <table>', 'Comma seperated table names to be excluded from export list') | ||
.option('-n, --naming <rule>', 'Naming enumeration value. (lowercase,uppercase)') | ||
.option('-w, --write <fileName>', 'Write result json to given file') | ||
@@ -140,0 +145,0 @@ .action(exp); |
@@ -20,8 +20,12 @@ /* UNIQORM | ||
constructor(dbPool, includeSchema, includeTables, excludeTables) { | ||
constructor(dbPool, options) { | ||
super(); | ||
this.dbPool = dbPool; | ||
this.includeSchema = includeSchema; | ||
this.includeTables = includeTables; | ||
this.excludeTables = excludeTables; | ||
if (options) { | ||
this.includeSchemas = options.includeSchemas; | ||
this.includeTables = options.includeTables; | ||
this.excludeTables = options.excludeTables; | ||
} | ||
this.naming = options && options.naming !== undefined ? | ||
options.naming : dbPool.config.naming; | ||
} | ||
@@ -31,11 +35,10 @@ | ||
if (!callback) | ||
return Promisify.fromCallback((cb)=>this.execute(cb)); | ||
return Promisify.fromCallback((cb) => this.execute(cb)); | ||
const self = this; | ||
let connection; | ||
let tables; | ||
const out = {}; | ||
const db = self.dbPool; | ||
const conditions = []; | ||
if (this.includeSchema) | ||
conditions.push(['schema_name', 'like', self.includeSchema]); | ||
if (this.includeSchemas) | ||
conditions.push(['schema_name', 'like', self.includeSchemas]); | ||
if (this.includeTables) | ||
@@ -46,4 +49,12 @@ conditions.push(['table_name', 'like', this.includeTables]); | ||
callback = callback || function() { | ||
}; | ||
}; | ||
const setCase = function(val) { | ||
if (!val) return val; | ||
return self.naming === 'lowercase' ? | ||
val.toLowerCase() : | ||
(self.naming === | ||
'uppercase' ? val.toUpperCase() : val); | ||
}; | ||
waterfall([ | ||
@@ -53,5 +64,4 @@ /* Get connection from db pool */ | ||
self.emit('process', 'connect', 'connecting'); | ||
return self.dbPool.connect().then(conn => { | ||
return db.test().then(() => { | ||
self.emit('process', 'connect', 'connected'); | ||
connection = conn; | ||
next(); | ||
@@ -63,38 +73,32 @@ }); | ||
function(next) { | ||
let counter = 0; | ||
self.emit('process', 'tables', 'query'); | ||
return connection.meta() | ||
.select() | ||
.tables('schema_name', 'table_name', 'table_comments') | ||
return db.metaData | ||
.select('schema_name', 'table_name', 'table_comments') | ||
.from('tables') | ||
.where(...conditions) | ||
.execute({ | ||
resultSet: { | ||
autoClose: true | ||
} | ||
}, (err, ret) => { | ||
.execute({cursor: true}, (err, ret) => { | ||
if (err) | ||
next(err); | ||
else { | ||
tables = ret.resultSet; | ||
tables.next(100, (err, rows, more) => { | ||
if (err) | ||
next(err); | ||
else if (rows) { | ||
counter += rows.length; | ||
for (const row of rows) { | ||
const tableName = row.TABLE_NAME; | ||
self.emit('process', 'tables', 'iterate', tableName); | ||
const o = out[tableName] = {}; | ||
if (row.SCHEMA_NAME) | ||
o.schema = row.SCHEMA_NAME; | ||
if (row.TABLE_COMMENTS) | ||
o.comments = row.TABLE_COMMENTS; | ||
} | ||
more(); | ||
} else { | ||
self.emit('process', 'tables', 'done', counter); | ||
next(); | ||
} | ||
}); | ||
} | ||
return next(err); | ||
const dset = ret.dataset; | ||
let counter = 0; | ||
dset.next((err, more) => { | ||
if (err) | ||
return next(err); | ||
if (more) { | ||
counter++; | ||
const tableName = setCase(dset.values.table_name); | ||
self.emit('process', 'tables', 'iterate', tableName); | ||
const o = out[tableName] = {}; | ||
if (dset.values.schema_name) | ||
o.schema = setCase(dset.values.schema_name); | ||
if (dset.values.table_comments) | ||
o.comments = dset.values.table_comments; | ||
more(); | ||
} else { | ||
self.emit('process', 'tables', 'done', counter); | ||
dset.close(() => next()); | ||
} | ||
}); | ||
}); | ||
@@ -105,49 +109,42 @@ }, | ||
function(next) { | ||
let counter = 0; | ||
self.emit('process', 'columns', 'query'); | ||
return connection.meta() | ||
.select() | ||
.columns() | ||
return db.metaData | ||
.select('table_name', 'column_name', 'data_type', 'data_length', | ||
'data_precision', 'data_scale', 'column_comments', 'nullable') | ||
.from('columns') | ||
.where(...conditions) | ||
.execute({ | ||
resultSet: { | ||
autoClose: true | ||
} | ||
}, (err, ret) => { | ||
.execute({cursor: true}, (err, ret) => { | ||
if (err) | ||
next(err); | ||
else { | ||
tables = ret.resultSet; | ||
tables.next(100, (err, rows, more) => { | ||
if (err) | ||
next(err); | ||
else if (rows) { | ||
counter += rows.length; | ||
for (const row of rows) { | ||
self.emit('process', 'columns', 'iterate', row.TABLE_NAME + | ||
'.' + row.COLUMN_NAME); | ||
const tbl = out[row.TABLE_NAME]; | ||
if (tbl) { | ||
const fields = tbl.fields = tbl.fields || {}; | ||
const field = fields[row.COLUMN_NAME] = {}; | ||
field.type = row.DATA_TYPE; | ||
if (row.DATA_LENGTH) | ||
field.size = row.DATA_LENGTH; | ||
if (row.DATA_PRECISION !== null) | ||
field.precision = row.DATA_PRECISION; | ||
if (row.DATA_SCALE) | ||
field.scale = row.DATA_SCALE; | ||
if (row.COLUMN_COMMETS) | ||
field.comments = row.COLUMN_COMMETS; | ||
if (!row.NULLABLE) | ||
field.notNull = 1; | ||
} | ||
} | ||
more(); | ||
} else { | ||
self.emit('process', 'columns', 'done', counter); | ||
next(); | ||
return next(err); | ||
const dset = ret.dataset; | ||
let counter = 0; | ||
dset.next((err, more) => { | ||
if (err) | ||
return next(err); | ||
if (more) { | ||
counter++; | ||
self.emit('process', 'columns', 'iterate', | ||
dset.values.table_name + '.' + dset.values.column_name); | ||
const tbl = out[setCase(dset.values.table_name)]; | ||
if (tbl) { | ||
const fields = tbl.fields = tbl.fields || {}; | ||
const field = fields[setCase(dset.values.column_name)] = {}; | ||
field.type = dset.values.data_type; | ||
if (dset.values.data_length) | ||
field.size = dset.values.data_length; | ||
if (dset.values.data_precision !== null) | ||
field.precision = dset.values.data_precision; | ||
if (dset.values.data_scale !== null) | ||
field.scale = dset.values.data_scale; | ||
if (dset.values.column_comments) | ||
field.comments = dset.values.column_comments; | ||
if (!dset.values.nullable) | ||
field.notNull = 1; | ||
} | ||
}); | ||
} | ||
more(); | ||
} else { | ||
self.emit('process', 'columns', 'done', counter); | ||
dset.close(() => next()); | ||
} | ||
}); | ||
}); | ||
@@ -158,39 +155,32 @@ }, | ||
function(next) { | ||
let counter = 0; | ||
self.emit('process', 'primary keys', 'query'); | ||
return connection.meta() | ||
.select() | ||
.primaryKeys('table_name', 'constraint_name', 'status', 'columns') | ||
return db.metaData | ||
.select('table_name', 'constraint_name', 'status', 'columns') | ||
.from('primary_keys') | ||
.where(...conditions) | ||
.execute({ | ||
resultSet: { | ||
autoClose: true | ||
} | ||
}, (err, ret) => { | ||
.execute({cursor: true}, (err, ret) => { | ||
if (err) | ||
next(err); | ||
else { | ||
//self.emit('process', 'tables_listed'); | ||
tables = ret.resultSet; | ||
tables.next(100, (err, rows, more) => { | ||
if (err) | ||
next(err); | ||
else if (rows) { | ||
counter += rows.length; | ||
for (const row of rows) { | ||
self.emit('process', 'primary keys', 'iterate', row.CONSTRAINT_NAME); | ||
const tbl = out[row.TABLE_NAME]; | ||
if (tbl) | ||
tbl.primaryKey = { | ||
constraintName: row.CONSTRAINT_NAME, | ||
columns: row.COLUMNS | ||
}; | ||
} | ||
more(); | ||
} else { | ||
self.emit('process', 'primary keys', 'done', counter); | ||
next(); | ||
} | ||
}); | ||
} | ||
return next(err); | ||
//self.emit('process', 'tables_listed'); | ||
const dset = ret.dataset; | ||
let counter = 0; | ||
dset.next((err, more) => { | ||
if (err) | ||
return next(err); | ||
if (more) { | ||
counter++; | ||
self.emit('process', 'primary keys', 'iterate', dset.values.table_name); | ||
const tbl = out[setCase(dset.values.table_name)]; | ||
if (tbl) | ||
tbl.primaryKey = { | ||
constraintName: setCase(dset.values.constraint_name), | ||
columns: setCase(dset.values.columns) | ||
}; | ||
more(); | ||
} else { | ||
self.emit('process', 'primary keys', 'done', counter); | ||
dset.close(() => next()); | ||
} | ||
}); | ||
}); | ||
@@ -201,46 +191,38 @@ }, | ||
function(next) { | ||
let counter = 0; | ||
self.emit('process', 'foreign keys', 'query'); | ||
return connection.meta() | ||
.select() | ||
.foreignKeys('table_name', 'constraint_name', 'status', | ||
return db.metaData | ||
.select('table_name', 'constraint_name', 'status', | ||
'column_name', 'r_schema', 'r_table_name', 'r_columns') | ||
.from('foreign_keys') | ||
.where(...conditions) | ||
.execute({ | ||
resultSet: { | ||
autoClose: true | ||
} | ||
}, (err, ret) => { | ||
.execute({cursor: true}, (err, ret) => { | ||
if (err) | ||
next(err); | ||
else { | ||
//self.emit('process', 'tables_listed'); | ||
tables = ret.resultSet; | ||
tables.next(100, (err, rows, more) => { | ||
if (err) | ||
next(err); | ||
else if (rows) { | ||
counter += rows.length; | ||
for (const row of rows) { | ||
self.emit('process', 'foreign keys', 'iterate', row.CONSTRAINT_NAME); | ||
const tbl = out[row.TABLE_NAME]; | ||
if (tbl) { | ||
const arr = tbl.foreignKeys = | ||
(tbl.foreignKeys || []); | ||
arr.push({ | ||
constraintName: row.CONSTRAINT_NAME, | ||
column: row.COLUMN_NAME, | ||
remoteSchema: row.R_SCHEMA, | ||
remoteTable: row.R_TABLE_NAME, | ||
remoteColumns: row.R_COLUMNS | ||
}); | ||
} | ||
} | ||
more(); | ||
} else { | ||
self.emit('process', 'foreign keys', 'done', counter); | ||
next(); | ||
return next(err); | ||
const dset = ret.dataset; | ||
let counter = 0; | ||
dset.next((err, more) => { | ||
if (err) | ||
return next(err); | ||
if (more) { | ||
counter++; | ||
self.emit('process', 'foreign keys', 'iterate', dset.values.constraint_name); | ||
const tbl = out[setCase(dset.values.table_name)]; | ||
if (tbl) { | ||
const arr = tbl.foreignKeys = | ||
(tbl.foreignKeys || []); | ||
arr.push({ | ||
constraintName: setCase(dset.values.constraint_name), | ||
column: setCase(dset.values.column_name), | ||
remoteSchema: setCase(dset.values.r_schema), | ||
remoteTable: setCase(dset.values.r_table_name), | ||
remoteColumns: setCase(dset.values.r_columns) | ||
}); | ||
} | ||
}); | ||
} | ||
more(); | ||
} else { | ||
self.emit('process', 'foreign keys', 'done', counter); | ||
dset.close(() => next()); | ||
} | ||
}); | ||
}); | ||
@@ -253,6 +235,2 @@ } | ||
function(err) { | ||
if (connection) { | ||
connection.close(); | ||
connection = undefined; | ||
} | ||
if (err) | ||
@@ -259,0 +237,0 @@ self.emit('error', err); |
@@ -62,3 +62,3 @@ /* UNIQORM | ||
//noinspection JSUnresolvedVariable | ||
const f = this.meta.fields[name]; | ||
const f = this.meta.getField(name); | ||
if (f) { | ||
@@ -108,3 +108,3 @@ //noinspection JSUnresolvedVariable | ||
}; | ||
const meta = new ModelMeta(config); | ||
const meta = new ModelMeta(this, config); | ||
// static members | ||
@@ -144,3 +144,2 @@ Object.defineProperty(ctor, 'name', { | ||
const p = this.meta.fields[field]; | ||
assert.ok(p, `Model (${this.name}) has no field (${field})`); | ||
field = p.fieldName; | ||
@@ -170,3 +169,3 @@ | ||
constructor(config) { | ||
constructor(model, config) { | ||
@@ -177,5 +176,8 @@ const tableName = config.tableName || config.name; | ||
//noinspection JSUnusedGlobalSymbols | ||
this.model = model; | ||
/*//noinspection JSUnusedGlobalSymbols | ||
const fields = new Proxy({}, { | ||
get: function(obj, key) { | ||
if (typeof key === 'string') | ||
return typeof key === 'string' ? obj[key.toUpperCase()] : obj[key]; | ||
@@ -191,3 +193,3 @@ }, | ||
Field, `Invalid field definition for ${key}`); | ||
obj[key.toUpperCase()] = value; | ||
obj[key] = value; | ||
return true; | ||
@@ -200,4 +202,4 @@ } | ||
writable: false | ||
}); | ||
});*/ | ||
this._fields = []; | ||
if (config) { | ||
@@ -213,6 +215,49 @@ this.setTable(config.tableName || config.name); | ||
getField(nameOrIndex) { | ||
if (nameOrIndex instanceof Number) { | ||
assert(nameOrIndex > 0 && nameOrIndex < | ||
this._fields.length, | ||
'Field index(' + nameOrIndex + ') out of bounds'); | ||
return this._fields[nameOrIndex]; | ||
} | ||
const i = this.indexOfField(nameOrIndex); | ||
assert(i >= 0, `Model (${this.model.name}) has no field (${nameOrIndex})`); | ||
return this._fields[i]; | ||
} | ||
getFieldNames() { | ||
return Object.getOwnPropertyNames(this.fields); | ||
const a = []; | ||
for (const f of this._fields) | ||
a.push(f.fieldName); | ||
return a; | ||
} | ||
indexOfField(name) { | ||
const self = this; | ||
for (let i = 0; i < self._fields.length; i++) { | ||
if (self._fields[i].fieldName.toLowerCase() === name.toLowerCase()) | ||
return i; | ||
} | ||
return -1; | ||
} | ||
setField(name, opts) { | ||
let field; | ||
if (name instanceof Field) { | ||
field = name; | ||
name = field.fieldName; | ||
} | ||
if (!field) { | ||
assert(name, 'Invalid argument. "name" property required'); | ||
assert(opts, 'Invalid argument. "opts" property required'); | ||
const T = Field.get(opts.type); | ||
assert.ok(T, `Unknown field type definition "${opts.type}" in field ${name}`); | ||
field = Reflect.construct(T, [opts]); | ||
} | ||
const i = this.indexOfField(name); | ||
if (i >= 0) | ||
this._fields[i] = field; | ||
else this._fields.push(field); | ||
} | ||
setFields(source) { | ||
@@ -227,3 +272,3 @@ if (source) { | ||
v.fieldType = Field.DataType.DATA; | ||
self.fields[key] = v; | ||
self.setField(key, v); | ||
}); | ||
@@ -251,7 +296,5 @@ } | ||
} | ||
for (const item of args) { | ||
const f = self.fields[item]; | ||
if (!f) | ||
throw new Error(`Default fields definition error. Field "${item}" not found`); | ||
} | ||
// Test fields | ||
for (const item of args) | ||
self.getField(item); | ||
this._defaultFields = args; | ||
@@ -265,8 +308,7 @@ return this; | ||
/* Clear previous flags */ | ||
Object.getOwnPropertyNames(self.fields).forEach(name => { | ||
self.fields[name].setPrimaryKey(false); | ||
self._fields.forEach(f => { | ||
f.setPrimaryKey(false); | ||
}); | ||
for (const f of fields) { | ||
const field = self.fields[f]; | ||
assert(field, `Can not set primary keys for ${self.name}. Field "${field}" not found`); | ||
const field = self.getField(f); | ||
field.setPrimaryKey(true); | ||
@@ -281,8 +323,6 @@ } | ||
const out = []; | ||
Object.getOwnPropertyNames(self.fields).forEach(key => { | ||
const f = self.fields[key]; | ||
if (f.primaryKey) | ||
out.push(f); | ||
} | ||
); | ||
self._fields.forEach(f => { | ||
if (f.primaryKey) | ||
out.push(f); | ||
}); | ||
return out; | ||
@@ -289,0 +329,0 @@ } |
@@ -98,2 +98,10 @@ /* UNIQORM | ||
execute(...args) { | ||
return this._prepare().execute(...args); | ||
} | ||
then(...args) { | ||
return this._prepare().then(...args); | ||
} | ||
/** | ||
@@ -203,8 +211,4 @@ * @private | ||
then(...args) { | ||
return this._prepare().then(...args); | ||
} | ||
} | ||
module.exports = SelectQuery; |
@@ -177,6 +177,7 @@ /* UNIQORM | ||
} | ||
callback(); | ||
} catch (e) { | ||
callback(e); | ||
return; | ||
} | ||
callback(); | ||
}); | ||
@@ -183,0 +184,0 @@ } |
{ | ||
"name": "uniqorm", | ||
"description": "Easy to use, multi-dialect ORM framework for JavaScript", | ||
"version": "0.0.9", | ||
"version": "0.1.0", | ||
"author": "Panates Ltd.", | ||
@@ -23,3 +23,3 @@ "contributors": [ | ||
"dependencies": { | ||
"chalk": "^1.1.3", | ||
"chalk": "^2.0.1", | ||
"commander": "^2.11.0", | ||
@@ -31,4 +31,4 @@ "putil-promisify": "^1.0.4", | ||
"babel-eslint": "^7.2.3", | ||
"eslint": "^4.1.1", | ||
"eslint-config-google": "^0.8.0", | ||
"eslint": "^4.2.0", | ||
"eslint-config-google": "^0.9.1", | ||
"istanbul": "^0.4.5", | ||
@@ -38,3 +38,3 @@ "mocha": "^3.4.2" | ||
"peerDependencies": { | ||
"sqb": "^0.4.14" | ||
"sqb": "^0.6.5" | ||
}, | ||
@@ -41,0 +41,0 @@ "engines": { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
54559
1891
+ Addedansi-styles@3.2.1(transitive)
+ Addedchalk@2.4.2(transitive)
+ Addedcolor-convert@1.9.3(transitive)
+ Addedcolor-name@1.1.3(transitive)
+ Addedhas-flag@3.0.0(transitive)
+ Addedsupports-color@5.5.0(transitive)
- Removedansi-regex@2.1.1(transitive)
- Removedansi-styles@2.2.1(transitive)
- Removedchalk@1.1.3(transitive)
- Removeddebug@2.6.9(transitive)
- Removeddoublylinked@1.0.7(transitive)
- Removedhas-ansi@2.0.0(transitive)
- Removedms@2.0.0(transitive)
- Removedputil-flattentext@1.1.2(transitive)
- Removedputil-taskqueue@1.3.1(transitive)
- Removedsqb@0.4.18(transitive)
- Removedstrip-ansi@3.0.1(transitive)
- Removedsupports-color@2.0.0(transitive)
Updatedchalk@^2.0.1