hedera-web/rest/core/query.php

217 lines
4.3 KiB
PHP
Raw Normal View History

<?php
2016-07-22 20:00:27 +00:00
use Vn\Lib;
2016-09-23 22:47:34 +00:00
use Vn\Web\Security;
2016-07-22 20:00:27 +00:00
class Query extends Vn\Web\JsonRequest
{
2016-09-06 14:25:02 +00:00
const PARAMS = ['sql'];
2016-09-23 22:47:34 +00:00
const SECURITY = Security::INVOKER;
2016-09-06 14:25:02 +00:00
function run ($db)
{
$results = [];
try {
2016-09-24 14:32:31 +00:00
$db->multiQuery ($_REQUEST['sql']);
2015-02-08 15:38:38 +00:00
do {
2016-09-24 14:32:31 +00:00
$result = $db->storeResult ();
if ($result !== FALSE)
{
2016-09-06 14:25:02 +00:00
$results[] = $this->transformResult ($result);
$result->free ();
}
else
$results[] = TRUE;
}
2016-09-24 14:32:31 +00:00
while ($db->moreResults () && $db->nextResult ());
2016-09-06 14:25:02 +00:00
2015-08-17 18:02:14 +00:00
// Checks for warnings
2016-09-06 14:25:02 +00:00
2016-09-24 14:32:31 +00:00
if ($db->checkWarnings ()
&& ($result = $db->query ('SHOW WARNINGS')))
2015-08-17 18:02:14 +00:00
{
$sql = 'SELECT description, @warn code '.
'FROM sql_message WHERE code = @warn';
while ($row = $result->fetch_assoc ())
{
if ($row['Code'] == 1265
2016-09-24 14:32:31 +00:00
&& ($warning = $db->getRow ($sql)))
2016-09-19 06:40:18 +00:00
trigger_error ("{$warning['code']}: {$warning['description']}", E_USER_WARNING);
2015-08-17 18:02:14 +00:00
else
2016-09-19 06:40:18 +00:00
trigger_error ("{$row['Code']}: {$row['Message']}", E_USER_WARNING);
2015-08-17 18:02:14 +00:00
}
}
2016-09-06 14:25:02 +00:00
2015-08-17 18:02:14 +00:00
// Checks for errors
2016-09-24 14:32:31 +00:00
$db->checkError ();
}
2016-07-22 20:00:27 +00:00
catch (Vn\Db\Exception $e)
{
2015-08-17 18:02:14 +00:00
$row = NULL;
$code = $e->getCode ();
$message = $e->getMessage ();
switch ($code)
{
case 1644: // ER_SIGNAL_EXCEPTION
{
$sql = 'SELECT description, #code code '.
'FROM sql_message WHERE code = #code';
2016-09-24 14:32:31 +00:00
$row = $db->getRow ($sql, ['code' => $message]);
2015-08-17 18:02:14 +00:00
break;
}
case 1305: // ER_SP_DOES_NOT_EXIST
{
if (strpos ($message, 'EXCEPTION') === FALSE)
break;
$sql = 'SELECT description, @err code '.
'FROM sql_message WHERE code = @err';
2016-09-24 14:32:31 +00:00
$row = $db->getRow ($sql);
2015-08-17 18:02:14 +00:00
break;
}
}
if ($row)
2016-08-25 10:47:09 +00:00
throw new Lib\UserException ($row['description'], $row['code']);
2015-08-17 18:02:14 +00:00
else
throw $e;
}
return $results;
}
2016-09-06 14:25:02 +00:00
/**
2016-09-20 18:36:22 +00:00
* Transforms the database result into a JSON parseable object.
2016-09-06 14:25:02 +00:00
**/
function transformResult ($result)
{
$tableMap = [];
$columns = $result->fetch_fields ();
$resultMap =
[
'data' => [],
'columns' => [],
'tables' => []
];
2015-02-17 11:48:53 +00:00
2016-09-06 14:25:02 +00:00
for ($i = 0; $i < $result->field_count; $i++)
{
$column = $columns[$i];
switch ($column->type)
{
case MYSQLI_TYPE_BIT:
$type = TYPE_BOOLEAN;
break;
case MYSQLI_TYPE_TINY:
case MYSQLI_TYPE_SHORT:
case MYSQLI_TYPE_LONG:
case MYSQLI_TYPE_LONGLONG:
case MYSQLI_TYPE_INT24:
case MYSQLI_TYPE_YEAR:
$type = TYPE_INTEGER;
break;
case MYSQLI_TYPE_FLOAT:
case MYSQLI_TYPE_DOUBLE:
case MYSQLI_TYPE_DECIMAL:
case MYSQLI_TYPE_NEWDECIMAL:
$type = TYPE_DOUBLE;
break;
case MYSQLI_TYPE_DATE:
$type = TYPE_DATE;
break;
case MYSQLI_TYPE_DATETIME:
case MYSQLI_TYPE_TIMESTAMP:
$type = TYPE_DATE_TIME;
break;
default;
$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);
$resultMap['columns'][] =
[
'type' => $type,
'flags' => $column->flags,
'def' => $default,
'name' => $column->name,
'orgname' => $column->orgname,
'table' => $tableIndex
];
}
$columns = $resultMap['columns'];
while ($row = $result->fetch_row ())
{
for ($j = 0; $j < $result->field_count; $j++)
$this->castValue ($row[$j], $columns[$j]['type']);
$resultMap['data'][] = $row;
}
return $resultMap;
}
/**
* Transforms the database value into a JSON parseable value.
**/
2015-02-17 11:48:53 +00:00
function castValue (&$value, $type)
{
if ($value !== NULL)
switch ($type)
{
case TYPE_BOOLEAN:
$value = (bool) $value;
break;
case TYPE_INTEGER:
$value = (int) $value;
break;
case TYPE_DOUBLE:
$value = (float) $value;
break;
case TYPE_DATE:
case TYPE_DATE_TIME:
$value = 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)
);
break;
}
}
2016-09-06 14:25:02 +00:00
}
?>