69 parent::__construct();
71 $this->phptype =
'pgsql';
72 $this->dbsyntax =
'pgsql';
74 $this->supported[
'sequences'] =
true;
75 $this->supported[
'indexes'] =
true;
76 $this->supported[
'affected_rows'] =
true;
77 $this->supported[
'summary_functions'] =
true;
78 $this->supported[
'order_by_text'] =
true;
79 $this->supported[
'transactions'] =
true;
80 $this->supported[
'savepoints'] =
true;
81 $this->supported[
'current_id'] =
true;
82 $this->supported[
'limit_queries'] =
true;
83 $this->supported[
'LOBs'] =
true;
84 $this->supported[
'replace'] =
'emulated';
85 $this->supported[
'sub_selects'] =
true;
86 $this->supported[
'auto_increment'] =
'emulated';
87 $this->supported[
'primary_key'] =
true;
88 $this->supported[
'result_introspection'] =
true;
89 $this->supported[
'prepared_statements'] =
true;
90 $this->supported[
'identifier_quoting'] =
true;
91 $this->supported[
'pattern_escaping'] =
true;
92 $this->supported[
'new_link'] =
true;
94 $this->options[
'multi_query'] =
false;
113 if (is_resource(
$error)) {
114 $native_msg = @pg_result_error(
$error);
115 } elseif ($this->connection) {
116 $native_msg = @pg_last_error($this->connection);
117 if (!$native_msg && @pg_connection_status($this->connection) === PGSQL_CONNECTION_BAD) {
118 $native_msg =
'Database connection has been lost.';
123 static $error_regexps;
124 if (empty($error_regexps)) {
125 $error_regexps =
array(
126 '/column .* (of relation .*)?does not exist/i' 128 '/(relation|sequence|table).*does not exist|class .* not found/i' 130 '/index .* does not exist/' 132 '/relation .* already exists/i' 134 '/(divide|division) by zero$/i' 136 '/pg_atoi: error in .*: can\'t parse /i' 138 '/invalid input syntax for( type)? (integer|numeric)/i' 140 '/value .* is out of range for type \w*int/i' 142 '/integer out of range/i' 144 '/value too long for type character/i' 146 '/attribute .* not found|relation .* does not have attribute/i' 148 '/column .* specified in USING clause does not exist in (left|right) table/i' 150 '/parser: parse error at or near/i' 154 '/column reference .* is ambiguous/i' 156 '/permission denied/' 158 '/violates not-null constraint/' 160 '/violates [\w ]+ constraint/' 162 '/referential integrity violation/' 164 '/more expressions than target columns/i' 171 foreach ($error_regexps as $regexp =>
$code) {
172 if (preg_match($regexp, $native_msg)) {
178 return array($error_code, null, $native_msg);
197 if ($escape_wildcards) {
204 if (version_compare(PHP_VERSION,
'5.2.0RC5',
'>=')) {
225 $this->
debug(
'Starting transaction/savepoint', __FUNCTION__,
array(
'is_manip' =>
true,
'savepoint' => $savepoint));
226 if (!is_null($savepoint)) {
227 if (!$this->in_transaction) {
229 'savepoint cannot be released when changes are auto committed', __FUNCTION__);
231 $query =
'SAVEPOINT '.$savepoint;
233 } elseif ($this->in_transaction) {
236 if (!$this->destructor_registered && $this->opened_persistent) {
237 $this->destructor_registered =
true;
238 register_shutdown_function(
'MDB2_closeOpenTransactions');
244 $this->in_transaction =
true;
264 $this->
debug(
'Committing transaction/savepoint', __FUNCTION__,
array(
'is_manip' =>
true,
'savepoint' => $savepoint));
265 if (!$this->in_transaction) {
267 'commit/release savepoint cannot be done changes are auto committed', __FUNCTION__);
269 if (!is_null($savepoint)) {
270 $query =
'RELEASE SAVEPOINT '.$savepoint;
278 $this->in_transaction =
false;
298 $this->
debug(
'Rolling back transaction/savepoint', __FUNCTION__,
array(
'is_manip' =>
true,
'savepoint' => $savepoint));
299 if (!$this->in_transaction) {
301 'rollback cannot be done changes are auto committed', __FUNCTION__);
303 if (!is_null($savepoint)) {
304 $query =
'ROLLBACK TO SAVEPOINT '.$savepoint;
313 $this->in_transaction =
false;
335 $this->
debug(
'Setting transaction isolation level', __FUNCTION__,
array(
'is_manip' =>
true));
336 switch ($isolation) {
337 case 'READ UNCOMMITTED':
338 case 'READ COMMITTED':
339 case 'REPEATABLE READ':
344 'isolation level is not supported: '.$isolation, __FUNCTION__);
347 $query =
"SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL $isolation";
366 $protocol = $this->dsn[
'protocol'] ? $this->dsn[
'protocol'] :
'tcp';
369 if ($protocol ==
'tcp') {
370 if ($this->dsn[
'hostspec']) {
371 $params[0].=
'host=' . $this->dsn[
'hostspec'];
373 if ($this->dsn[
'port']) {
374 $params[0].=
' port=' . $this->dsn[
'port'];
376 } elseif ($protocol ==
'unix') {
378 if ($this->dsn[
'socket']) {
379 $params[0].=
'host=' . $this->dsn[
'socket'];
381 if ($this->dsn[
'port']) {
382 $params[0].=
' port=' . $this->dsn[
'port'];
388 if ($this->dsn[
'username']) {
389 $params[0].=
' user=\'' . addslashes($this->dsn[
'username']) .
'\'';
391 if ($this->dsn[
'password']) {
392 $params[0].=
' password=\'' . addslashes($this->dsn[
'password']) .
'\'';
394 if (!empty($this->dsn[
'options'])) {
395 $params[0].=
' options=' . $this->dsn[
'options'];
397 if (!empty($this->dsn[
'tty'])) {
398 $params[0].=
' tty=' . $this->dsn[
'tty'];
400 if (!empty($this->dsn[
'connect_timeout'])) {
401 $params[0].=
' connect_timeout=' . $this->dsn[
'connect_timeout'];
403 if (!empty($this->dsn[
'sslmode'])) {
404 $params[0].=
' sslmode=' . $this->dsn[
'sslmode'];
406 if (!empty($this->dsn[
'service'])) {
407 $params[0].=
' service=' . $this->dsn[
'service'];
410 if (!empty($this->dsn[
'new_link'])
411 && ($this->dsn[
'new_link'] ==
'true' || $this->dsn[
'new_link'] ===
true))
413 if (version_compare(phpversion(),
'4.3.0',
'>=')) {
414 $params[] = PGSQL_CONNECT_FORCE_NEW;
418 $connect_function = $persistent ?
'pg_pconnect' :
'pg_connect';
423 'unable to establish a connection', __FUNCTION__);
426 if (empty($this->dsn[
'disable_iso_date'])) {
427 if (!@pg_query(
$connection,
"SET SESSION DATESTYLE = 'ISO'")) {
429 'Unable to set date style to iso', __FUNCTION__);
433 if (!empty($this->dsn[
'charset'])) {
454 if (is_resource($this->connection)) {
455 if (count(array_diff($this->connected_dsn, $this->dsn)) == 0
456 && $this->connected_database_name == $this->database_name
457 && ($this->opened_persistent == $this->options[
'persistent'])
466 'extension '.$this->phptype.
' is not compiled into PHP', __FUNCTION__);
469 if ($this->database_name) {
477 $this->opened_persistent = $this->options[
'persistent'];
478 $this->dbsyntax = $this->dsn[
'dbsyntax'] ? $this->dsn[
'dbsyntax'] :
$this->phptype;
506 'Unable to set client charset: '.$charset, __FUNCTION__);
525 if (is_resource($this->connection)) {
526 if ($this->in_transaction) {
529 $persistent = $this->options[
'persistent'];
536 $this->options[
'persistent'] = $persistent;
539 if (!$this->opened_persistent || $force) {
540 @pg_close($this->connection);
543 return parent::disconnect($force);
564 'Cannot connect to template1', __FUNCTION__);
570 $this->offset = $this->limit = 0;
581 return $affected_rows;
601 $this->last_query =
$query;
609 if ($this->options[
'disable_query']) {
610 $result = $is_manip ? 0 : null;
621 $function = $this->options[
'multi_query'] ?
'pg_send_query' :
'pg_query';
625 'Could not execute statement', __FUNCTION__);
627 } elseif ($this->options[
'multi_query']) {
630 'Could not get the first result from a multi query', __FUNCTION__);
658 return @pg_affected_rows(
$result);
677 && !preg_match(
'/LIMIT\s*\d(?:\s*(?:,|OFFSET)\s*\d+)?(?:[^\)]*)?$/i',
$query)
680 if (substr(
$query, -1) ==
';') {
686 $query.=
" LIMIT $limit OFFSET $offset";
705 $pos = strpos(strtolower(
$query),
'where');
706 $where = $pos ? substr(
$query, $pos) :
'';
708 $manip_clause =
'(\bDELETE\b\s+(?:\*\s+)?\bFROM\b|\bUPDATE\b)';
709 $from_clause =
'([\w\.]+)';
710 $where_clause =
'(?:(.*)\bWHERE\b\s+(.*))|(.*)';
711 $pattern =
'/^'. $manip_clause .
'\s+' . $from_clause .
'(?:\s)*(?:'. $where_clause .
')?$/i';
712 $matches = preg_match($pattern,
$query, $match);
716 $what = (count($matches) == 6) ? $match[5] : $match[3];
717 return $manip.
' '.$from.
' '.$what.
' WHERE ctid=(SELECT ctid FROM '.$from.
' '.$where.
' LIMIT '.
$limit.
')';
735 $query =
'SHOW SERVER_VERSION';
736 if ($this->connected_server_info) {
745 $this->connected_server_info = $server_info;
747 $tmp = explode(
'.', $server_info, 3);
750 && preg_match(
'/(\d+)(.*)/', $tmp[1], $tmp2)
752 $server_info =
array(
757 'native' => $server_info,
760 $server_info =
array(
761 'major' => isset($tmp[0]) ? $tmp[0] : null,
762 'minor' => isset($tmp[1]) ? $tmp[1] : null,
763 'patch' => isset($tmp[2]) ? $tmp[2] : null,
765 'native' => $server_info,
797 if ($this->options[
'emulate_prepared']) {
798 $obj =& parent::prepare(
$query, $types, $result_types, $lobs);
804 $this->offset = $this->limit = 0;
812 $pgtypes = function_exists(
'pg_prepare') ? false :
array();
813 if ($pgtypes !==
false && !empty($types)) {
817 $placeholder_type_guess = $placeholder_type = null;
820 $positions =
array();
821 $position = $parameter = 0;
822 while ($position < strlen(
$query)) {
823 $q_position = strpos(
$query, $question, $position);
824 $c_position = strpos(
$query, $colon, $position);
825 if ($q_position && $c_position) {
826 $p_position = min($q_position, $c_position);
827 } elseif ($q_position) {
828 $p_position = $q_position;
829 } elseif ($c_position) {
830 $p_position = $c_position;
834 if (is_null($placeholder_type)) {
835 $placeholder_type_guess =
$query[$p_position];
842 if ($new_pos != $position) {
843 $position = $new_pos;
847 if (
$query[$position] == $placeholder_type_guess) {
848 if (is_null($placeholder_type)) {
849 $placeholder_type =
$query[$p_position];
850 $question = $colon = $placeholder_type;
851 if (!empty($types) && is_array($types)) {
852 if ($placeholder_type ==
':') {
854 $types = array_values($types);
858 if ($placeholder_type_guess ==
'?') {
862 $name = preg_replace(
'/^.{'.($position+1).
'}([a-z0-9_]+).*$/si',
'\\1',
$query);
865 'named parameter with an empty name', __FUNCTION__);
868 $length = strlen($name) + 1;
870 if ($pgtypes !==
false) {
871 if (is_array($types) && array_key_exists($name, $types)) {
872 $pgtypes[] = $this->datatype->mapPrepareDatatype($types[$name]);
873 } elseif (is_array($types) && array_key_exists($parameter, $types)) {
874 $pgtypes[] = $this->datatype->mapPrepareDatatype($types[$parameter]);
879 if (($key_parameter = array_search($name, $positions))) {
881 foreach ($positions as $key => $value) {
882 if ($key_parameter == $key) {
889 $next_parameter = $parameter;
890 $positions[] = $name;
892 $query = substr_replace(
$query,
'$'.$parameter, $position, $length);
893 $position = $p_position + strlen($parameter);
895 $position = $p_position;
903 $statement_name = sprintf($this->options[
'statement_format'], $this->phptype, md5(
time() + rand()));
904 $statement_name = strtolower($statement_name);
905 if ($pgtypes ===
false) {
909 'Unable to create prepared statement handle', __FUNCTION__);
915 $types_string =
' ('.implode(
', ', $pgtypes).
') ';
917 $query =
'PREPARE '.$statement_name.$types_string.
' AS '.
$query;
924 $class_name =
'MDB2_Statement_'.$this->phptype;
925 $obj =
new $class_name($this, $statement_name, $positions,
$query, $types, $result_types, $is_manip,
$limit,
$offset);
926 $this->
debug(
$query, __FUNCTION__,
array(
'is_manip' => $is_manip,
'when' =>
'post',
'result' => $obj));
944 list($table, $field) = explode(
'_', $sqn);
945 $query =
"SELECT substring((SELECT substring(pg_get_expr(d.adbin, d.adrelid) for 128) 947 WHERE d.adrelid = a.attrelid 948 AND d.adnum = a.attnum 950 ) FROM 'nextval[^\']*\'([^\']*)') 952 LEFT JOIN pg_class c ON c.oid = a.attrelid 953 LEFT JOIN pg_attrdef d ON d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef 954 WHERE (c.relname = ".$this->quote($sqn,
'text');
955 if (!empty($field)) {
956 $query .=
" OR (c.relname = ".$this->quote($table,
'text').
" AND a.attname = ".$this->
quote($field,
'text').
")";
959 AND NOT a.attisdropped 961 AND pg_get_expr(d.adbin, d.adrelid) LIKE 'nextval%' 964 if (!
PEAR::isError($seqname) && !empty($seqname) && is_string($seqname)) {
968 return sprintf($this->options[
'seqname_format'],
969 preg_replace(
'/[^\w\$.]/i',
'_', $sqn));
985 function nextID($seq_name, $ondemand =
true)
988 $query =
"SELECT NEXTVAL('$sequence_name')";
995 $result = $this->manager->createSequence($seq_name);
998 'on demand sequence could not be created', __FUNCTION__);
1000 return $this->nextId($seq_name,
false);
1020 if (empty($table) && empty($field)) {
1021 return $this->
queryOne(
'SELECT lastval()',
'integer');
1023 $seq = $table.(empty($field) ?
'' :
'_'.$field);
1025 return $this->
queryOne(
"SELECT currval('$sequence_name')",
'integer');
1041 return $this->
queryOne(
"SELECT last_value FROM $sequence_name",
'integer');
1067 if (!is_null($rownum)) {
1068 $seek = $this->seek($rownum);
1077 $row = @pg_fetch_array($this->result, null, PGSQL_ASSOC);
1081 $row = array_change_key_case(
$row, $this->db->options[
'field_case']);
1084 $row = @pg_fetch_row($this->result);
1087 if ($this->result ===
false) {
1089 'resultset has already been freed', __FUNCTION__);
1098 if (empty($this->types)) {
1105 $this->db->_fixResultArrayValues(
$row, $mode);
1107 if (!empty($this->types)) {
1108 $row = $this->db->datatype->convertResultRow($this->types,
$row, $rtrim);
1110 if (!empty($this->values)) {
1111 $this->_assignBindColumns(
$row);
1114 $object_class = $this->db->options[
'fetch_class'];
1115 if ($object_class ==
'stdClass') {
1140 $numcols = $this->numCols();
1145 $column_name = @pg_field_name($this->result,
$column);
1149 $columns = array_change_key_case(
$columns, $this->db->options[
'field_case']);
1166 $cols = @pg_num_fields($this->result);
1167 if (is_null($cols)) {
1168 if ($this->result ===
false) {
1170 'resultset has already been freed', __FUNCTION__);
1171 } elseif (is_null($this->result)) {
1172 return count($this->types);
1174 return $this->db->raiseError(null, null, null,
1175 'Could not get column count', __FUNCTION__);
1196 if (!($this->result = @pg_get_result(
$connection))) {
1213 if (is_resource($this->result) && $this->db->connection) {
1214 $free = @pg_free_result($this->result);
1215 if ($free ===
false) {
1216 return $this->db->raiseError(null, null, null,
1217 'Could not free result', __FUNCTION__);
1220 $this->result =
false;
1245 if ($this->rownum != ($rownum - 1) && !@pg_result_seek($this->result, $rownum)) {
1246 if ($this->result ===
false) {
1248 'resultset has already been freed', __FUNCTION__);
1249 } elseif (is_null($this->result)) {
1253 'tried to seek to an invalid row number ('.$rownum.
')', __FUNCTION__);
1255 $this->rownum = $rownum - 1;
1270 $numrows = $this->numRows();
1274 return $this->rownum < ($numrows - 1);
1288 $rows = @pg_num_rows($this->result);
1289 if (is_null($rows)) {
1290 if ($this->result ===
false) {
1292 'resultset has already been freed', __FUNCTION__);
1293 } elseif (is_null($this->result)) {
1296 return $this->db->raiseError(null, null, null,
1297 'Could not get row count', __FUNCTION__);
1322 function &
_execute($result_class =
true, $result_wrap_class =
false)
1324 if (is_null($this->statement)) {
1325 $result =& parent::_execute($result_class, $result_wrap_class);
1329 $this->db->debug($this->
query,
'execute',
array(
'is_manip' => $this->is_manip,
'when' =>
'pre',
'parameters' => $this->values));
1330 if ($this->db->getOption(
'disable_query')) {
1331 $result = $this->is_manip ? 0 : null;
1341 $parameters =
array();
1343 if (
true || !function_exists(
'pg_execute')) {
1344 $query =
'EXECUTE '.$this->statement;
1346 if (!empty($this->positions)) {
1347 foreach ($this->positions as $parameter) {
1348 if (!array_key_exists($parameter, $this->values)) {
1350 'Unable to bind to missing placeholder: '.$parameter, __FUNCTION__);
1352 $value = $this->values[$parameter];
1353 $type = array_key_exists($parameter, $this->types) ? $this->types[$parameter] : null;
1354 if (is_resource($value) || $type ==
'clob' || $type ==
'blob') {
1355 if (!is_resource($value) && preg_match(
'/^(\w+:\/\/)(.*)$/', $value, $match)) {
1356 if ($match[1] ==
'file://') {
1359 $value = @fopen($value,
'r');
1362 if (is_resource($value)) {
1364 while (!@feof($value)) {
1365 $data.= @fread($value, $this->db->options[
'lob_buffer_length']);
1373 $parameters[] = $this->db->quote($value, $type,
$query);
1376 $query.=
' ('.implode(
', ', $parameters).
')';
1383 $err =& $this->db->raiseError(null, null, null,
1384 'Unable to execute statement', __FUNCTION__);
1394 if ($this->is_manip) {
1396 return $affected_rows;
1400 $result_class, $result_wrap_class, $this->limit, $this->offset);
1401 $this->db->debug($this->
query,
'execute',
array(
'is_manip' => $this->is_manip,
'when' =>
'post',
'result' =>
$result));
1416 if (is_null($this->positions)) {
1417 return $this->db->raiseError(
MDB2_ERROR, null, null,
1418 'Prepared statement has already been freed', __FUNCTION__);
1422 if (!is_null($this->statement)) {
1427 $query =
'DEALLOCATE PREPARE '.$this->statement;
const MDB2_FETCHMODE_ASSOC
Column data indexed by column names.
const MDB2_OK(!class_exists('PEAR'))
The method mapErrorCode in each MDB2_dbtype implementation maps native error codes to one of these...
_doConnect($database_name, $persistent=false)
Does the grunt work of connecting to the database.
commit($savepoint=null)
Commit the database changes done during a transaction that is in progress or release a savepoint...
loadExtension($ext)
OS independant PHP extension load.
const MDB2_FETCHMODE_DEFAULT
This is a special constant that tells MDB2 the user hasn't specified any particular get mode...
const MDB2_ERROR_UNSUPPORTED
numRows()
Returns the number of rows in a result object.
setCharset($charset, $connection=null)
Set the charset on the current connection.
lastInsertID($table=null, $field=null)
Returns the autoincrement ID if supported or $id or fetches the current ID in a sequence called: $tab...
const MDB2_PORTABILITY_EMPTY_TO_NULL
Portability: convert empty values to null strings in data output by query*() and fetch*().
connect()
Connect to the database.
_affectedRows($connection, $result=null)
Returns the number of rows affected.
setTransactionIsolation($isolation)
Set the transacton isolation level.
currID($seq_name)
Returns the current id of a sequence.
errorInfo($error=null)
This method is used to collect information about an error.
quoteIdentifier($str, $check_option=false)
Quote a string so it can be safely used as a table or column name.
& prepare($query, $types=null, $result_types=null, $lobs=array())
Prepares a query for multiple execution with execute().
beginTransaction($savepoint=null)
Start a transaction or set a savepoint.
const MDB2_ERROR_CONSTRAINT
escape($text, $escape_wildcards=false)
Quotes a string so it can be safely used in a query.
const MDB2_ERROR_NOSUCHFIELD
& query($query, $types=null, $result_class=true, $result_wrap_class=false)
Send a query to the database and return any results.
const MDB2_FETCHMODE_OBJECT
Column data as object properties.
debug($message, $scope='', $context=array())
set a debug message
& _wrapResult($result, $types=array(), $result_class=true, $result_wrap_class=false, $limit=null, $offset=null)
wrap a result set into the correct class
_skipDelimitedStrings($query, $position, $p_position)
Utility method, used by prepare() to avoid replacing placeholders within delimited strings...
_modifyQuery($query, $is_manip, $limit, $offset)
Changes a query string for various DBMS specific reasons.
& fetchRow($fetchmode=MDB2_FETCHMODE_DEFAULT, $rownum=null)
Fetch a row and insert the data into an existing array.
const MDB2_PREPARE_MANIP
These are just helper constants to more verbosely express parameters to prepare() ...
& _doQuery($query, $is_manip=false, $connection=null, $database_name=null)
Execute a query.
const MDB2_ERROR_NEED_MORE_DATA
_getColumnNames()
Retrieve the names of columns returned by the DBMS in a query result.
popExpect()
This method pops one element off the expected error codes stack.
const MDB2_PORTABILITY_RTRIM
Portability: right trim the data output by query*() and fetch*().
seek($rownum=0)
Seek to a specific row in a result set.
expectError($code=' *')
This method is used to tell which errors you expect to get.
const MDB2_ERROR_NOT_FOUND
& raiseError($code=null, $mode=null, $options=null, $userinfo=null, $method=null)
This method is used to communicate an error and invoke error callbacks etc.
const MDB2_ERROR_CONNECT_FAILED
const MDB2_ERROR_CONSTRAINT_NOT_NULL
& _execute($result_class=true, $result_wrap_class=false)
Execute a prepared query statement helper method.
Create styles array
The data for the language used.
nextResult()
Move the internal result pointer to the next available result.
const MDB2_ERROR_VALUE_COUNT_ON_ROW
valid()
Check if the end of the result set has been reached.
free()
Free the internal resources associated with result.
getSequenceName($sqn)
adds sequence name formatting to a sequence name
disconnect($force=true)
Log out and disconnect from the database.
numCols()
Count the number of columns returned by the DBMS in a query result.
escapePattern($text)
Quotes pattern (% and _) characters in a string)
const MDB2_ERROR_INVALID_NUMBER
getServerVersion($native=false)
return version information about the server
__construct()
Constructor.
rollback($savepoint=null)
Cancel any database changes done during a transaction or since a specific savepoint that is in progre...
getConnection()
Returns a native connection.
Create new PHPExcel object
obj_idprivate
quote($value, $type=null, $quote=true, $escape_wildcards=false)
Convert a text value into a DBMS specific format that is suitable to compose query statements...
queryOne($query, $type=null, $colnum=0)
Execute the specified query, fetch the value from the first column of the first row of the result set...
const MDB2_ERROR_ACCESS_VIOLATION
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
free()
Release resources allocated for the specified prepared query.
_modifyManipQuery($query, $limit)
Changes a manip query string for various DBMS specific reasons.
& loadModule($module, $property=null, $phptype_specific=null)
loads a module
const MDB2_ERROR_ALREADY_EXISTS
const MDB2_PORTABILITY_FIX_CASE
Portability: convert names of tables and fields to case defined in the "field_case" option when using...
& standaloneQuery($query, $types=null, $is_manip=false)
execute a query as DBA
nextID($seq_name, $ondemand=true)
Returns the next free id of a sequence.
isError($data, $code=null)
Tell whether a value is a PEAR error.
const MDB2_ERROR_NOSUCHTABLE