Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

leoric

Package Overview
Dependencies
Maintainers
1
Versions
141
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

leoric - npm Package Compare versions

Comparing version 1.9.0 to 1.10.0

src/drivers/sqlite/connection.js

9

History.md

@@ -0,1 +1,8 @@

1.10.0 / 2021-09-14
==================
* feat: SQLite driver should emit "connection" event when new connection is created (#168)
* fix: bulkCreate(...records) should recognize custom setters (#168)
* fix: attribute.equals() check should ignore defaultValue (#172)
1.9.0 / 2021-09-04

@@ -77,3 +84,3 @@ ==================

* feat: support class static attributes and hooks (#131)
* fix: names defined in Bone.attributes should be always enumerable (#128)
* fix: names defined in Bone.attributes should always be enumerable (#128)
* chore: add quality badge to readme (#129)

@@ -80,0 +87,0 @@

4

index.js

@@ -59,3 +59,3 @@ 'use strict';

const { columnName, dataType, defaultValue, ...restInfo } = columnInfo;
const name = columnName == '_id' ? columnName : camelCase(columnName);
const name = columnName === '_id' ? columnName : camelCase(columnName);
// leave out defaultValue to let database take over the default

@@ -189,3 +189,3 @@ attributes[name] = {

if (!replacements.hasOwnProperty(key)) {
throw new Error(`unable to replace :${key}`);
throw new Error(`unable to replace: ${key}`);
}

@@ -192,0 +192,0 @@ values.push(replacements[key]);

{
"name": "leoric",
"version": "1.9.0",
"version": "1.10.0",
"description": "JavaScript Object-relational mapping alchemy",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -946,3 +946,3 @@ 'use strict';

attributeMap,
associations: [],
associations: {},
tableAlias,

@@ -1317,2 +1317,5 @@ synchronized: Object.keys(compare(attributes, columns)).length === 0,

// records might change when filter through custom setters
records = instances.map(instance => instance.getRaw());
// bulk create with instances is possible only if

@@ -1324,6 +1327,3 @@ // 1) either all of records primary key are set

if (options.validate !== false) {
records.map(record => {
if (record instanceof Bone) record._validateAttributes();
else this._validateAttributes(record);
});
for (const record of records) this._validateAttributes(record);
}

@@ -1499,3 +1499,3 @@ return await new Spell(this, options).$bulkInsert(records);

if (Object.keys(columns).length === 0) {
if (columns.length === 0) {
await driver.createTable(table, attributes);

@@ -1502,0 +1502,0 @@ } else {

@@ -67,4 +67,4 @@ 'use strict';

const { type } = token;
if (type == 'func') return false;
if (type == 'alias' && token.args[0].type == 'func') return false;
if (type === 'func') return false;
if (type === 'alias' && token.args[0].type === 'func') return false;
}

@@ -89,3 +89,3 @@ if (groups.length > 0) return false;

if (Object.keys(spell.joins).length == 0) {
if (Object.keys(spell.joins).length === 0) {
return Collection.from(rows, row => Model.instantiate(Object.values(row)[0]));

@@ -123,3 +123,3 @@ }

if (!current[qualifier]) current[qualifier] = new Collection();
if (!id || current[qualifier].some(item => item[Model.primaryKey] == id)) continue;
if (!id || current[qualifier].some(item => item[Model.primaryKey] === id)) continue;
current[qualifier].push(Model.instantiate(values));

@@ -162,5 +162,5 @@ } else {

// mysql2 sometimes nests rows with table name instead of table alias
const qualifier = prop == table ? tableAlias : prop;
const qualifier = prop === table ? tableAlias : prop;
const obj = result[qualifier] || (result[qualifier] = {});
if (qualifier == '') {
if (qualifier === '') {
Object.assign(obj, data);

@@ -167,0 +167,0 @@ }

@@ -109,3 +109,3 @@ 'use strict';

if (!targetAttribute) return false;
const props = [ 'dataType', 'allowNull', 'defaultValue', 'primaryKey' ];
const props = [ 'dataType', 'allowNull', 'primaryKey' ];
for (const prop of props) {

@@ -112,0 +112,0 @@ // SQLite has default value as string even if data type is integer

'use strict';
const EventEmitter = require('events');
const strftime = require('strftime');

@@ -12,126 +11,3 @@

const spellbook = require('./spellbook');
// SELECT users.id AS "users:id", ...
// => [ { users: { id, ... } } ]
function nest(rows, fields, spell) {
const { Model } = spell;
const { tableAlias } = Model;
const results = [];
for (const row of rows) {
const result = {};
const qualified = Object.keys(row).some(entry => entry.includes(':'));
for (const key in row) {
const parts = key.split(':');
const [qualifier, column] = qualified
? (parts.length > 1 ? parts : ['', key])
: [Model.attributeMap.hasOwnProperty(key) ? tableAlias : '', key];
const obj = result[qualifier] || (result[qualifier] = {});
obj[column] = row[key];
}
results.push(result);
}
return { rows: results, fields };
}
class Connection {
constructor({ client, database, mode, pool }) {
const { Database, OPEN_READWRITE, OPEN_CREATE } = client;
if (mode == null) mode = OPEN_READWRITE | OPEN_CREATE;
this.database = new Database(database, mode);
this.pool = pool;
}
async query(query, values, spell) {
const { sql, nestTables } = query.sql ? query : { sql: query };
if (/^(?:pragma|select)/i.test(sql)) {
const result = await this.all(sql, values);
if (nestTables) return nest(result.rows, result.fields, spell);
return result;
}
return await this.run(sql, values);
}
all(sql, values) {
return new Promise((resolve, reject) => {
this.database.all(sql, values, (err, rows, fields) => {
if (err) reject(err);
else resolve({ rows, fields });
});
});
}
run(sql, values) {
return new Promise((resolve, reject) => {
this.database.run(sql, values, function Leoric_sqliteRun(err) {
if (err) reject(err);
else resolve({ insertId: this.lastID, affectedRows: this.changes });
});
});
}
release() {
this.pool.releaseConnection(this);
}
async end() {
const { connections } = this.pool;
const index = connections.indexOf(this);
if (index >= 0) connections.splice(index, 1);
return await new Promise((resolve, reject) => {
this.database.close(function(err) {
if (err) reject(err);
resolve();
});
});
}
}
class Pool extends EventEmitter {
constructor(opts) {
super(opts);
this.options = {
connectionLimit: 10,
...opts,
client: opts.client || 'sqlite3',
};
this.client = require(this.options.client);
this.connections = [];
this.queue = [];
}
async getConnection() {
const { connections, queue, client, options } = this;
for (const connection of connections) {
if (connection.idle) {
connection.idle = false;
this.emit('acquire', connection);
return connection;
}
}
if (connections.length < options.connectionLimit) {
const connection = new Connection({ ...options, client, pool: this });
connections.push(connection);
this.emit('acquire', connection);
return connection;
}
await new Promise(resolve => queue.push(resolve));
return await this.getConnection();
}
releaseConnection(connection) {
connection.idle = true;
this.emit('release', connection);
const { queue } = this;
while (queue.length > 0) {
const task = queue.shift();
task();
}
}
}
const Pool = require('./pool');
class SqliteDriver extends AbstractDriver {

@@ -138,0 +14,0 @@ constructor(opts = {}) {

@@ -58,7 +58,3 @@ 'use strict';

const OPERATORS = new Set(
['between', 'not between', ...UNARY_OPERATORS, ...BINARY_OPERATORS].sort((a, b) => {
if (a.length > b.length) return -1;
else if (a.length < b.length) return 1;
else return 0;
})
['between', 'not between', ...UNARY_OPERATORS, ...BINARY_OPERATORS].sort((a, b) => b.length - a.length)
);

@@ -157,3 +153,3 @@

next();
while (chr && chr != quote) {
while (chr && chr !== quote) {
value += chr;

@@ -176,3 +172,3 @@ next();

space();
} while (chr == ',');
} while (chr === ',');
next();

@@ -198,6 +194,6 @@ return { type: 'func', name, args };

next();
while (chr && chr != ')') {
while (chr && chr !== ')') {
space();
const item = token();
if (item.type == 'literal') {
if (item.type === 'literal') {
items.push(item.value);

@@ -221,4 +217,4 @@ } else {

if (/['"]/.test(chr)) return string();
if (chr == '?') return placeholder();
if (chr == '(') return array();
if (chr === '?') return placeholder();
if (chr === '(') return array();

@@ -228,3 +224,3 @@ for (const name of OPERATORS) {

const chunk = str.slice(i, j);
if (chunk.toLowerCase() == name && (str[j] == ' ' || !/[a-z]$/.test(name))) {
if (chunk.toLowerCase() === name && (str[j] === ' ' || !/[a-z]$/.test(name))) {
i += name.length;

@@ -249,3 +245,3 @@ chr = str[i];

}
else if (chr == '(') {
else if (chr === '(') {
return func(lowerCase);

@@ -269,3 +265,3 @@ }

const conj = token();
if (conj.name != 'and') throw new Error(`Unexpected conj ${conj}`);
if (conj.name !== 'and') throw new Error(`Unexpected conj ${conj}`);
space();

@@ -282,4 +278,4 @@ const end = token();

function unary(op) {
const arg = chr == '(' ? expr() : token();
if (op.name == '-' && arg.type == 'literal' && Number.isFinite(arg.value)) {
const arg = chr === '(' ? expr() : token();
if (op.name === '-' && arg.type === 'literal' && Number.isFinite(arg.value)) {
return { type: 'literal', value: -arg.value };

@@ -293,4 +289,4 @@ } else {

const op = token();
if (op.name == 'as') return alias(t);
if (op.name == 'between' || op.name == 'not between') {
if (op.name === 'as') return alias(t);
if (['between', 'not between'].includes(op.name)) {
return between(op, t);

@@ -300,3 +296,3 @@ }

space();
const isLower = chr == '(';
const isLower = chr === '(';
const operand = LOGICAL_OPERATORS.includes(op.name) ? expr() : token();

@@ -307,7 +303,7 @@ // parseExpr('1 > -1')

}
else if (operand.type == 'op' && operand.args.length < 2) {
else if (operand.type === 'op' && operand.args.length < 2) {
throw new Error(`Unexpected token ${operand.name}`);
}
// parseExpr('a = 1 && b = 2 && c = 3')
else if (operand.type == 'op' && !isLower && precedes(op.name, operand.name) <= 0) {
else if (operand.type === 'op' && !isLower && precedes(op.name, operand.name) <= 0) {
const { args } = operand;

@@ -318,3 +314,3 @@ operand.args = [{ ...op, args: [t, args[0]] }, args[1]];

// parseExpr('a + b * c')
else if (operand.type !== 'op' && t.type == 'op' && precedes(op.name, t.name) < 0) {
else if (operand.type !== 'op' && t.type === 'op' && precedes(op.name, t.name) < 0) {
t.args[1] = { ...op, args: [t.args[1], operand] };

@@ -334,7 +330,7 @@ return t;

let node;
while (chr && chr != ',' && chr != ')') {
while (chr && chr !== ',' && chr !== ')') {
space();
if (node) {
// check arguments length to differentiate unary minus and binary minus
if (UNARY_OPERATORS.includes(node.name) && node.args.length == 0) {
if (UNARY_OPERATORS.includes(node.name) && node.args.length === 0) {
node = unary(node);

@@ -349,3 +345,3 @@ }

}
else if (chr == '(') {
else if (chr === '(') {
next();

@@ -355,3 +351,3 @@ node = expr();

}
else if (chr == '*') {
else if (chr === '*') {
node = wildcard();

@@ -370,3 +366,3 @@ }

results.push(expr());
if (chr == ',') next();
if (chr === ',') next();
}

@@ -373,0 +369,0 @@ return results;

@@ -84,5 +84,9 @@ 'use strict';

function isOperatorCondition(condition) {
return isPlainObject(condition) &&
Object.keys(condition).length > 0 &&
Object.keys(condition).every($op => OPERATOR_MAP.hasOwnProperty($op));
if (!isPlainObject(condition)) return false;
const keys = Object.keys(condition);
return (
keys.length > 0 &&
keys.every($op => OPERATOR_MAP.hasOwnProperty($op))
);
}

@@ -256,3 +260,3 @@

const { joins, Model } = spell;
if (typeof names[0] == 'function') {
if (typeof names[0] === 'function') {
names = Object.keys(Model.attributes).filter(names[0]);

@@ -436,3 +440,3 @@ } else {

walkExpr(token, node => {
if (node.type == 'id' && !node.qualifiers && RefModel.attributes[node.value]) {
if (node.type === 'id' && !node.qualifiers && RefModel.attributes[node.value]) {
node.qualifiers = [refName];

@@ -469,3 +473,3 @@ }

walkExpr(condition, ({ type, value }) => {
if (type == 'id' && value == deletedAt) {
if (type === 'id' && value == deletedAt) {
found = true;

@@ -533,3 +537,3 @@ }

this.scopes = scopes;
this.scopes = scopes;

@@ -846,3 +850,3 @@ /**

const token = parseExpr(name);
if (token.type == 'alias') {
if (token.type === 'alias') {
groups.push({ type: 'id', value: token.value });

@@ -852,3 +856,3 @@ } else {

}
if (!columns.some(entry => entry.value == token.value)) {
if (!columns.some(entry => entry.value === token.value)) {
columns.push(token);

@@ -1000,3 +1004,3 @@ }

$join(Model, onConditions, ...values) {
if (typeof Model == 'string') {
if (typeof Model === 'string') {
return this.$with(...arguments);

@@ -1003,0 +1007,0 @@ }

@@ -72,3 +72,3 @@ 'use strict';

const value = setValue != null? setValue : defaultValue;
const value = setValue != null ? setValue : defaultValue;
if (typeof validateArgs === 'function') {

@@ -106,4 +106,4 @@ let needToRevert = false;

if (['true', 'false'].indexOf(String(validateArgs)) >= 0) {
if (validator.call(ctx, value == null? value : String(value)) !== args) {
throw new LeoricValidateError(name, field, msg, !validateArgs? validateArgs : undefined);
if (validator.call(ctx, value == null ? value : String(value)) !== args) {
throw new LeoricValidateError(name, field, msg, !validateArgs ? validateArgs : undefined);
}

@@ -110,0 +110,0 @@ return;

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc