0
1
Fork 0

Db.Model soporta actualizaciones bajo demanda, edicion de consignatarios, errores solucionados

This commit is contained in:
Juan Ferrer Toribio 2015-03-19 20:36:11 +01:00
parent d64160d891
commit 0a738a55d7
28 changed files with 911 additions and 484 deletions

View File

@ -1,5 +1,5 @@
Package: hedera-web Package: hedera-web
Version: 1.0-42 Version: 1.0-43
Architecture: all Architecture: all
Maintainer: Juan Ferrer Toribio <juan@verdnatura.es> Maintainer: Juan Ferrer Toribio <juan@verdnatura.es>
Depends: apache2, php5-mysql, php-vn-web Depends: apache2, php5-mysql, php-vn-web

View File

@ -0,0 +1,36 @@
Vn.Address = new Class
({
Extends: Vn.Module
,activate: function ()
{
this.$('return').addEventListener ('click', this.onReturnClick.bind (this));
this.$('accept').addEventListener ('click', this.onAcceptClick.bind (this));
this.$('iter').on ('status-changed', this.onStatusChange, this);
this.$('model').on ('operations-done', this.onOperationsDone, this);
}
,onStatusChange: function (form)
{
if (this.$('address').value == 0)
form.insertRow ();
}
,onOperationsDone: function ()
{
(new Htk.Toast ()).showMessage (_('ConsigneeChangedSuccessfully'));
this.onReturnClick ();
}
,onAcceptClick: function ()
{
this.$('iter').performOperations ();
}
,onReturnClick: function ()
{
window.history.back();
}
});

View File

@ -0,0 +1,31 @@
.address
{
padding: 1em;
}
.address .box
{
max-width: 40em;
}
.address .box .body
{
margin: 0 auto;
max-width: 25em;
padding: 3em;
}
div.form-group
{
padding: 0.4em;
}
.address label
{
display: block;
margin-bottom: 0.5em;
}
.address input,
.address select
{
margin: 0;
width: 100%;
}

View File

@ -0,0 +1,61 @@
<vn>
<vn-group>
<vn-param id="address">
<vn-hash-link key="address"/>
</vn-param>
<db-form id="iter">
<db-model id="model">
SELECT id, name, consignee, city, zip_code, province_id
FROM address_view
WHERE active != FALSE AND id = #address
<sql-batch property="batch">
<item name="address" param="address"/>
</sql-batch>
</db-model>
</db-form>
</vn-group>
<div id="form" class="address">
<div class="box">
<div class="header">
<h1><t>EditConsignee</t></h1>
<div class="action-bar">
<button id="return">
<img src="image/dark/go-previous.svg" alt=""/>
<t>Return</t>
</button>
<button id="accept">
<img src="image/dark/ok.svg" alt=""/>
<t>Accept</t>
</button>
</div>
</div>
<div class="body">
<div class="form-group">
<label><t>Name:</t></label>
<htk-entry column="consignee" form="iter"/>
</div>
<div class="form-group">
<label><t>Adress:</t></label>
<htk-entry column="name" form="iter"/>
</div>
<div class="form-group">
<label><t>City:</t></label>
<htk-entry column="city" form="iter"/>
</div>
<div class="form-group">
<label><t>ZipCode:</t></label>
<htk-entry column="zip_code" form="iter"/>
</div>
<div class="form-group">
<label><t>Province:</t></label>
<htk-combo column="province_id" form="iter">
<db-model property="model">
SELECT province_id, name FROM vn2008.province
ORDER BY name
</db-model>
</htk-combo>
</div>
</div>
</div>
</div>
</vn>

View File

@ -1,5 +1,5 @@
Vn.Account = new Class Vn.Conf = new Class
({ ({
Extends: Vn.Module Extends: Vn.Module
@ -13,6 +13,15 @@ Vn.Account = new Class
this.$('new-password').addEventListener ('change', this.onPasswordChange.bind (this)); this.$('new-password').addEventListener ('change', this.onPasswordChange.bind (this));
this.$('repeat-password').addEventListener ('change', this.onPasswordChange.bind (this)); this.$('repeat-password').addEventListener ('change', this.onPasswordChange.bind (this));
this.$('user-name').addEventListener ('change', this.onUserChange.bind (this)); this.$('user-name').addEventListener ('change', this.onUserChange.bind (this));
this.$('add').addEventListener ('click', this.onAddClick.bind (this));
}
,onAddClick: function ()
{
this.hash.set ({
'form': 'account/address',
'address': 0
});
} }
,onUserDataReady: function (form) ,onUserDataReady: function (form)

View File

@ -0,0 +1,42 @@
.conf
{
padding: 1em;
}
.conf .box
{
max-width: 40em;
}
.conf .form
{
margin: 0 auto;
max-width: 25em;
padding: 2em;
}
.conf .form-group
{
padding: 0.4em;
}
.conf .form-group label
{
display: block;
margin-bottom: 0.5em;
}
.conf .form-group input[type=text],
.conf .form-group input[type=password]
{
margin: 0;
width: 100%;
}
.conf .form-group input[type=password]
{
margin-bottom: 0.5em;
}
.consignee
{
margin-bottom: 1em;
}
.consignee p
{
margin: 0.2em 0;
}

View File

@ -8,8 +8,14 @@
ON u.id = c.user_id ON u.id = c.user_id
</db-model> </db-model>
</db-form> </db-form>
<db-model id="consignees">
SELECT id, consignee, p.name province, zip_code, city, a.name
FROM address_view a
JOIN vn2008.province p ON a.province_id = p.province_id
WHERE active != FALSE
</db-model>
</vn-group> </vn-group>
<div id="form" class="account"> <div id="form" class="conf">
<div class="box"> <div class="box">
<div class="header"> <div class="header">
<h1><t>Configuration</t></h1> <h1><t>Configuration</t></h1>
@ -17,7 +23,7 @@
<div class="form"> <div class="form">
<div class="form-group"> <div class="form-group">
<label for="user-id"><t>UserNumber</t></label> <label for="user-id"><t>UserNumber</t></label>
<htk-label column="id" form="user-form"/> <htk-text column="id" form="user-form"/>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="user-name"><t>UserName</t></label> <label for="user-name"><t>UserName</t></label>
@ -38,5 +44,33 @@
</div> </div>
</div> </div>
</div> </div>
<div class="box">
<div class="header">
<h1><t>Consignees</t></h1>
<div class="action-bar">
<button id="add">
<img src="image/dark/add.svg" alt=""/>
<t>Add</t>
</button>
</div>
</div>
<div class="form">
<htk-repeater model="consignees" form-id="iter">
<div class="consignee">
<h2><htk-text form="iter" column="consignee"/></h2>
<p>
<htk-text form="iter" column="name"/>
</p>
<p>
<htk-text form="iter" column="zip_code"/> -
<htk-text form="iter" column="city"/>
</p>
<p>
<htk-text form="iter" column="province"/>
</p>
</div>
</htk-repeater>
</div>
</div>
</div> </div>
</vn> </vn>

View File

@ -1,34 +0,0 @@
.account
{
padding: 1em;
}
.account .box
{
max-width: 40em;
}
.account .form
{
margin: 0 auto;
max-width: 25em;
padding: 2em;
}
.account .form-group
{
padding: 0.4em;
}
.account .form-group label
{
display: block;
margin-bottom: 0.5em;
}
.account .form-group input[type=text],
.account .form-group input[type=password]
{
margin: 0;
width: 100%;
}
.account .form-group input[type=password]
{
margin-bottom: 0.5em;
}

View File

@ -12,6 +12,7 @@ Vn.Catalog = new Class
model.setFieldFlags ('id', Db.Conn.Flag.AI); model.setFieldFlags ('id', Db.Conn.Flag.AI);
model.setFieldFlags ('Id_Article', Db.Conn.Flag.PRI_KEY); model.setFieldFlags ('Id_Article', Db.Conn.Flag.PRI_KEY);
this.$('price').renderer = this.priceRenderer;
this.$('type-column').renderer = this.typeRenderer.bind (this); this.$('type-column').renderer = this.typeRenderer.bind (this);
this.$('cat').renderer = this.catRenderer; this.$('cat').renderer = this.catRenderer;
this.$('basket-button').addEventListener ('click', this.basketClicked.bind (this)); this.$('basket-button').addEventListener ('click', this.basketClicked.bind (this));
@ -26,17 +27,12 @@ Vn.Catalog = new Class
this.$('warehouse').value = 1; this.$('warehouse').value = 1;
this.$('date').value = new Date (); this.$('date').value = new Date ();
if (!Vn.Url.getQuery ('guest')) var orderId = Vn.Cookie.getInt ('order');
{
var orderId = Vn.Cookie.getInt ('order');
if (!orderId) if (!orderId)
this.configureView (); this.configureView ();
else
this.$('order-batch').addValue ('order', orderId);
}
else else
this.$('order').value = 0; this.$('order-batch').addValue ('order', orderId);
} }
,onRealmsReload: function (model, status) ,onRealmsReload: function (model, status)
@ -189,17 +185,6 @@ Vn.Catalog = new Class
Vn.Cookie.unset ('order'); Vn.Cookie.unset ('order');
this.$('order').value = orderId; this.$('order').value = orderId;
var priceCol = new Htk.ColumnSpin
({
title: 'Price'
,digits: 2
,unit: '€'
,column: 'price'
,renderer: this.priceRenderer
});
grid.insertColumn (11, priceCol);
this.$('basket-button').disabled = false; this.$('basket-button').disabled = false;
} }

View File

@ -28,8 +28,7 @@
<db-model result-index="1" main-table="m" updatable="false" id="items-model"> <db-model result-index="1" main-table="m" updatable="false" id="items-model">
CALL item (#warehouse, #date); CALL item (#warehouse, #date);
SELECT i.grouping, m.amount, Foto, i.available, Article, Categoria, SELECT i.grouping, m.amount, Foto, i.available, Article, Categoria,
Medida, Tallos, Color, o.Abreviatura, price, fixed, m.id, Medida, Tallos, Color, o.Abreviatura, price, fixed, m.id, Id_Article
Id_Article
FROM vn2008.Articles a FROM vn2008.Articles a
INNER JOIN vn2008.item_catalog i ON i.item_id = a.Id_Article INNER JOIN vn2008.item_catalog i ON i.item_id = a.Id_Article
LEFT JOIN vn2008.Origen o ON a.id_origen = o.id LEFT JOIN vn2008.Origen o ON a.id_origen = o.id
@ -106,6 +105,7 @@
<htk-column-text title="_Color" column="Color"/> <htk-column-text title="_Color" column="Color"/>
<htk-column-text title="_Tallos" column="Tallos"/> <htk-column-text title="_Tallos" column="Tallos"/>
<htk-column-text title="_Origin" column="Abreviatura"/> <htk-column-text title="_Origin" column="Abreviatura"/>
<htk-column-text title="_Price" column="price" digits="2" unit="€" id="price"/>
</htk-grid> </htk-grid>
<p class="footer-message"> <p class="footer-message">
<t>IndicativePhotos</t> <t>IndicativePhotos</t>

View File

@ -5,11 +5,15 @@ Vn.New = new Class
,activate: function () ,activate: function ()
{ {
this.$('new-cancel').addEventListener ('click', this.onCancelClick.bind (this));
this.$('new-accept').addEventListener ('click', this.onAcceptClick.bind (this));
this.$('new-form').on ('status-changed', this.onStatusChange, this);
this.$('new-body').on ('changed', this.onBodyChange, this);
this.$('html-editor').id = 'html-editor'; this.$('html-editor').id = 'html-editor';
this.$('return').addEventListener ('click', this.onReturnClick.bind (this));
this.$('accept').addEventListener ('click', this.onAcceptClick.bind (this));
this.$('body').on ('changed', this.onBodyChange, this);
this.$('iter').on ('status-changed', this.onStatusChange, this);
this.$('model').on ('operations-done', this.onOperationsDone, this);
this.$('model').mode = Db.Model.Mode.ON_DEMAND;
this.$('model').setDefault ('user_id', 'news',
new Sql.Func ({schema: 'account', name: 'user_get_id'}));
tinymce.init ({ tinymce.init ({
mode : 'exact' mode : 'exact'
@ -36,13 +40,19 @@ Vn.New = new Class
,onStatusChange: function (form) ,onStatusChange: function (form)
{ {
if (this.$('new-param').value == 0) if (this.$('new-id').value == 0)
form.insertRow (); form.insertRow ();
} }
,onOperationsDone: function ()
{
(new Htk.Toast ()).showMessage (_('NewChangedSuccessfully'));
this.onReturnClick ();
}
,onBodyChange: function () ,onBodyChange: function ()
{ {
var newHtml = this.$('new-form').get ('text'); var newHtml = this.$('iter').get ('text');
if (!newHtml) if (!newHtml)
newHtml = ''; newHtml = '';
@ -50,40 +60,16 @@ Vn.New = new Class
tinyMCE.get ('html-editor').setContent (newHtml); tinyMCE.get ('html-editor').setContent (newHtml);
} }
,onCancelClick: function () ,onAcceptClick: function ()
{
var newHtml = tinyMCE.get ('html-editor').getContent ();
this.$('iter').set ('text', newHtml);
this.$('iter').performOperations ();
}
,onReturnClick: function ()
{ {
this.hash.set ({'form': 'news/news'}); this.hash.set ({'form': 'news/news'});
} }
,onAcceptClick: function ()
{
var form = this.$('new-form');
var newHtml = tinyMCE.get ('html-editor').getContent ();
if (this.$('new-param').value == 0)
{
var batch = new Sql.Batch ();
batch.addValue ('title', form.get ('title'));
batch.addValue ('tag', form.get ('tag'));
batch.addValue ('text', newHtml);
var query = 'INSERT INTO news (title, text, tag, user_id) '
+'VALUES (#title, #text, #tag, account.user_get_id())';
this.conn.execQuery (query, this.newAdded.bind (this), batch);
// this.$('new-form').performOperations ();
}
else
{
form.set ('text', newHtml);
this.onCancelClick ();
}
}
,newAdded: function (resultSet)
{
if (resultSet.fetchResult ())
this.onCancelClick ();
}
}); });

View File

@ -1,15 +1,15 @@
<vn> <vn>
<vn-group> <vn-group>
<vn-param id="new-param"> <vn-param id="new-id">
<vn-hash-link key="new"/> <vn-hash-link key="new"/>
</vn-param> </vn-param>
<db-form id="new-form"> <db-form id="iter">
<db-param column="text" id="new-body"/> <db-param column="text" id="body"/>
<db-model> <db-model id="model">
SELECT id, user_id, title, text, tag SELECT id, title, text, tag
FROM news WHERE id = #new FROM news WHERE id = #new
<sql-batch property="batch"> <sql-batch property="batch">
<item name="new" param="new-param"/> <item name="new" param="new-id"/>
</sql-batch> </sql-batch>
</db-model> </db-model>
</db-form> </db-form>
@ -18,15 +18,25 @@
<div class="box"> <div class="box">
<div class="header"> <div class="header">
<h1><t>AddNew</t></h1> <h1><t>AddNew</t></h1>
<div class="action-bar">
<button id="return">
<img src="image/dark/go-previous.svg" alt=""/>
<t>Return</t>
</button>
<button id="accept">
<img src="image/dark/ok.svg" alt=""/>
<t>Accept</t>
</button>
</div>
</div> </div>
<div class="form"> <div class="form">
<div class="form-group"> <div class="form-group">
<label><t>Title:</t></label> <label><t>Title:</t></label>
<htk-entry column="title" form="new-form"/> <htk-entry column="title" form="iter"/>
</div> </div>
<div class="form-group"> <div class="form-group">
<label><t>Tag:</t></label> <label><t>Tag:</t></label>
<htk-combo column="tag" form="new-form"> <htk-combo column="tag" form="iter">
<db-model property="model"> <db-model property="model">
SELECT name, description FROM news_tag SELECT name, description FROM news_tag
ORDER BY description ORDER BY description
@ -37,10 +47,6 @@
<label><t>NewBody:</t></label> <label><t>NewBody:</t></label>
<textarea id="html-editor"/> <textarea id="html-editor"/>
</div> </div>
<div class="foot">
<button id="new-cancel" class="vn"><t>Cancel</t></button>
<button id="new-accept" class="vn"><t>Accept</t></button>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -204,7 +204,7 @@ Db.Conn.implement
if (results[i] !== true) if (results[i] !== true)
{ {
var data = results[i].data; var data = results[i].data;
var columns = results[i].field; var columns = results[i].columns;
for (var j = 0; j < columns.length; j++) for (var j = 0; j < columns.length; j++)
{ {

View File

@ -1,30 +0,0 @@
Vn.HttpRequest = new Class
({
kvPairs: {}
,add: function (map)
{
for (var key in map)
this.kvPairs[key] = map[key];
}
,send: function (file, callback)
{
this.request = new XMLHttpRequest ();
this.request.open ('post', file, true);
this.request.setRequestHeader ('Content-Type', 'application/x-www-form-urlencoded');
this.request.onreadystatechange = this.requestStateChanged.bind (this, callback);
this.request.send (Vn.Url.makeUri (this.kvPairs));
}
,requestStateChanged: function (callback)
{
if (this.request.readyState == 4)
callback (this, this.request.status == 200);
}
,getJson: function ()
{
return eval ('('+ this.request.responseText +')');
}
});

View File

@ -1,4 +1,12 @@
/**
* Class to handle the Database select results. Also allows
* updates, insertions and deletions on tables where the primary key is
* selected.
*
* Note that table names must be unique in the selection query, otherwise
* updates are not allowed. If two tables of different schemes
* have the same name, an alias should be used to solve this.
**/
Db.Model = new Class ().extend Db.Model = new Class ().extend
({ ({
Status: Status:
@ -7,6 +15,22 @@ Db.Model = new Class ().extend
,LOADING : 2 ,LOADING : 2
,READY : 3 ,READY : 3
,ERROR : 4 ,ERROR : 4
},
Mode:
{
ON_CHANGE: 1
,ON_DEMAND: 2
},
Operation:
{
INSERT: 1 << 1
,UPDATE: 1 << 2
,DELETE: 1 << 3
}
,SortWay:
{
ASC : 1,
DESC : 2
} }
}); });
@ -171,23 +195,31 @@ Db.Model.implement
,_batch: null ,_batch: null
,_stmt: null ,_stmt: null
,_status: Db.Model.Status.CLEAN ,_status: Db.Model.Status.CLEAN
,requestedMainTable: null
,requestedUpdatable: true
,data: null ,data: null
,tables: null
,columns: null ,columns: null
,columnMap: null ,columnMap: null
,insertedRow: -1
,defaults: []
,columnDefaults: []
,sortColumn: -1 ,sortColumn: -1
,sortWay: null
,requestedIndexes: {} ,requestedIndexes: {}
,indexes: [] ,indexes: []
,mode: Db.Model.Mode.ON_CHANGE
,operations: null
,operationsMap: null
,_insertedRow: -1
,defaults: []
,columnDefaults: []
,requestedMainTable: null
,requestedUpdatable: true
,initialize: function (props) ,initialize: function (props)
{ {
this.parent (props); this.parent (props);
this.cleanData (); this._cleanData ();
this.setStatus (Db.Model.Status.CLEAN); this._resetOperations ();
this._setStatus (Db.Model.Status.CLEAN);
} }
,loadXml: function (builder, node) ,loadXml: function (builder, node)
@ -208,18 +240,62 @@ Db.Model.implement
if (this._conn && this._stmt if (this._conn && this._stmt
&& (!this._batch || this._batch.isReady ())) && (!this._batch || this._batch.isReady ()))
{ {
this.setStatus (Db.Model.Status.LOADING); this._setStatus (Db.Model.Status.LOADING);
this._conn.execStmt (this._stmt, this.selectDone.bind (this), this._batch); this._conn.execStmt (this._stmt, this._selectDone.bind (this), this._batch);
} }
else else
{ {
this.cleanData (); this._cleanData ();
this.setStatus (Db.Model.Status.CLEAN); this._setStatus (Db.Model.Status.CLEAN);
} }
} }
,_selectDone: function (resultSet)
{
var result;
var dataResult;
,cleanData: function (error) this._cleanData ();
for (var i = 0; result = resultSet.fetchResult (); i++)
if (i == this._resultIndex)
dataResult = result;
if (dataResult && typeof dataResult === 'object')
{
this.sortColumn = -1;
this.data = dataResult.data;
this.tables = dataResult.tables;
this.columns = dataResult.columns;
this.columnMap = dataResult.columnMap;
this.repairColumns (this.columns);
this._refreshRowIndexes ();
this.refreshMainTable ();
for (column in this.requestedIndexes)
this._buildIndex (column);
this._setStatus (Db.Model.Status.READY);
}
else
this._setStatus (Db.Model.Status.ERROR);
}
,_refreshRowIndexes: function ()
{
for (var i = 0; i < this.data.length; i++)
this.data[i].index = i;
if (this.operationsMap)
{
this.operationsMap = {};
for (var i = 0; i < this.operations.length; i++)
this.operationsMap[i] = this.operations[i];
}
}
,_cleanData: function (error)
{ {
this.data = null; this.data = null;
this.columns = null; this.columns = null;
@ -230,7 +306,7 @@ Db.Model.implement
,refreshUpdatable: function () ,refreshUpdatable: function ()
{ {
var oldValue = this._updatable; var oldValue = this._updatable;
this._updatable = this._mainTable != null && this.requestedUpdatable; this._updatable = this._mainTable !== null && this.requestedUpdatable;
if (oldValue != this._updatable) if (oldValue != this._updatable)
this.signalEmit ('updatable-changed'); this.signalEmit ('updatable-changed');
@ -239,16 +315,15 @@ Db.Model.implement
,refreshMainTable: function () ,refreshMainTable: function ()
{ {
var newMainTable = null; var newMainTable = null;
var newMainSchema = null; var tables = this.tables;
var x = this.columns;
if (x) if (tables)
for (var i = 0; i < x.length; i++) for (var i = 0; i < tables.length; i++)
if (x[i].flags & Db.Conn.Flag.PRI_KEY) if (tables[i].pks.length > 0)
if (!this.requestedMainTable if (!this.requestedMainTable
|| x[i].table === this.requestedMainTable) || tables[i].name === this.requestedMainTable)
{ {
newMainTable = x[i].table; newMainTable = i;
break; break;
} }
@ -256,6 +331,23 @@ Db.Model.implement
this.refreshUpdatable (); this.refreshUpdatable ();
} }
/**
* Sets the default value for inserted fields.
*
* @param {String} field The destination field name
* @param {String} table The destination table name
* @param {Sql.Expr} srcColumn The default value expression
**/
,setDefault: function (field, table, expr)
{
this.defaults.push
({
field: field
,table: table
,expr: expr
});
}
/** /**
* Sets the default value for inserted fields. * Sets the default value for inserted fields.
* *
@ -283,7 +375,7 @@ Db.Model.implement
**/ **/
,setDefaultFromColumn: function (field, table, srcColumn) ,setDefaultFromColumn: function (field, table, srcColumn)
{ {
this.columnDefaults.push this.defaults.push
({ ({
field: field field: field
,table: table ,table: table
@ -305,17 +397,17 @@ Db.Model.implement
/** /**
* Checks if the row exists. * Checks if the row exists.
* *
* @param {integer} row The row index * @param {integer} rowIndex The row index
* @return {Boolean} %true if row exists, %false otherwise * @return {Boolean} %true if row exists, %false otherwise
**/ **/
,checkRowExists: function (row) ,checkRowExists: function (rowIndex)
{ {
return this.data && row >= 0 && row < this.data.length; return this.data && rowIndex >= 0 && rowIndex < this.data.length;
} }
,checkRowUpdatable: function (row) ,checkRowUpdatable: function (rowIndex)
{ {
return this.checkRowExists (row); return this.checkRowExists (rowIndex);
} }
/** /**
@ -338,16 +430,16 @@ Db.Model.implement
/** /**
* Gets a value from the model. * Gets a value from the model.
* *
* @param {number} row The row index * @param {number} rowIndex The row index
* @param {string} columnName The column name * @param {string} columnName The column name
* @return {mixed} The value * @return {mixed} The value
**/ **/
,get: function (row, columnName) ,get: function (rowIndex, columnName)
{ {
var index = this.getColumnIndex (columnName); var index = this.getColumnIndex (columnName);
if (index != -1) if (index != -1)
return this.getByIndex (row, index); return this.getByIndex (rowIndex, index);
return undefined; return undefined;
} }
@ -355,29 +447,29 @@ Db.Model.implement
/** /**
* Updates a value on the model. * Updates a value on the model.
* *
* @param {number} row The row index * @param {number} rowIndex The row index
* @param {string} columnName The column name * @param {string} columnName The column name
* @param {mixed} value The new value * @param {mixed} value The new value
**/ **/
,set: function (row, columnName, value) ,set: function (rowIndex, columnName, value)
{ {
var index = this.getColumnIndex (columnName); var index = this.getColumnIndex (columnName);
if (index != -1) if (index != -1)
this.setByIndex (row, index, value); this.setByIndex (rowIndex, index, value);
} }
/** /**
* Gets a value from the model using the column index. * Gets a value from the model using the column index.
* *
* @param {number} row The row index * @param {number} rowIndex The row index
* @param {number} column The column index * @param {number} column The column index
* @return {mixed} The value * @return {mixed} The value
**/ **/
,getByIndex: function (row, column) ,getByIndex: function (rowIndex, column)
{ {
if (this.checkRowExists (row) && this.checkColExists (column)) if (this.checkRowExists (rowIndex) && this.checkColExists (column))
return this.data[row][column]; return this.data[rowIndex][column];
return undefined; return undefined;
} }
@ -385,86 +477,75 @@ Db.Model.implement
/** /**
* Updates a value on the model using the column index. * Updates a value on the model using the column index.
* *
* @param {number} row The row index * @param {number} rowIndex The row index
* @param {number} col The column index * @param {number} col The column index
* @param {mixed} value The new value * @param {mixed} value The new value
**/ **/
,setByIndex: function (row, col, value) ,setByIndex: function (rowIndex, col, value)
{ {
if (!(this.checkRowUpdatable (row) && this.checkColExists (col))) if (!(this.checkRowUpdatable (rowIndex) && this.checkColExists (col)))
return; return;
if (row == this.insertedRow) var tableIndex = this.columns[col].table;
{ var pks = this.tables[tableIndex].pks;
this.performUpdate (row, [col], [value]);
if (pks.length == 0)
return; return;
}
var column = this.columns[col]; var row = this.data[rowIndex];
var where = this.getWhere (column.table, row, false);
if (where) var op = this._createOperation (rowIndex);
op.type |= Db.Model.Operation.UPDATE;
if (!op.oldValues)
op.oldValues = [];
if (!op.tables)
op.tables = {};
var tableOp = op.tables[tableIndex];
if (!tableOp)
{ {
var multiStmt = new Sql.MultiStmt (); tableOp = Db.Model.Operation.UPDATE;
var table = new Sql.Table for (var i = 0; i < pks.length; i++)
({ if (!row[pks[i]] && !op.oldValues[pks[i]])
name: column.orgtable {
,schema: column.db tableOp = Db.Model.Operation.INSERT;
}); break;
}
var update = new Sql.Update ({where: where}); op.tables[tableIndex] = tableOp;
update.addTarget (table);
update.addSet (column.orgname, value);
multiStmt.addStmt (update);
var select = new Sql.Select ({where: where});
select.addTarget (table);
select.addField (column.orgname);
multiStmt.addStmt (select);
var updateData = {
row: row
,columns: [col]
};
this._conn.execStmt (multiStmt,
this.updateDone.bind (this, updateData));
} }
else
this.sendInsert (column.table, row, col, value); if (tableOp & Db.Model.Operation.UPDATE
&& op.oldValues[col] === undefined)
op.oldValues[col] = row[col];
this.signalEmit ('row-updated-before', rowIndex);
row[col] = value;
this.signalEmit ('row-updated', rowIndex, [col]);
if (this.mode == Db.Model.Mode.ON_CHANGE
&& !(op.type & Db.Model.Operation.INSERT))
this.performOperations ();
} }
/** /**
* Deletes a row from the model. * Deletes a row from the model.
* *
* @param {number} row The row index * @param {number} rowIndex The row index
**/ **/
,deleteRow: function (row) ,deleteRow: function (rowIndex)
{ {
if (!this.checkRowUpdatable (row)) if (!this.checkRowUpdatable (rowIndex))
return; return;
if (row != this.insertedRow) var op = this._createOperation (rowIndex);
{ op.type |= Db.Model.Operation.DELETE;
var where = this.getWhere (this._mainTable, row, false);
if (where) if (this.mode === Db.Model.Mode.ON_CHANGE)
{ this.performOperations ();
var deleteQuery = new Sql.Delete ({where: where});
var table = this.getTarget (this._mainTable);
deleteQuery.addTarget (table);
this._conn.execStmt (deleteQuery,
this.deleteDone.bind (this, row));
}
}
else
{
this.performDelete (row);
this.insertedRow = -1;
}
} }
/** /**
@ -474,30 +555,298 @@ Db.Model.implement
**/ **/
,insertRow: function () ,insertRow: function ()
{ {
if (!this._updatable || this.insertedRow != -1) if (!this._updatable || this._insertedRow != -1)
return -1; return -1;
var x = this.columns; var cols = this.columns;
var newRow = new Array (x.length); var newRow = new Array (cols.length);
for (var i = 0; i < x.length; i++) for (var i = 0; i < cols.length; i++)
if (x[i].table === this._mainTable) if (cols[i].table === this._mainTable)
newRow[i] = x[i].def; newRow[i] = cols[i].def;
else else
newRow[i] = null; newRow[i] = null;
this.insertedRow = this.data.push (newRow) - 1; this._insertedRow = this.data.push (newRow) - 1;
this.signalEmit ('row-inserted', this.insertedRow);
return this.insertedRow; var op = this._createOperation (this._insertedRow);
op.type |= Db.Model.Operation.INSERT;
this.signalEmit ('row-inserted', this._insertedRow);
return this._insertedRow;
} }
/**
* Performs all model changes on the database.
**/
,performOperations: function () ,performOperations: function ()
{ {
if (this.insertedRow == -1) if (this.operations.length === 0)
return; return;
this.sendInsert (this._mainTable, this.insertedRow, -1, null); var stmts = new Sql.MultiStmt ();
var query = new Sql.String ({query: 'START TRANSACTION'});
stmts.addStmt (query);
for (var i = 0; i < this.operations.length; i++)
{
query = null;
var op = this.operations[i];
if (op.type & Db.Model.Operation.DELETE)
{
if (op.type & Db.Model.Operation.INSERT)
continue;
var where = this._createWhere (this._mainTable, op, true);
if (where)
{
query = new Sql.Delete ({where: where});
query.addTarget (this._createTarget (this._mainTable));
}
}
else if (op.type & (Db.Model.Operation.INSERT | Db.Model.Operation.UPDATE))
{
query = new Sql.MultiStmt ();
for (var tableIndex in op.tables)
{
var stmt = this._createDmlQuery (op, parseInt (tableIndex));
query.addStmt (stmt);
}
}
if (query)
{
stmts.addStmt (query);
}
else
{
console.warn ('Db.Model: %s', _('ErrorSavingChanges'));
return;
}
}
var query = new Sql.String ({query: 'COMMIT'});
stmts.addStmt (query);
this._conn.execStmt (stmts,
this._onOperationsDone.bind (this));
}
,_createDmlQuery: function (op, tableIndex)
{
var where = this._createWhere (tableIndex, op, false);
if (!where)
return null;
var multiStmt = new Sql.MultiStmt ();
var target = this._createTarget (tableIndex);
var select = new Sql.Select ({where: where});
select.addTarget (target);
var tableOp = op.tables[tableIndex];
var table = this.tables[tableIndex];
var row = op.row;
var cols = this.columns;
if (tableOp & Db.Model.Operation.INSERT)
{
var dmlQuery = new Sql.Insert ();
for (var i = 0; i < this.defaults.length; i++)
{
var def = this.defaults[i];
if (def.table === table.name)
{
if (def.value)
dmlQuery.addSet (def.field, def.value);
else if (def.expr)
dmlQuery.addExpr (def.field, def.expr);
else if (def.srcColumn)
{
var columnIndex = this.getColumnIndex (def.srcColumn);
dmlQuery.addSet (def.field, row[columnIndex]);
}
}
}
for (var i = 0; i < cols.length; i++)
if (cols[i].table === tableIndex)
{
if (row[i] !== null)
dmlQuery.addSet (cols[i].orgname, row[i]);
select.addField (cols[i].orgname);
}
}
else
{
var updateWhere = this._createWhere (tableIndex, op, true);
if (!updateWhere)
return null;
var dmlQuery = new Sql.Update ({where: updateWhere});
for (var i = 0; i < cols.length; i++)
if (cols[i].table === tableIndex && op.oldValues[i] !== undefined)
{
var fieldName = cols[i].orgname;
dmlQuery.addSet (fieldName, row[i]);
select.addField (fieldName);
}
}
dmlQuery.addTarget (target);
multiStmt.addStmt (dmlQuery);
multiStmt.addStmt (select);
return multiStmt;
}
,_onOperationsDone: function (resultSet)
{
if (resultSet.getError ())
return;
resultSet.fetchResult ();
for (var i = 0; i < this.operations.length; i++)
{
var isOperation = true;
var op = this.operations[i];
var row = op.row;
if (op.type & Db.Model.Operation.DELETE
&& op.type & Db.Model.Operation.INSERT)
isOperation = false;
if (op.type & Db.Model.Operation.DELETE)
{
resultSet.fetchResult ();
this._performDelete (row);
}
else if (op.type & (Db.Model.Operation.INSERT | Db.Model.Operation.UPDATE))
{
this.signalEmit ('row-updated-before', row.index);
var updatedCols = [];
var cols = this.columns;
for (var tableIndex in op.tables)
{
var j = 0;
tableIndex = parseInt (tableIndex);
var tableOp = op.tables[tableIndex];
var table = this.tables[tableIndex];
resultSet.fetchResult ();
var newValues = resultSet.fetchRow ();
if (tableOp & Db.Model.Operation.INSERT)
{
for (var i = 0; i < cols.length; i++)
if (cols[i].table === tableIndex)
{
row[i] = newValues[j++];
updatedCols.push (i);
}
}
else
{
for (var i = 0; i < cols.length; i++)
if (cols[i].table === tableIndex
&& op.oldValues[i] !== undefined)
{
row[i] = newValues[j++];
updatedCols.push (i);
}
}
}
this.signalEmit ('row-updated', row.index, updatedCols);
}
}
resultSet.fetchResult ();
if (isOperation)
this.signalEmit ('operations-done');
this._resetOperations ();
}
/**
* Undoes all unsaved changes made to the model.
**/
,reverseOperations: function ()
{
for (var i = 0; i < this.operations.length; i++)
{
var op = this.operations[i];
var row = op.row;
if (op.type & Db.Model.Operation.INSERT)
{
this._performDelete (row);
}
else if (op.type & Db.Model.Operation.UPDATE)
{
this.signalEmit ('row-updated-before', row.index);
var updatedCols = [];
var cols = this.columns;
for (var i = 0; i < cols.length; i++)
if (op.oldValues[i] !== undefined)
{
row[i] = op.oldValues[i];
updatedCols.push (i);
}
this.signalEmit ('row-updated', row.index, updatedCols);
}
}
this._resetOperations ();
}
,_resetOperations: function ()
{
this.operations = [];
this.operationsMap = {};
}
,_performDelete: function (row)
{
if (!this.requestedMainTable)
{
this.signalEmit ('row-deleted-before', row.index);
this.data.splice (row.index, 1);
this.signalEmit ('row-deleted', row.index);
}
else
{
this.signalEmit ('row-updated-before', row.index);
var updatedCols = [];
for (var i = 0; i < this.columns.length; i++)
if (this.columns[i].table == this._mainTable)
{
row[i] = null;
updatedCols.push (i);
}
this.signalEmit ('row-updated', row.index, updatedCols);
}
} }
/* /*
@ -518,12 +867,12 @@ Db.Model.implement
* *
* @param {integer} column the column index * @param {integer} column the column index
**/ **/
,sort: function (column) ,sort: function (column, way)
{ {
if (!this.checkColExists (column)) if (!this.checkColExists (column))
return; return;
this.setStatus (Db.Model.Status.LOADING); this._setStatus (Db.Model.Status.LOADING);
if (column != this.sortColumn) if (column != this.sortColumn)
{ {
@ -533,7 +882,9 @@ Db.Model.implement
else else
this.data.reverse (); this.data.reverse ();
this.setStatus (Db.Model.Status.READY); this._refreshRowIndexes ();
this._setStatus (Db.Model.Status.READY);
} }
/** /**
@ -548,10 +899,10 @@ Db.Model.implement
this.requestedIndexes[column] = true; this.requestedIndexes[column] = true;
if (this._status == Db.Model.Status.READY) if (this._status == Db.Model.Status.READY)
this.buildIndex (column); this._buildIndex (column);
} }
,buildIndex: function (column) ,_buildIndex: function (column)
{ {
var columnIndex = this.getColumnIndex (column); var columnIndex = this.getColumnIndex (column);
@ -653,193 +1004,74 @@ Db.Model.implement
return -1; return -1;
} }
// private: ,_setStatus: function (status)
,setStatus: function (status)
{ {
this._status = status; this._status = status;
this.signalEmit ('status-changed', status); this.signalEmit ('status-changed', status);
} }
,getTarget: function (table) ,_createTarget: function (tableIndex)
{ {
var x = this.columns; var table = this.tables[tableIndex];
for (var i = 0; i < x.length; i++) return new Sql.Table
if (x[i].table == table) ({
return new Sql.Table name: table.orgname
({ ,schema: table.schema
name: x[i].orgtable });
,schema: x[i].db
});
return null;
} }
,getWhere: function (table, rowIndex, forInsert) ,_createWhere: function (tableIndex, op, useOldValues)
{ {
var keyFound = false; var where = new Sql.Operation ({type: Sql.Operation.Type.AND});
var row = this.data[rowIndex]; var pks = this.tables[tableIndex].pks;
var andOp = new Sql.Operation ({type: Sql.Operation.Type.AND});
var x = this.columns; if (pks.length === 0)
return null;
for (var i = 0; i < x.length; i++) for (var i = 0; i < pks.length; i++)
if (x[i].flags & Db.Conn.Flag.PRI_KEY
&& x[i].table === table)
{ {
var equalOp = new Sql.Operation ({type: Sql.Operation.Type.EQUAL}); var col = pks[i];
equalOp.exprs.add (new Sql.Field ({name: x[i].orgname})); var column = this.columns[col];
andOp.exprs.add (equalOp);
if (row[i]) var equalOp = new Sql.Operation ({type: Sql.Operation.Type.EQUAL});
equalOp.exprs.add (new Sql.Value ({value: row[i]})); equalOp.exprs.add (new Sql.Field ({name: column.orgname}));
else if (x[i].flags & Db.Conn.Flag.AI && forInsert) where.exprs.add (equalOp);
var pkValue = null;
if (useOldValues && op.oldValues
&& op.oldValues[col] !== undefined)
pkValue = op.oldValues[col];
else
pkValue = op.row[col];
if (pkValue)
equalOp.exprs.add (new Sql.Value ({value: pkValue}));
else if (column.flags & Db.Conn.Flag.AI && !useOldValues)
equalOp.exprs.add (new Sql.Func ({name: 'LAST_INSERT_ID'})); equalOp.exprs.add (new Sql.Func ({name: 'LAST_INSERT_ID'}));
else else
break; return null;
keyFound = true;
} }
return (keyFound) ? andOp : null; return where;
} }
,sendInsert: function (table, rowIndex, singleColumn, newValue) ,_createOperation: function (rowIndex)
{ {
var where = this.getWhere (table, rowIndex, true); var op = this.operationsMap[rowIndex];
if (!where) if (!op)
return;
var multiStmt = new Sql.MultiStmt ();
var target = this.getTarget (table);
var insert = new Sql.Insert ();
insert.addTarget (target);
multiStmt.addStmt (insert);
var x = this.defaults;
for (var i = 0; i < x.length; i++)
if (x[i].table === table)
insert.addSet (x[i].field, x[i].value);
var x = this.columnDefaults;
for (var i = 0; i < x.length; i++)
if (x[i].table === table)
insert.addSet (x[i].field, this.get (rowIndex, x[i].srcColumn));
var select = new Sql.Select ({where: where});
select.addTarget (target);
multiStmt.addStmt (select);
var columns = [];
var row = this.data[rowIndex];
var x = this.columns;
for (var i = 0; i < x.length; i++)
if (x[i].table === table)
{ {
var setValue = singleColumn != i ? row[i] : newValue; op = {
type: 0,
if (setValue) row: this.data[rowIndex]
insert.addSet (x[i].orgname, setValue); };
this.operations.push (op);
select.addField (x[i].orgname); this.operationsMap[rowIndex] = op;
columns.push (i);
} }
var updateData = { return op;
row: rowIndex
,columns: columns
};
this._conn.execStmt (multiStmt,
this.updateDone.bind (this, updateData));
}
,selectDone: function (resultSet)
{
var result;
var dataResult;
this.cleanData ();
for (var i = 0; result = resultSet.fetchResult (); i++)
if (i == this._resultIndex)
dataResult = result;
if (dataResult && typeof dataResult === 'object')
{
this.sortColumn = -1;
this.data = dataResult.data;
this.columns = dataResult.columns;
this.columnMap = dataResult.columnMap;
this.repairColumns (this.columns);
this.refreshMainTable ();
for (column in this.requestedIndexes)
this.buildIndex (column);
this.setStatus (Db.Model.Status.READY);
}
else
this.setStatus (Db.Model.Status.ERROR);
}
,updateDone: function (updateData, resultSet)
{
var newValues;
if (resultSet.fetchResult () && (newValues = resultSet.fetchRow ()))
this.performUpdate (updateData.row, updateData.columns, newValues);
}
,performUpdate: function (rowIndex, columns, newValues)
{
this.signalEmit ('row-updated-before', rowIndex);
var row = this.data[rowIndex];
for (var i = 0; i < columns.length; i++)
row[columns[i]] = newValues[i];
this.signalEmit ('row-updated', rowIndex, columns);
}
,deleteDone: function (rowIndex, resultSet)
{
if (resultSet.fetchResult())
this.performDelete (rowIndex);
}
,performDelete: function (rowIndex)
{
var row = this.data[rowIndex];
if (!this.requestedMainTable)
{
this.signalEmit ('row-deleted-before', rowIndex);
this.data.splice (rowIndex, 1);
this.signalEmit ('row-deleted', rowIndex);
}
else
{
this.signalEmit ('row-updated-before', rowIndex);
var columns = [];
for (var i = 0; i < this.columns.length; i++)
if (this.columns[i].table == this._mainTable)
{
row[i] = null;
columns.push (i);
}
this.signalEmit ('row-updated', rowIndex, columns);
}
} }
// Delete when MySQL FLAG and view orgname "bugs" are repaired: // Delete when MySQL FLAG and view orgname "bugs" are repaired:

View File

@ -46,7 +46,7 @@ Db.ResultSet = new Class
if (result !== null) if (result !== null)
{ {
if (result.data instanceof Array) if (result.data instanceof Array)
return new Db.Result (result.data, result.field); return new Db.Result (result);
else else
return true; return true;
} }

View File

@ -6,20 +6,22 @@ Db.Result = new Class
/** /**
* Initilizes the result object. * Initilizes the result object.
**/ **/
initialize: function (data, columns) initialize: function (result)
{ {
this.data = data; this.data = result.data;
this.columns = columns; this.tables = result.tables;
this.columnMap = null; this.columns = result.columns;
this.row = -1; this.row = -1;
if (columns) if (this.columns)
{ {
this.columnMap = {}; this.columnMap = {};
for (var i = 0; i < columns.length; i++) for (var i = 0; i < this.columns.length; i++)
this.columnMap[columns[i].name] = i; this.columnMap[this.columns[i].name] = i;
} }
else
this.columnMap = null;
} }
/** /**

View File

@ -14,6 +14,12 @@ Sql.Dml = new Class
this.field.push (new Sql.Field ({name: fieldName})); this.field.push (new Sql.Field ({name: fieldName}));
} }
,addExpr: function (fieldName, expr)
{
this.expr.push (expr);
this.field.push (new Sql.Field ({name: fieldName}));
}
,delSet: function () ,delSet: function ()
{ {
this.field.splice (0, this.field.length); this.field.splice (0, this.field.length);

View File

@ -14,6 +14,11 @@ Sql.Func = new Class
type: String type: String
,value: null ,value: null
}, },
schema:
{
type: String
,value: null
},
params: params:
{ {
type: Sql.List type: Sql.List
@ -23,6 +28,7 @@ Sql.Func = new Class
,render: function (batch) ,render: function (batch)
{ {
return this.name + '()'; var sql = (this.schema) ? '`' + this.schema + '`.' : '';
return sql + '`' + this.name + '`()';
} }
}); });

View File

@ -13,6 +13,11 @@ Sql.MultiStmt = new Class
return this.stmts.push (stmt); return this.stmts.push (stmt);
} }
,getStmt: function (stmtIndex)
{
return this.stmts[index];
}
,stmtChanged: function () ,stmtChanged: function ()
{ {
this.signalEmit ('changed'); this.signalEmit ('changed');
@ -35,7 +40,12 @@ Sql.MultiStmt = new Class
var sql = ''; var sql = '';
for (var i = 0; i < this.stmts.length; i++) for (var i = 0; i < this.stmts.length; i++)
sql += this.stmts[i].render (batch) + '; '; {
if (i > 0)
sql += ";\n";
sql += this.stmts[i].render (batch);
}
return sql; return sql;
} }

View File

@ -42,7 +42,7 @@ Vn.Builder = new Class
,loadXmlFromNode: function (node) ,loadXmlFromNode: function (node)
{ {
this.contexts = []; this.contexts = [];
var mainNode = this.loadNode (node, null); var mainNode = this.loadNode (node);
this.resolveProperties (); this.resolveProperties ();
delete this.contexts; delete this.contexts;
return mainNode; return mainNode;
@ -53,8 +53,9 @@ Vn.Builder = new Class
this.objectMap[id] = object; this.objectMap[id] = object;
} }
,loadNode: function (node, parentContext) ,loadNode: function (node)
{ {
var customNode;
var htmlNode = null; var htmlNode = null;
var tagName = null; var tagName = null;
@ -69,59 +70,32 @@ Vn.Builder = new Class
{ {
htmlNode = document.importNode (node, false); htmlNode = document.importNode (node, false);
} }
else if ((customNode = this.loadCustomNode (node, null)))
{
if (customNode instanceof Htk.Widget)
htmlNode = customNode.getNode ();
}
else else
{ {
var vnObject = null; htmlNode = document.createElement (tagName);
var context = null;
var htmlNode = null;
var klass = Vn.customTags[tagName];
var nodeId = node.getAttribute ('id');
if (klass) var a = node.attributes;
{
var vnObject = new klass ();
if (vnObject instanceof Htk.Widget) for (var i = 0; i < a.length; i++)
htmlNode = vnObject.getNode (); if (a[i].nodeName !== 'id')
htmlNode.setAttribute (a[i].nodeName,
this.translateValue (a[i].nodeValue));
if (!this.tags[tagName]) this.registerObject (node, htmlNode);
this.tags[tagName] = [];
this.tags[tagName].push (vnObject);
context = {
node: node
,parent: parentContext
,object: vnObject
,klass: klass
};
this.contexts.push (context);
}
else
{
htmlNode = document.createElement (tagName);
vnObject = htmlNode;
var a = node.attributes;
for (var i = 0; i < a.length; i++)
if (a[i].nodeName !== 'id')
htmlNode.setAttribute (a[i].nodeName,
this.translateValue (a[i].nodeValue));
}
if (nodeId)
this.objectMap[nodeId] = vnObject;
var childs = node.childNodes; var childs = node.childNodes;
if (childs) if (childs)
for (var i = 0; i < childs.length; i++) for (var i = 0; i < childs.length; i++)
{ {
var htmlChild = var htmlChild = this.loadNode (childs[i]);
this.loadNode (childs[i], context);
if (htmlChild && htmlNode) if (htmlChild)
htmlNode.appendChild (htmlChild); htmlNode.appendChild (htmlChild);
} }
} }
@ -129,6 +103,51 @@ Vn.Builder = new Class
return htmlNode; return htmlNode;
} }
,loadCustomNode: function (node, parentContext)
{
if (!node.tagName)
return null;
var tagName = node.tagName.toLowerCase ();
var klass = Vn.customTags[tagName];
if (!klass)
return null;
var customNode = new klass ();
if (!this.tags[tagName])
this.tags[tagName] = [];
this.tags[tagName].push (customNode);
var context = {
node: node
,parent: parentContext
,object: customNode
,klass: klass
};
this.contexts.push (context);
this.registerObject (node, customNode);
var childs = node.childNodes;
if (childs)
for (var i = 0; i < childs.length; i++)
this.loadCustomNode (childs[i], context);
return customNode;
}
,registerObject: function (node, object)
{
var nodeId = node.getAttribute ('id');
if (nodeId)
this.objectMap[nodeId] = object;
}
,translateValue: function (value) ,translateValue: function (value)
{ {
var chr = value.charAt (0); var chr = value.charAt (0);

View File

@ -4,6 +4,8 @@
,"Title:": "Títol:" ,"Title:": "Títol:"
,"NewBody:": "Cos:" ,"NewBody:": "Cos:"
,"Cancel": "Cancel" ,"Return": "Tornar"
,"Accept": "Acceptar" ,"Accept": "Acceptar"
,"NewChangedSuccessfully": "Notícia modificada correctament"
} }

View File

@ -4,6 +4,8 @@
,"Title:": "Título:" ,"Title:": "Título:"
,"NewBody:": "Cuerpo:" ,"NewBody:": "Cuerpo:"
,"Cancel": "Cancelar" ,"Return": "Volver"
,"Accept": "Aceptar" ,"Accept": "Aceptar"
,"NewChangedSuccessfully": "Noticia modificada correctamente"
} }

View File

@ -4,6 +4,8 @@
,"Title:": "Titre:" ,"Title:": "Titre:"
,"NewBody:": "Corps:" ,"NewBody:": "Corps:"
,"Cancel": "Annuler" ,"Return": "Reviens"
,"Accept": "Accepter" ,"Accept": "Accepter"
,"NewChangedSuccessfully": "Nouvelles modifié avec succès"
} }

View File

@ -21,12 +21,14 @@ class RestMod extends Rest\Module
if ($result !== FALSE) if ($result !== FALSE)
{ {
$tableMap = [];
$columns = $result->fetch_fields (); $columns = $result->fetch_fields ();
$resultMap = $resultMap =
[ [
'data' => [], 'data' => [],
'field' => [] 'columns' => [],
'tables' => []
]; ];
for ($i = 0; $i < $result->field_count; $i++) for ($i = 0; $i < $result->field_count; $i++)
@ -63,22 +65,38 @@ class RestMod extends Rest\Module
$type = TYPE_STRING; $type = TYPE_STRING;
} }
if (!isset ($tableMap[$column->table]))
{
$resultMap['tables'][] =
[
'name' => $column->table,
'orgname' => $column->orgtable,
'schema' => $column->db,
'pks' => []
];
$tableIndex = count ($resultMap['tables']) - 1;
$tableMap[$column->table] = $tableIndex;
}
else
$tableIndex = $tableMap[$column->table];
if ($column->flags & MYSQLI_PRI_KEY_FLAG)
$resultMap['tables'][$tableIndex]['pks'][] = $i;
$default = $this->castValue ($column->def, $type); $default = $this->castValue ($column->def, $type);
$resultMap['field'][] = $resultMap['columns'][] =
[ [
'type' => $type,
'flags' => $column->flags,
'def' => $default,
'name' => $column->name, 'name' => $column->name,
'orgname' => $column->orgname, 'orgname' => $column->orgname,
'table' => $column->table, 'table' => $tableIndex
'orgtable' => $column->orgtable,
'def' => $default,
'db' => $column->db,
'flags' => $column->flags,
'type' => $type
]; ];
} }
$columns = $resultMap['field']; $columns = $resultMap['columns'];
while ($row = $result->fetch_row ()) while ($row = $result->fetch_row ())
{ {
@ -95,6 +113,8 @@ class RestMod extends Rest\Module
$results[] = TRUE; $results[] = TRUE;
} }
while ($conn->moreResults () && $conn->nextResult ()); while ($conn->moreResults () && $conn->nextResult ());
$conn->checkError ();
} }
catch (Db\Exception $e) catch (Db\Exception $e)
{ {