0
1
Fork 0

Improved timezone handling

This commit is contained in:
Juan Ferrer 2020-05-03 22:35:24 +02:00
parent 4733185e9f
commit 7219962f0c
7 changed files with 80 additions and 84 deletions

View File

@ -23,5 +23,6 @@ return [
,'schema' => 'hedera' ,'schema' => 'hedera'
,'user' => 'hedera-web' ,'user' => 'hedera-web'
,'pass' => '' ,'pass' => ''
,'tz' => 'Europe/madrid'
] ]
]; ];

2
debian/changelog vendored
View File

@ -1,4 +1,4 @@
hedera-web (1.407.11) stable; urgency=low hedera-web (1.407.12) stable; urgency=low
* Initial Release. * Initial Release.

View File

@ -9,7 +9,7 @@
* class or you could have a serious security hole in you application becasuse * 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 * the user can send any statement to the server. For example: DROP DATABASE
**/ **/
var Connection = new Class (); var Connection = new Class();
module.exports = Connection; module.exports = Connection;
var Flag = var Flag =
@ -45,10 +45,9 @@ Connection.implement
* @param {String} sql The SQL statement * @param {String} sql The SQL statement
* @param {Function} callback The function to call when operation is done * @param {Function} callback The function to call when operation is done
**/ **/
,execSql: function (sql, callback) ,execSql: function(sql, callback) {
{ this.send('core/query', {'sql': sql},
this.send ('core/query', {'sql': sql}, this._onExec.bind(this, callback));
this._onExec.bind (this, callback));
} }
/** /**
@ -58,9 +57,8 @@ Connection.implement
* @param {Function} callback The function to call when operation is done * @param {Function} callback The function to call when operation is done
* @param {Sql.Batch} batch The batch used to set the parameters * @param {Sql.Batch} batch The batch used to set the parameters
**/ **/
,execStmt: function (stmt, callback, batch) ,execStmt: function(stmt, callback, batch) {
{ this.execSql(stmt.render(batch), callback);
this.execSql (stmt.render (batch), callback);
} }
/** /**
@ -70,39 +68,33 @@ Connection.implement
* @param {Function} callback The function to call when operation is done * @param {Function} callback The function to call when operation is done
* @param {Sql.Batch} batch The batch used to set the parameters * @param {Sql.Batch} batch The batch used to set the parameters
**/ **/
,execQuery: function (query, callback, batch) ,execQuery: function(query, callback, batch) {
{ this.execStmt(new Sql.String({query: query}), callback, batch);
this.execStmt (new Sql.String ({query: query}), callback, batch);
} }
/* /*
* Parses a value to date. * Parses a value to date.
*/ */
,valueToDate: function (value) ,valueToDate: function(value) {
{ return new Date(value);
return new Date (value * 1000);
} }
/* /*
* Called when a query is executed. * Called when a query is executed.
*/ */
,_onExec: function (callback, json, error) ,_onExec: function(callback, json, error) {
{
if (json) if (json)
try { try {
if (json && json instanceof Array) if (json && json instanceof Array)
for (var i = 0; i < json.length; i++) for (var i = 0; i < json.length; i++)
if (json[i] !== true) if (json[i] !== true) {
{
var data = json[i].data; var data = json[i].data;
var columns = json[i].columns; var columns = json[i].columns;
for (var j = 0; j < columns.length; j++) for (var j = 0; j < columns.length; j++) {
{
var castFunc = null; var castFunc = null;
switch (columns[j].type) switch (columns[j].type) {
{
case Type.DATE: case Type.DATE:
case Type.DATE_TIME: case Type.DATE_TIME:
case Type.TIMESTAMP: case Type.TIMESTAMP:
@ -110,25 +102,22 @@ Connection.implement
break; break;
} }
if (castFunc !== null) if (castFunc !== null) {
{
if (columns[j].def != 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++) for (var k = 0; k < data.length; k++)
if (data[k][j] != null) 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; error = e;
} }
if (callback) if (callback)
callback (new Db.ResultSet (json, error)); callback(new Db.ResultSet(json, error));
} }
}); });

View File

@ -235,6 +235,10 @@ td.cell-image .htk-image
{ {
border-top: none; border-top: none;
} }
.htk-calendar th.button
{
display: table-cell;
}
.htk-calendar th.button:hover .htk-calendar th.button:hover
{ {
cursor: pointer; cursor: pointer;

View File

@ -1,11 +1,10 @@
var Expr = require ('./expr'); var Expr = require('./expr');
/** /**
* The equivalent of a SQL value. * The equivalent of a SQL value.
**/ **/
module.exports = new Class module.exports = new Class({
({
Extends: Expr Extends: Expr
,Tag: 'sql-value' ,Tag: 'sql-value'
@ -17,13 +16,11 @@ module.exports = new Class
param: param:
{ {
type: Vn.Param type: Vn.Param
,set: function (x) ,set: function(x) {
{ this.link({_param: x}, {'changed': this.onParamChange});
this.link ({_param: x}, {'changed': this.onParamChange}); this.onParamChange();
this.onParamChange ();
} }
,get: function () ,get: function() {
{
return this._param; return this._param;
} }
}, },
@ -33,27 +30,24 @@ module.exports = new Class
value: value:
{ {
type: String type: String
,set: function (x) ,set: function(x) {
{ if (Vn.Value.compare(x, this._value))
if (Vn.Value.compare (x, this._value))
return; return;
if (x instanceof Date) if (x instanceof Date)
x = x.clone (); x = x.clone();
this._value = x; this._value = x;
if (this._param && !this.paramLock) if (this._param && !this.paramLock) {
{
this.paramLock = true; this.paramLock = true;
this._param.value = x; this._param.value = x;
this.paramLock = false; this.paramLock = false;
} }
this.signalEmit ('changed'); this.signalEmit('changed');
} }
,get: function () ,get: function() {
{
return this._value; return this._value;
} }
} }
@ -61,11 +55,10 @@ module.exports = new Class
,_value: undefined ,_value: undefined
,_param: null ,_param: null
,regexp: new RegExp ('(\\\\)|\'', 'g') ,regexp: new RegExp('(\\\\)|\'', 'g')
,paramLock: false ,paramLock: false
,onParamChange: function () ,onParamChange: function() {
{
if (this.paramLock || !this._param) if (this.paramLock || !this._param)
return; return;
@ -74,15 +67,12 @@ module.exports = new Class
this.paramLock = false; this.paramLock = false;
} }
,isReady: function () ,isReady: function() {
{
return this._value !== undefined; return this._value !== undefined;
} }
,replaceFunc: function (token) ,replaceFunc: function(token) {
{ switch (token) {
switch (token)
{
case '\\': return '\\\\'; case '\\': return '\\\\';
case '\'': return '\\\''; case '\'': return '\\\'';
} }
@ -90,23 +80,25 @@ module.exports = new Class
return token; return token;
} }
,render: function (batch) ,render: function() {
{
var v = this._value; var v = this._value;
switch (typeof v) switch (typeof v) {
{
case 'number': case 'number':
return v; return v;
case 'boolean': case 'boolean':
return (v) ? 'TRUE' : 'FALSE'; return (v) ? 'TRUE' : 'FALSE';
case 'string': case 'string':
return "'" + v.replace (this.regexp, this.replaceFunc) + "'"; return "'" + v.replace(this.regexp, this.replaceFunc) + "'";
case 'object':
if (v instanceof Date)
return Vn.Date.strftime (v, '\'%Y-%m-%d\'');
default: 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'; return 'NULL';
} }
} }
}
}); });

View File

@ -1,6 +1,6 @@
{ {
"name": "hedera-web", "name": "hedera-web",
"version": "1.407.11", "version": "1.407.12",
"description": "Verdnatura web page", "description": "Verdnatura web page",
"license": "GPL-3.0", "license": "GPL-3.0",
"repository": { "repository": {

View File

@ -8,6 +8,18 @@ class Query extends Vn\Web\JsonRequest {
const PARAMS = ['sql']; const PARAMS = ['sql'];
const SECURITY = Security::INVOKER; 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) { function run($db) {
$results = []; $results = [];
@ -151,7 +163,10 @@ class Query extends Vn\Web\JsonRequest {
* Transforms the database value into a JSON parseable value. * Transforms the database value into a JSON parseable value.
**/ **/
function castValue($value, $type) { function castValue($value, $type) {
if ($value !== NULL) if ($value == '' && $type != Type::STRING)
$value = NULL;
if (!empty($value))
switch ($type) { switch ($type) {
case Type::BOOLEAN: case Type::BOOLEAN:
return (bool) $value; return (bool) $value;
@ -161,14 +176,9 @@ class Query extends Vn\Web\JsonRequest {
return (float) $value; return (float) $value;
case Type::DATE: case Type::DATE:
case Type::DATE_TIME: case Type::DATE_TIME:
return mktime( $d = new DateTime($value, $this->tz);
substr($value, 11 , 2) $d->setTimeZone($this->utcTz);
,substr($value, 14 , 2) return $d->format('Y-m-d\TH:i:s.v\Z');
,substr($value, 17 , 2)
,substr($value, 5 , 2)
,substr($value, 8 , 2)
,substr($value, 0 , 4)
);
break; break;
} }