forked from verdnatura/hedera-web
Improved timezone handling
This commit is contained in:
parent
4733185e9f
commit
7219962f0c
|
@ -23,5 +23,6 @@ return [
|
|||
,'schema' => 'hedera'
|
||||
,'user' => 'hedera-web'
|
||||
,'pass' => ''
|
||||
,'tz' => 'Europe/madrid'
|
||||
]
|
||||
];
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
hedera-web (1.407.11) stable; urgency=low
|
||||
hedera-web (1.407.12) stable; urgency=low
|
||||
|
||||
* Initial Release.
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
* class or you could have a serious security hole in you application becasuse
|
||||
* the user can send any statement to the server. For example: DROP DATABASE
|
||||
**/
|
||||
var Connection = new Class ();
|
||||
var Connection = new Class();
|
||||
module.exports = Connection;
|
||||
|
||||
var Flag =
|
||||
|
@ -45,10 +45,9 @@ Connection.implement
|
|||
* @param {String} sql The SQL statement
|
||||
* @param {Function} callback The function to call when operation is done
|
||||
**/
|
||||
,execSql: function (sql, callback)
|
||||
{
|
||||
this.send ('core/query', {'sql': sql},
|
||||
this._onExec.bind (this, callback));
|
||||
,execSql: function(sql, callback) {
|
||||
this.send('core/query', {'sql': sql},
|
||||
this._onExec.bind(this, callback));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,9 +57,8 @@ Connection.implement
|
|||
* @param {Function} callback The function to call when operation is done
|
||||
* @param {Sql.Batch} batch The batch used to set the parameters
|
||||
**/
|
||||
,execStmt: function (stmt, callback, batch)
|
||||
{
|
||||
this.execSql (stmt.render (batch), callback);
|
||||
,execStmt: function(stmt, callback, batch) {
|
||||
this.execSql(stmt.render(batch), callback);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -70,39 +68,33 @@ Connection.implement
|
|||
* @param {Function} callback The function to call when operation is done
|
||||
* @param {Sql.Batch} batch The batch used to set the parameters
|
||||
**/
|
||||
,execQuery: function (query, callback, batch)
|
||||
{
|
||||
this.execStmt (new Sql.String ({query: query}), callback, batch);
|
||||
,execQuery: function(query, callback, batch) {
|
||||
this.execStmt(new Sql.String({query: query}), callback, batch);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses a value to date.
|
||||
*/
|
||||
,valueToDate: function (value)
|
||||
{
|
||||
return new Date (value * 1000);
|
||||
,valueToDate: function(value) {
|
||||
return new Date(value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when a query is executed.
|
||||
*/
|
||||
,_onExec: function (callback, json, error)
|
||||
{
|
||||
,_onExec: function(callback, json, error) {
|
||||
if (json)
|
||||
try {
|
||||
if (json && json instanceof Array)
|
||||
for (var i = 0; i < json.length; i++)
|
||||
if (json[i] !== true)
|
||||
{
|
||||
if (json[i] !== true) {
|
||||
var data = json[i].data;
|
||||
var columns = json[i].columns;
|
||||
|
||||
for (var j = 0; j < columns.length; j++)
|
||||
{
|
||||
for (var j = 0; j < columns.length; j++) {
|
||||
var castFunc = null;
|
||||
|
||||
switch (columns[j].type)
|
||||
{
|
||||
switch (columns[j].type) {
|
||||
case Type.DATE:
|
||||
case Type.DATE_TIME:
|
||||
case Type.TIMESTAMP:
|
||||
|
@ -110,25 +102,22 @@ Connection.implement
|
|||
break;
|
||||
}
|
||||
|
||||
if (castFunc !== null)
|
||||
{
|
||||
if (castFunc !== null) {
|
||||
if (columns[j].def != null)
|
||||
columns[j].def = castFunc (columns[j].def);
|
||||
columns[j].def = castFunc(columns[j].def);
|
||||
|
||||
for (var k = 0; k < data.length; k++)
|
||||
if (data[k][j] != null)
|
||||
data[k][j] = castFunc (data[k][j]);
|
||||
data[k][j] = castFunc(data[k][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
|
||||
if (callback)
|
||||
callback (new Db.ResultSet (json, error));
|
||||
callback(new Db.ResultSet(json, error));
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -235,6 +235,10 @@ td.cell-image .htk-image
|
|||
{
|
||||
border-top: none;
|
||||
}
|
||||
.htk-calendar th.button
|
||||
{
|
||||
display: table-cell;
|
||||
}
|
||||
.htk-calendar th.button:hover
|
||||
{
|
||||
cursor: pointer;
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
|
||||
var Expr = require ('./expr');
|
||||
var Expr = require('./expr');
|
||||
|
||||
/**
|
||||
* The equivalent of a SQL value.
|
||||
**/
|
||||
module.exports = new Class
|
||||
({
|
||||
module.exports = new Class({
|
||||
Extends: Expr
|
||||
,Tag: 'sql-value'
|
||||
|
||||
|
@ -17,13 +16,11 @@ module.exports = new Class
|
|||
param:
|
||||
{
|
||||
type: Vn.Param
|
||||
,set: function (x)
|
||||
{
|
||||
this.link ({_param: x}, {'changed': this.onParamChange});
|
||||
this.onParamChange ();
|
||||
,set: function(x) {
|
||||
this.link({_param: x}, {'changed': this.onParamChange});
|
||||
this.onParamChange();
|
||||
}
|
||||
,get: function ()
|
||||
{
|
||||
,get: function() {
|
||||
return this._param;
|
||||
}
|
||||
},
|
||||
|
@ -33,27 +30,24 @@ module.exports = new Class
|
|||
value:
|
||||
{
|
||||
type: String
|
||||
,set: function (x)
|
||||
{
|
||||
if (Vn.Value.compare (x, this._value))
|
||||
,set: function(x) {
|
||||
if (Vn.Value.compare(x, this._value))
|
||||
return;
|
||||
|
||||
if (x instanceof Date)
|
||||
x = x.clone ();
|
||||
x = x.clone();
|
||||
|
||||
this._value = x;
|
||||
|
||||
if (this._param && !this.paramLock)
|
||||
{
|
||||
if (this._param && !this.paramLock) {
|
||||
this.paramLock = true;
|
||||
this._param.value = x;
|
||||
this.paramLock = false;
|
||||
}
|
||||
|
||||
this.signalEmit ('changed');
|
||||
this.signalEmit('changed');
|
||||
}
|
||||
,get: function ()
|
||||
{
|
||||
,get: function() {
|
||||
return this._value;
|
||||
}
|
||||
}
|
||||
|
@ -61,11 +55,10 @@ module.exports = new Class
|
|||
|
||||
,_value: undefined
|
||||
,_param: null
|
||||
,regexp: new RegExp ('(\\\\)|\'', 'g')
|
||||
,regexp: new RegExp('(\\\\)|\'', 'g')
|
||||
,paramLock: false
|
||||
|
||||
,onParamChange: function ()
|
||||
{
|
||||
,onParamChange: function() {
|
||||
if (this.paramLock || !this._param)
|
||||
return;
|
||||
|
||||
|
@ -74,15 +67,12 @@ module.exports = new Class
|
|||
this.paramLock = false;
|
||||
}
|
||||
|
||||
,isReady: function ()
|
||||
{
|
||||
,isReady: function() {
|
||||
return this._value !== undefined;
|
||||
}
|
||||
|
||||
,replaceFunc: function (token)
|
||||
{
|
||||
switch (token)
|
||||
{
|
||||
,replaceFunc: function(token) {
|
||||
switch (token) {
|
||||
case '\\': return '\\\\';
|
||||
case '\'': return '\\\'';
|
||||
}
|
||||
|
@ -90,23 +80,25 @@ module.exports = new Class
|
|||
return token;
|
||||
}
|
||||
|
||||
,render: function (batch)
|
||||
{
|
||||
,render: function() {
|
||||
var v = this._value;
|
||||
|
||||
switch (typeof v)
|
||||
{
|
||||
switch (typeof v) {
|
||||
case 'number':
|
||||
return v;
|
||||
case 'boolean':
|
||||
return (v) ? 'TRUE' : 'FALSE';
|
||||
case 'string':
|
||||
return "'" + v.replace (this.regexp, this.replaceFunc) + "'";
|
||||
case 'object':
|
||||
if (v instanceof Date)
|
||||
return Vn.Date.strftime (v, '\'%Y-%m-%d\'');
|
||||
return "'" + v.replace(this.regexp, this.replaceFunc) + "'";
|
||||
default:
|
||||
if (v instanceof Date) {
|
||||
// TODO: Read time zone from db configuration
|
||||
var tz = {timeZone: 'Europe/Madrid'};
|
||||
var localeDate = new Date(v.toLocaleString('en-US', tz));
|
||||
return Vn.Date.strftime(localeDate, '\'%Y-%m-%d\'');
|
||||
} else {
|
||||
return 'NULL';
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "hedera-web",
|
||||
"version": "1.407.11",
|
||||
"version": "1.407.12",
|
||||
"description": "Verdnatura web page",
|
||||
"license": "GPL-3.0",
|
||||
"repository": {
|
||||
|
|
|
@ -8,6 +8,18 @@ class Query extends Vn\Web\JsonRequest {
|
|||
const PARAMS = ['sql'];
|
||||
const SECURITY = Security::INVOKER;
|
||||
|
||||
function __construct($app) {
|
||||
parent::__construct($app);
|
||||
$this->utcTz = new DateTimeZone('UTC');
|
||||
|
||||
$dbConf = $app->getConf()['db'];
|
||||
|
||||
if (isset($dbConf['tz']))
|
||||
$this->tz = new DateTimeZone($dbConf['tz']);
|
||||
else
|
||||
$this->tz = $this->utcTz;
|
||||
}
|
||||
|
||||
function run($db) {
|
||||
$results = [];
|
||||
|
||||
|
@ -151,7 +163,10 @@ class Query extends Vn\Web\JsonRequest {
|
|||
* Transforms the database value into a JSON parseable value.
|
||||
**/
|
||||
function castValue($value, $type) {
|
||||
if ($value !== NULL)
|
||||
if ($value == '' && $type != Type::STRING)
|
||||
$value = NULL;
|
||||
|
||||
if (!empty($value))
|
||||
switch ($type) {
|
||||
case Type::BOOLEAN:
|
||||
return (bool) $value;
|
||||
|
@ -161,14 +176,9 @@ class Query extends Vn\Web\JsonRequest {
|
|||
return (float) $value;
|
||||
case Type::DATE:
|
||||
case Type::DATE_TIME:
|
||||
return mktime(
|
||||
substr($value, 11 , 2)
|
||||
,substr($value, 14 , 2)
|
||||
,substr($value, 17 , 2)
|
||||
,substr($value, 5 , 2)
|
||||
,substr($value, 8 , 2)
|
||||
,substr($value, 0 , 4)
|
||||
);
|
||||
$d = new DateTime($value, $this->tz);
|
||||
$d->setTimeZone($this->utcTz);
|
||||
return $d->format('Y-m-d\TH:i:s.v\Z');
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue