0
1
Fork 0
This commit is contained in:
Juan Ferrer Toribio 2017-11-13 17:36:30 +01:00
parent 1cec1b4cd6
commit f9c002f08a
23 changed files with 638 additions and 325 deletions

View File

@ -104,7 +104,7 @@ Hedera.Catalog = new Class
Db.Model.SortWay.ASC : Db.Model.SortWay.DESC; Db.Model.SortWay.ASC : Db.Model.SortWay.DESC;
if (sortField) if (sortField)
this.$.items.sortByName (sortField, sortWay); this.$.items.sort (sortField, sortWay);
this.hideMenu (); this.hideMenu ();
} }
@ -113,13 +113,7 @@ Hedera.Catalog = new Class
{ {
var params = this.params.$; var params = this.params.$;
var shouldRefresh = params.search || var shouldRefresh = params.search ||
params.realm && ( params.realm && params.type;
params.type ||
params.color ||
params.origin ||
params.category ||
params.producer
);
if (shouldRefresh) if (shouldRefresh)
{ {
@ -130,20 +124,154 @@ Hedera.Catalog = new Class
this.$.items.refresh (modelParams); this.$.items.refresh (modelParams);
this.hideMenu (); this.hideMenu ();
this.$.order.style.display = 'block';
} }
else else
{
this.$.items.clean (); this.$.items.clean ();
this.$.order.style.display = 'none';
this.showFilters (params.search || params.realm);
} }
,showFilters: function (show)
{
this.$.filters.style.display = show ? 'block' : 'none';
this.$.realmMsg.style.display = show ? 'none' : 'block';
this.$.order.style.display = show ? 'block' : 'none';
}
,onRemoveFiltersClick: function ()
{
this.params.$ = {};
}
,tagFilter: {}
,onTagFilterAdd: function ()
{
tagFilter[tag.id] = tag.value;
}
,buildTagFilter: function (excludeTag)
{
var Type = Sql.Operation.Type;
var join = new Sql.Join ({
target: Sql.Table ({
schema: 'vn',
name: 'item',
alias: 'i'
})
});
join.push (new Sql.JoinItem ({
target: new Sql.Table ({
schema: 'vn',
name: 'family',
alias: 'f'
}),
condition: new Sql.Operation ({
type: Type.EQUAL,
exprs: [
new Sql.Field ({
target: 'f',
name: 'id'
}),
new Sql.Field ({
target: 'i',
name: 'familyFk'
})
]
})
}));
var i = -1;
for (var tagId in this.tagFilter)
{
var tagValue = this.tagFilter[tagId];
if (tagId == excludeTag)
continue;
i++;
var tAlias = 'it'+ i;
var joinItem = new Sql.JoinItem ({
target: new Sql.Table ({
schema: 'vn',
name: 'itemTag',
alias: tAlias
}),
condition: new Sql.Operation ({
type: Type.AND
})
});
join.push (joinItem);
joinItem.condition.exprs = [
new Sql.Operation ({
type: Type.EQUAL,
exprs: [
new Sql.Field ({
target: tAlias,
name: 'itemFk'
}),
new Sql.Field ({
target: 'i',
name: 'id'
})
]
}),
new Sql.Operation ({
type: Type.EQUAL,
exprs: [
new Sql.Field ({
target: tAlias,
name: 'tagFk'
}),
new Sql.Value ({
value: tagId
})
]
}),
new Sql.Operation ({
type: Type.EQUAL,
exprs: [
new Sql.Field ({
target: tAlias,
name: 'value'
}),
new Sql.Value ({
value: tagValue
})
]
})
];
}
}
,onTagsReady: function (resultSet)
{
var tags = resultSet.fetchArray ();
tags.forEach (function (tag) {
var model = new Db.Model ({
autoLoad: false,
query: query
});
var combo = new Vn.Combo ({
name: tag.name,
lot: lot,
placeholder: tag.description,
model: model
});
div.appendChild (combo);
});
} }
,onRealmChange: function () ,onRealmChange: function ()
{ {
var newValue = this.params.$.realm;
this.$.filters.style.display = newValue ? 'block' : 'none';
this.$.realmMsg.style.display = newValue ? 'none' : 'block';
this.refreshTitleColor (); this.refreshTitleColor ();
} }

View File

@ -1,43 +1,39 @@
<vn> <vn>
<vn-group> <vn-group>
<vn-lot-query id="params" on-change="onParamsChange"> <vn-lot-query id="params" on-change="onParamsChange">
<vn-spec name="search" type="String"/>
<vn-spec name="itemId" type="Number"/>
<vn-spec name="realm" type="Number"/> <vn-spec name="realm" type="Number"/>
<vn-spec name="type" type="Number"/> <vn-spec name="type" type="Number"/>
<vn-spec name="search" type="String"/>
<vn-spec name="color" type="String"/>
<vn-spec name="origin" type="Number"/>
<vn-spec name="category" type="String"/>
<vn-spec name="producer" type="Number"/>
<vn-spec name="itemId" type="Number"/>
</vn-lot-query> </vn-lot-query>
<sql-filter type="AND" id="filter"> <sql-filter type="AND" id="filter">
<sql-filter-item type="EQUAL" <sql-filter-item type="EQUAL"
target="a" field="tipo_id" target="i" field="familyFk"
param="type"/> param="type"/>
<sql-filter type="OR"> <sql-filter type="OR">
<sql-filter-item type="LIKE" <sql-filter-item type="LIKE"
target="a" field="Article" target="i" field="name"
param="search"/> param="search"/>
<sql-filter-item type="EQUAL" <sql-filter-item type="EQUAL"
target="a" field="Id_Article" target="i" field="id"
param="search"/> param="search"/>
<sql-filter-item type="EQUAL" <sql-filter-item type="EQUAL"
target="a" field="Id_Article" target="i" field="id"
param="itemId"/> param="itemId"/>
</sql-filter> </sql-filter>
<sql-filter-item type="EQUAL"
target="a" field="Color"
param="color"/>
<sql-filter-item type="EQUAL"
target="a" field="id_origen"
param="origin"/>
<sql-filter-item type="EQUAL"
target="a" field="Categoria"
param="category"/>
<sql-filter-item type="EQUAL"
target="a" field="producer_id"
param="producer"/>
</sql-filter> </sql-filter>
<vn-string id="pre-query">
DROP TEMPORARY TABLE IF EXISTS tItems;
CREATE TEMPORARY TABLE tItems
(INDEX (id))
ENGINE = MEMORY
SELECT i.id
FROM #joins
WHERE #filter;
</vn-string>
<vn-string id="post-query">
DROP TEMPORARY TABLE tItems;
</vn-string>
<db-model <db-model
id="items" id="items"
result-index="2" result-index="2"
@ -45,9 +41,9 @@
CREATE TEMPORARY TABLE tmp.bionic_calc CREATE TEMPORARY TABLE tmp.bionic_calc
(INDEX (item_id)) (INDEX (item_id))
ENGINE = MEMORY ENGINE = MEMORY
SELECT a.Id_Article item_id SELECT i.id item_id
FROM vn2008.Articles a FROM vn.item i
JOIN vn2008.Tipos t ON t.tipo_id = a.tipo_id JOIN vn.family f ON f.id = i.familyFk
WHERE #filter; WHERE #filter;
CALL bionic_calc (); CALL bionic_calc ();
SELECT a.Id_Article item_id, a.description, b.available, b.price, SELECT a.Id_Article item_id, a.description, b.available, b.price,
@ -75,6 +71,15 @@
FROM basket_item FROM basket_item
GROUP BY warehouse_id GROUP BY warehouse_id
</db-query> </db-query>
<db-query id="tags" on-ready="onTagsReady">
SELECT it.tagFk, SUM(it.priority) priority
FROM vn.itemTag it
JOIN vn.item i ON i.id = it.itemFk
WHERE #filter
GROUP BY tagFk
ORDER BY priority DESC
LIMIT 6
</db-query>
<db-form id="card-extend"> <db-form id="card-extend">
<db-model <db-model
property="model" property="model"
@ -215,10 +220,10 @@
</div> </div>
<div id="filters" class="filters"> <div id="filters" class="filters">
<h2>_Filter by</h2> <h2>_Filter by</h2>
<vn-filter <label>_Family</label>
<htk-combo
name="type" name="type"
lot="params" lot="params">
placeholder="_Family">
<db-model <db-model
id="types" id="types"
property="model" property="model"
@ -234,73 +239,10 @@
WHERE t.reino_id = #realm WHERE t.reino_id = #realm
ORDER BY name ORDER BY name
</db-model> </db-model>
</vn-filter> </htk-combo>
<vn-filter <button on-click="onRemoveFiltersClick">
id="test" _Remove filters
name="color" </button>
lot="params"
placeholder="_Color"
filter="filter">
<db-model property="model" auto-load="false" result-index="1">
CALL item_available ();
SELECT DISTINCT c.Id_Tinta, l.str name
FROM vn2008.Tintas c
JOIN vn2008.Articles a ON a.Color = c.Id_Tinta
JOIN vn2008.Tipos t ON t.tipo_id = a.tipo_id
LEFT JOIN vn_locale.color_view l ON l.color_id = c.Id_Tinta
JOIN tmp.item_available i ON i.item_id = a.Id_Article
WHERE #filter
ORDER BY name
</db-model>
</vn-filter>
<vn-filter
name="producer"
lot="params"
placeholder="_Producer"
filter="filter">
<db-model property="model" auto-load="false" result-index="1">
CALL item_available ();
SELECT DISTINCT p.producer_id, p.name
FROM vn2008.producer p
JOIN vn2008.Articles a ON a.producer_id = p.producer_id
JOIN vn2008.Tipos t ON t.tipo_id = a.tipo_id
JOIN tmp.item_available i ON i.item_id = a.Id_Article
WHERE #filter
ORDER BY name
</db-model>
</vn-filter>
<vn-filter
name="origin"
lot="params"
placeholder="_Origin"
filter="filter">
<db-model property="model" auto-load="false" result-index="1">
CALL item_available ();
SELECT DISTINCT o.id, l.str name, o.Abreviatura
FROM vn2008.Origen o
JOIN vn2008.Articles a ON a.id_origen = o.id
JOIN vn2008.Tipos t ON t.tipo_id = a.tipo_id
LEFT JOIN vn_locale.origin_view l ON l.origin_id = o.id
JOIN tmp.item_available i ON i.item_id = a.Id_Article
WHERE #filter
ORDER BY name
</db-model>
</vn-filter>
<vn-filter
name="category"
lot="params"
placeholder="_Category"
filter="filter">
<db-model property="model" auto-load="false" result-index="1">
CALL item_available ();
SELECT DISTINCT a.Categoria, a.Categoria category
FROM vn2008.Articles a
JOIN vn2008.Tipos t ON t.tipo_id = a.tipo_id
JOIN tmp.item_available i ON i.item_id = a.Id_Article
WHERE #filter
ORDER BY a.Categoria
</db-model>
</vn-filter>
</div> </div>
<div id="order" class="order"> <div id="order" class="order">
<h2>_Order by</h2> <h2>_Order by</h2>

View File

@ -743,7 +743,7 @@ Klass.implement
var stmts = new Sql.MultiStmt (); var stmts = new Sql.MultiStmt ();
var query = new Sql.String ({query: 'START TRANSACTION'}); var query = new Sql.String ({query: 'START TRANSACTION'});
stmts.addStmt (query); stmts.push (query);
for (var i = 0; i < ops.length; i++) for (var i = 0; i < ops.length; i++)
{ {
@ -759,7 +759,10 @@ Klass.implement
if (where) if (where)
{ {
query = new Sql.Delete ({where: where}); query = new Sql.Delete ({
where: where,
limit: 1
});
query.addTarget (this._createTarget (this._mainTable)); query.addTarget (this._createTarget (this._mainTable));
} }
} }
@ -770,13 +773,13 @@ Klass.implement
for (var tableIndex in op.tables) for (var tableIndex in op.tables)
{ {
var stmt = this._createDmlQuery (op, parseInt (tableIndex)); var stmt = this._createDmlQuery (op, parseInt (tableIndex));
query.addStmt (stmt); query.push (stmt);
} }
} }
if (query) if (query)
{ {
stmts.addStmt (query); stmts.push (query);
} }
else else
{ {
@ -786,7 +789,7 @@ Klass.implement
} }
var query = new Sql.String ({query: 'COMMIT'}); var query = new Sql.String ({query: 'COMMIT'});
stmts.addStmt (query); stmts.push (query);
this._conn.execStmt (stmts, this._conn.execStmt (stmts,
this._onOperationsDone.bind (this, ops)); this._onOperationsDone.bind (this, ops));
@ -804,7 +807,10 @@ Klass.implement
var multiStmt = new Sql.MultiStmt (); var multiStmt = new Sql.MultiStmt ();
var target = this._createTarget (tableIndex); var target = this._createTarget (tableIndex);
var select = new Sql.Select ({where: where}); var select = new Sql.Select ({
where: where,
limit: 1
});
select.addTarget (target); select.addTarget (target);
var row = op.row; var row = op.row;
@ -846,7 +852,10 @@ Klass.implement
if (!updateWhere) if (!updateWhere)
return null; return null;
var dmlQuery = new Sql.Update ({where: updateWhere}); var dmlQuery = new Sql.Update ({
where: updateWhere,
limit: 1
});
for (var i = 0; i < cols.length; i++) for (var i = 0; i < cols.length; i++)
if (cols[i].table === tableIndex && op.oldValues[cols[i].name] !== undefined) if (cols[i].table === tableIndex && op.oldValues[cols[i].name] !== undefined)
@ -859,8 +868,8 @@ Klass.implement
dmlQuery.addTarget (target); dmlQuery.addTarget (target);
multiStmt.addStmt (dmlQuery); multiStmt.push (dmlQuery);
multiStmt.addStmt (select); multiStmt.push (select);
return multiStmt; return multiStmt;
} }
@ -947,7 +956,8 @@ Klass.implement
,_createWhere: function (tableIndex, op, useOldValues) ,_createWhere: function (tableIndex, op, useOldValues)
{ {
var where = new Sql.Operation ({type: Sql.Operation.Type.AND}); var Type = Sql.Operation.Type;
var where = new Sql.Operation ({type: Type.AND});
var pks = this.tables[tableIndex].pks; var pks = this.tables[tableIndex].pks;
if (pks.length === 0) if (pks.length === 0)
@ -957,9 +967,9 @@ Klass.implement
{ {
var column = this.columns[pks[i]]; var column = this.columns[pks[i]];
var equalOp = new Sql.Operation ({type: Sql.Operation.Type.EQUAL}); var equalOp = new Sql.Operation ({type: Type.EQUAL});
equalOp.exprs.add (new Sql.Field ({name: column.orgname})); equalOp.push (new Sql.Field ({name: column.orgname}));
where.exprs.add (equalOp); where.push (equalOp);
var pkValue = null; var pkValue = null;
@ -970,9 +980,9 @@ Klass.implement
pkValue = op.row[column.name]; pkValue = op.row[column.name];
if (pkValue) if (pkValue)
equalOp.exprs.add (new Sql.Value ({value: pkValue})); equalOp.push (new Sql.Value ({value: pkValue}));
else if (column.flags & Connection.Flag.AI && !useOldValues) else if (column.flags & Connection.Flag.AI && !useOldValues)
equalOp.exprs.add (new Sql.Function ({name: 'LAST_INSERT_ID'})); equalOp.push (new Sql.Function ({name: 'LAST_INSERT_ID'}));
else else
return null; return null;
} }

View File

@ -64,7 +64,7 @@ module.exports = new Class
,set: function (x) ,set: function (x)
{ {
this.link ({_lot: x}, {'change': this.onChange}); this.link ({_lot: x}, {'change': this.onChange});
this._autoLoad (); this.onChange ();
} }
,get: function () ,get: function ()
{ {

View File

@ -7,17 +7,17 @@ var Stmt = require ('./stmt');
module.exports = new Class module.exports = new Class
({ ({
Extends: Stmt Extends: Stmt
,Tag: 'sql-delete'
,render: function (batch) ,render: function (params)
{ {
var sql = 'DELETE FROM ' + this.renderTarget (batch); var sql = 'DELETE FROM '
+ this.renderTarget (params);
if (this.where) if (this.where)
sql += ' WHERE ' + this.where.render (batch); sql += ' WHERE ' + this.where.render (params);
sql += ' LIMIT 1'; // Only for security.
sql += this.renderLimit(params);
return sql; return sql;
} }
}); });

View File

@ -32,7 +32,12 @@ module.exports = new Class
,render: function () ,render: function ()
{ {
var sql = (this.target) ? '`' + this.target + '`.' : ''; var sql = '';
return sql + '`' + this.name + '`';
if (this.target)
sql += this.renderIdentifier (this.target) +'.';
sql += this.renderIdentifier (this.name);
return sql;
} }
}); });

View File

@ -50,26 +50,24 @@ module.exports = new Class
,render: function (params) ,render: function (params)
{ {
var op = new Operation ({type: this.type}); var newOp = new Operation ({type: this.type});
var field = new Field ({ newOp.push (new Field ({
name: this.field, name: this.field,
target: this.target target: this.target
}); }));
op.appendChild (field);
var value = params[this.param]; var value = params[this.param];
if (this.type === Operation.Type.LIKE && typeof value == 'string') if (this.type === Operation.Type.LIKE && typeof value === 'string')
{ {
value = value.replace (/[\%\?]/g, this._escapeChar); value = value.replace (/[\%\?]/g, this._escapeChar);
value = value.replace (/^|\s+|$/g, '%'); value = value.replace (/^|\s+|$/g, '%');
} }
var sqlValue = new Value ({value: value}); newOp.push (new Value ({value: value}));
op.appendChild (sqlValue);
return op.render (params); return newOp.render (params);
} }
,_escapeChar: function (char) ,_escapeChar: function (char)

View File

@ -16,7 +16,7 @@ module.exports = new Class
*/ */
,isReady: function (params) ,isReady: function (params)
{ {
var exprs = this.exprs.objects; var exprs = this.exprs;
for (var i = exprs.length; i--;) for (var i = exprs.length; i--;)
if (exprs[i].isReady (params)) if (exprs[i].isReady (params))
return true; return true;
@ -31,16 +31,22 @@ module.exports = new Class
*/ */
,render: function (params) ,render: function (params)
{ {
var op = new Operation ({type: this.type}); var newOp;
var exprs = this.exprs.objects; var newExprs = [];
for (var i = 0; i < exprs.length; i++) this.exprs.forEach (function (expr) {
if (exprs[i].isReady (params)) if (expr.isReady (params))
op.exprs.add (exprs[i]); newExprs.push (exprs[i]);
})
if (op.exprs.objects.length == 0) if (newExprs.length > 0)
op = new Value ({value: true}); newOp = new Operation ({
type: this.type,
exprs: newExprs
});
else
newOp = new Value ({value: true});
return op.render (params); return newOp.render (params);
} }
}); });

View File

@ -1,38 +1,61 @@
var Expr = require ('./expr'); var Expr = require ('./expr');
var List = require ('./list'); var ListHolder = require ('./list-holder');
/** /**
* The equivalent of a SQL function. * The equivalent of a SQL function.
*
* @param {string} funcName The name of the function
* @param {Array#Sql.Expr} param Array with function parameters
*/ */
module.exports = new Class module.exports = new Class
({ ({
Extends: Expr Extends: Expr
,Tag: 'sql-function'
,Implements: ListHolder
,Properties: ,Properties:
{ {
/**
* The function name.
*/
name: name:
{ {
type: String type: String
,value: null ,value: null
}, },
/**
* The function schema.
*/
schema: schema:
{ {
type: String type: String
,value: null ,value: null
}, },
/**
* The function parameters.
*/
params: params:
{ {
type: List type: Array
,value: null ,set: function (x)
{
this.list = x;
}
,get: function ()
{
return this.list;
}
} }
} }
,render: function (batch) ,render: function (params)
{ {
var sql = (this.schema) ? '`' + this.schema + '`.' : ''; var sql = '';
return sql + '`' + this.name + '`()';
if (this.schema)
sql += this.renderIdentifier (this.schema) +'.';
sql += this.renderIdentifier (this.name)
+ '('
+ this.renderListWs (this.list, params, ', ')
+ ')';
return sql;
} }
}); });

View File

@ -8,31 +8,14 @@ module.exports = new Class
({ ({
Extends: Dml Extends: Dml
,render: function (batch) ,render: function (params)
{ {
var sql; return 'INSERT INTO '
var n; + this.renderTarget (params)
+ ' ('
sql = 'INSERT INTO ' + this.renderTarget (batch) + ' ('; + this.renderListWs (this.field, params, ', ')
+ ') VALUES ('
for (n = 0; n < this.field.length; n++) + this.renderListWs (this.expr, params, ', ')
{ + ')';
if (n > 0)
sql += ', ';
sql += this.field[n].render (batch);
}
sql += ') VALUES (';
for (n = 0; n < this.field.length; n++)
{
if (n > 0)
sql += ', ';
sql += this.expr[n].render(batch);
}
sql += ')';
return sql;
} }
}) })

49
js/sql/join-item.js Normal file
View File

@ -0,0 +1,49 @@
var Target = require ('./target');
var Expr = require ('./expr');
var SqlObject = require ('./object');
var Type = require ('./join').Type;
var TypeSql = require ('./join').TypeSql;
/**
* The equivalent of a SQL join.
*/
module.exports = new Class
({
Extends: SqlObject
,Tag: 'sql-join-table'
,Properties:
{
/**
* The join type.
*/
type:
{
enumType: Type
,value: 0
},
/**
* The right target.
*/
target:
{
type: Target
,value: null
},
/**
* The join on condition.
*/
condition:
{
type: Expr
,value: null
}
}
,render: function (params)
{
return TypeSql[this.type] +' JOIN '
+ this.target.render (params)
+ this.renderIfSet (this.condition, 'ON', params);
}
});

59
js/sql/join.js Normal file
View File

@ -0,0 +1,59 @@
var Target = require ('./target');
var ListHolder = require ('./list-holder');
/**
* The equivalent of a SQL join.
*/
var Klass = new Class ();
module.exports = Klass;
var Type = {
INNER : 0,
LEFT : 1,
RIGHT : 2
};
var TypeSql = [
'INNER',
'LEFT',
'RIGHT'
];
Klass.extend
({
Type: Type,
TypeSql: TypeSql
});
Klass.implement
({
Extends: Target
,Implements: ListHolder
,Tag: 'sql-join'
,Properties:
{
/**
* The right targets.
*/
targets:
{
type: Array
,set: function (x)
{
this.list = x;
}
,get: function ()
{
return this.list;
}
}
}
,render: function (params)
{
return '('+ this.target.render (params) +' '
+ this.renderList (this.list, params)
+ ')';
}
});

58
js/sql/list-holder.js Normal file
View File

@ -0,0 +1,58 @@
/**
* Interface for array holders.
*/
module.exports = new Class
({
Properties:
{
list:
{
type: Array
,set: function (x)
{
this._list = x;
}
,get: function ()
{
return this._list;
}
}
}
,_list: []
,appendChild: function (child)
{
this._list.push (child);
}
/**
* Adds an element to the list.
*
* @param {SqlObject} element The element to add
*/
,push: function (element)
{
this._list.push (element);
}
/**
* Removes an element from the list.
*
* @param {Number} i The element index
*/
,splice: function (i)
{
this._list.splice (i);
}
/**
* Adds an element to the list.
*
* @param {Number} i The element index
*/
,get: function (i)
{
return this._list[i];
}
});

View File

@ -1,5 +1,6 @@
var Stmt = require ('./stmt'); var Stmt = require ('./stmt');
var ListHolder = require ('./list-holder');
/** /**
* The equivalent of a SQL multi statement. * The equivalent of a SQL multi statement.
@ -7,42 +8,34 @@ var Stmt = require ('./stmt');
module.exports = new Class module.exports = new Class
({ ({
Extends: Stmt Extends: Stmt
,Implements: ListHolder
,stmts: [] ,Tag: 'sql-multi-stmt'
,Properties:
,addStmt: function (stmt)
{ {
return this.stmts.push (stmt); /**
* The statements list.
*/
stmts:
{
type: Array
,set: function (x)
{
this.list = x;
}
,get: function ()
{
return this.list;
}
}
} }
,getStmt: function (stmtIndex) ,render: function (params)
{
return this.stmts[index];
}
,isReady: function ()
{
if (this.stmts.length == 0)
return false;
for (var i = 0; i < this.stmts.length; i++)
if (!this.stmts[i].isReady ())
return false;
return true;
}
,render: function (batch)
{ {
var sql = ''; var sql = '';
for (var i = 0; i < this.stmts.length; i++) this._list.forEach (function (stmt) {
{ sql += stmt.render (params) +";\n";
if (i > 0) });
sql += ";\n";
sql += this.stmts[i].render (batch);
}
return sql; return sql;
} }

View File

@ -5,14 +5,6 @@ module.exports = new Class
({ ({
Extends: Vn.Object Extends: Vn.Object
/**
* Renders the object as an SQL string.
*
* @param {Object} params The params used to render the object
* @return {string} The SQL string
*/
,render: function () {}
/** /**
* Gets if the object is ready to be rendered. * Gets if the object is ready to be rendered.
* *
@ -30,4 +22,76 @@ module.exports = new Class
* @return {Array} An array with the names of the found parameters * @return {Array} An array with the names of the found parameters
*/ */
,findHolders: function () {} ,findHolders: function () {}
/**
* Renders the object as an SQL string.
*
* @param {Object} params The params used to render the object
* @return {string} The SQL string
*/
,render: function () {}
/**
* Renders an objects array.
*
* @param {Array} list The objects array
* @param {Object} params The parameters
* @return {string} The rendered SQL string
*/
,renderList: function (list, params)
{
var sql = '';
list.forEach (function (item) {
sql += item.render (params);
})
return sql;
}
/**
* Renders an objects array using a separator.
*
* @param {Array} list The objects array
* @param {Object} params The parameters
* @param {String} separator The separator between items
* @return {string} The rendered SQL string
*/
,renderListWs: function (list, params, separator)
{
var sql = '';
list.forEach (function (item, i) {
if (i > 0)
sql += separator;
sql += item.render (params);
})
return sql;
}
/**
* Renders a quoted SQL identifier.
*
* @param {String} identifier The identifier
* @return {string} The quoted identifier
*/
,renderIdentifier: function (identifier)
{
return '`'+ identifier +'`';
}
/**
* Renders the object if it's defined.
*
* @param {String} prefix The rendered string prefix
* @return {string} The rendered object with its prefix
*/
,renderIfSet: function (object, prefix, params)
{
if (object)
return ' '+ prefix +' '+ object.render (params);
else
return '';
}
}); });

View File

@ -1,11 +1,12 @@
var Expr = require ('./expr'); var Expr = require ('./expr');
var ListHolder = require ('./list-holder');
/** /**
* The equivalent of a SQL operation between exprs. * The equivalent of a SQL operation between exprs.
* *
* @param {Array#Sql.Expr} expr Array with the exprs * @param {Array#Expr} exprs Array with the exprs
* @param {Sql..Operation.Type} type The type of the operation * @param {Type} type The type of the operation
*/ */
var Klass = new Class (); var Klass = new Class ();
module.exports = Klass; module.exports = Klass;
@ -37,6 +38,7 @@ Klass.extend
Klass.implement Klass.implement
({ ({
Extends: Expr Extends: Expr
,Implements: ListHolder
,Tag: 'sql-operation' ,Tag: 'sql-operation'
,Properties: ,Properties:
{ {
@ -44,47 +46,26 @@ Klass.implement
{ {
enumType: Type enumType: Type
,value: -1 ,value: -1
},
exprs:
{
type: Array
,set: function (x)
{
this.list = x;
}
,get: function ()
{
return this.list;
}
} }
} }
,initialize: function (props) ,render: function (params)
{ {
this.parent (props);
this.link ({exprs: new Sql.List ()}, {'changed': this.onListChange});
}
,appendChild: function (child)
{
this.exprs.add (child);
}
,onListChange: function ()
{
this.emit ('changed');
}
,isReady: function ()
{
return this.exprs.isReady ();
}
,render: function (batch)
{
var sql = '(';
var operator = ' '+ Operators[this.type] +' '; var operator = ' '+ Operators[this.type] +' ';
var e = this.exprs.getArray (); return '('
+ this.renderListWs (this.list, params, operator)
for (var i = 0; i < e.length; i++) + ')';
{
if (i > 0)
sql += operator;
sql += e[i].render (batch);
}
sql += ')';
return sql;
} }
}); });

View File

@ -16,22 +16,17 @@ module.exports = new Class
this.expr.push (new Field ({name: fieldName})); this.expr.push (new Field ({name: fieldName}));
} }
,render: function (batch) ,render: function (params)
{ {
var sql = 'SELECT ' var sql = 'SELECT '
+ this.renderListWs (this.expr, params, ', ')
for (var i = 0; i < this.expr.length; i++) + ' FROM '
{ + this.renderTarget (params);
if (i > 0)
sql += ', ';
sql += this.expr[i].render(batch);
}
sql += ' FROM ' + this.renderTarget (batch);
if (this.where) if (this.where)
sql += ' WHERE ' + this.where.render (batch); sql += ' WHERE ' + this.where.render (params);
sql += this.renderLimit (params);
return sql; return sql;
} }
}); });

View File

@ -5,6 +5,7 @@ Sql = module.exports = {
Object : require ('./object') Object : require ('./object')
,Holder : require ('./holder') ,Holder : require ('./holder')
,List : require ('./list') ,List : require ('./list')
,ListHolder : require ('./list-holder')
,Expr : require ('./expr') ,Expr : require ('./expr')
,Value : require ('./value') ,Value : require ('./value')
,Field : require ('./field') ,Field : require ('./field')
@ -12,6 +13,8 @@ Sql = module.exports = {
,Operation : require ('./operation') ,Operation : require ('./operation')
,Target : require ('./target') ,Target : require ('./target')
,Table : require ('./table') ,Table : require ('./table')
,Join : require ('./join')
,JoinItem : require ('./join-item')
,Stmt : require ('./stmt') ,Stmt : require ('./stmt')
,Dml : require ('./dml') ,Dml : require ('./dml')
,String : require ('./string') ,String : require ('./string')

View File

@ -14,6 +14,11 @@ module.exports = new Class
{ {
type: Expr type: Expr
,value: null ,value: null
},
limit:
{
type: Number
,value: null
} }
} }
@ -24,24 +29,19 @@ module.exports = new Class
this.target.push (target); this.target.push (target);
} }
,renderTarget: function (batch) ,renderTarget: function (params)
{ {
var sql; if (this.target.length > 0)
var len = this.target.length; return this.renderListWs (this.target, params, ', ');
if (len > 0)
{
sql = ' ';
for (var n = 0; n < len; n++)
{
if (n > 0) sql += ', ';
sql += this.target[n].render (batch);
}
}
else else
sql += 'DUAL'; return 'DUAL';
}
return sql; ,renderLimit: function ()
{
if (this.limit != null)
return 'LIMIT '+ parseInt (this.limit);
else
return '';
} }
}); });

View File

@ -14,6 +14,11 @@ module.exports = new Class
type: String type: String
,value: null ,value: null
}, },
alias:
{
type: String
,value: null
},
schema: schema:
{ {
type: String type: String
@ -21,10 +26,18 @@ module.exports = new Class
} }
} }
,render: function (batch) ,render: function ()
{ {
var sql = this.schema ? '`' + this.schema + '`.' : ''; var sql = '';
sql += '`' + this.name + '`';
if (this.schema)
sql += this.renderIndentifier (this.schema) +'.';
sql += this.renderIndentifier (this.name);
if (this.alias)
sql += ' AS '+ this.renderIndentifier (this.alias);
return sql; return sql;
} }
}); });

View File

@ -8,25 +8,22 @@ module.exports = new Class
({ ({
Extends: Dml Extends: Dml
,render: function (batch) ,render: function (params)
{ {
var sql; var sql = 'UPDATE '
var n; + this.renderTarget (params)
+ ' SET ';
sql = 'UPDATE ' + this.renderTarget (batch) + ' SET '; this.field.forEach (function (field, i) {
if (i > 0)
for (n = 0; n < this.field.length; n++)
{
if (n > 0)
sql += ', '; sql += ', ';
sql += this.field[n].render () + ' = ' + this.expr[n].render(batch); sql += field.render (params)
} + ' = '
+ this.expr[i].render(params);
if (this.where) });
sql += ' WHERE ' + this.where.render (batch);
sql += ' LIMIT 1'; // Only for security.
sql += this.renderIfSet (this.where, 'WHERE', params)
+ this.renderLimit(params);
return sql; return sql;
} }
}); });

View File

@ -76,7 +76,18 @@ module.exports = new Class
{ {
params = this.transformParams (params); params = this.transformParams (params);
var diff = Value.partialDiff (this._params, params); var diff = Value.partialDiff (this._params, params);
this._assign (diff);
}
,setAll: function (params)
{
params = this.transformParams (params);
var diff = Value.diff (this._params, params);
this._assign (diff);
}
,_assign: function (diff)
{
if (diff) if (diff)
{ {
Object.assign (this._params, diff); Object.assign (this._params, diff);
@ -93,11 +104,6 @@ module.exports = new Class
} }
} }
,setAll: function (params)
{
this.assign (params);
}
,transformParams: function (params) ,transformParams: function (params)
{ {
var newParams = {}; var newParams = {};
@ -125,6 +131,8 @@ function cast (value, type)
var date = new Date (value); var date = new Date (value);
date.setHours (0, 0, 0, 0); date.setHours (0, 0, 0, 0);
return date; return date;
case String:
return value;
default: default:
if (type instanceof Object) if (type instanceof Object)
return JSON.parse (value); return JSON.parse (value);

View File

@ -50,22 +50,20 @@ module.exports = new Class
,assign: function (params) ,assign: function (params)
{ {
var diff = Value.partialDiff (this._params, params); var diff = Value.partialDiff (this._params, params);
this._assign (diff);
if (diff)
{
Object.assign (this._params, diff);
this._paramsChanged (diff);
this.changed (diff);
}
} }
,setAll: function (params) ,setAll: function (params)
{ {
var diff = Value.diff (this._params, params); var diff = Value.diff (this._params, params);
this._assign (diff);
}
,_assign: function (diff)
{
if (diff) if (diff)
{ {
this._params = Value.kvClone (params); Object.assign (this._params, diff);
this._paramsChanged (diff); this._paramsChanged (diff);
this.changed (diff); this.changed (diff);
} }