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'
,'user' => 'hedera-web'
,'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.

View File

@ -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));
}
});

View File

@ -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;

View File

@ -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)
{
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\'');
default:
switch (typeof v) {
case 'number':
return v;
case 'boolean':
return (v) ? 'TRUE' : 'FALSE';
case 'string':
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';
}
}
}
});

View File

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

View File

@ -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;
@ -159,16 +174,11 @@ class Query extends Vn\Web\JsonRequest {
return (int) $value;
case Type::DOUBLE:
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)
);
case Type::DATE:
case Type::DATE_TIME:
$d = new DateTime($value, $this->tz);
$d->setTimeZone($this->utcTz);
return $d->format('Y-m-d\TH:i:s.v\Z');
break;
}