login (); if (empty ($_REQUEST['sql'])) throw new Lib\Exception (s('EmptyQuery'), 'emptyQuery'); $results = []; try { $db->multiQuery ($_REQUEST['sql']); do { $result = $db->storeResult (); if ($result !== FALSE) { $tableMap = []; $columns = $result->fetch_fields (); $resultMap = [ 'data' => [], 'columns' => [], 'tables' => [] ]; 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; } $results[] = $resultMap; $result->free (); } else $results[] = TRUE; } while ($db->moreResults () && $db->nextResult ()); // Checks for warnings if ($db->checkWarnings () && ($result = $db->query ('SHOW WARNINGS'))) { $sql = 'SELECT description, @warn code '. 'FROM sql_message WHERE code = @warn'; while ($row = $result->fetch_assoc ()) { if ($row['Code'] == 1265 && ($warning = $db->getRow ($sql))) $this->app->addWarning ($warning['description'], $warning['code']); else trigger_error ("${row['Code']}: ${row['Message']}", E_USER_WARNING); } } // Checks for errors $db->checkError (); } catch (Vn\Db\Exception $e) { $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'; $row = $db->getRow ($sql, ['code' => $message]); 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'; $row = $db->getRow ($sql); break; } } if ($row) throw new Lib\Exception ($row['description'], $row['code']); else throw $e; } return $results; } 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; } } } ?>