Source for file postgresql.php
Documentation is available at postgresql.php
* dbscript for PHP 4 & 5 - restful crud framework
* @version 0.1.2 -- 19-Feb-2007
* @author Brian Hendrickson <brian@dbscript.net>
* @link http://dbscript.net/
* @copyright Copyright 2007 Brian Hendrickson
* @license http://www.opensource.org/licenses/mit-license.php MIT License
* adapter for the PostgreSQL database system
* $db = new PostgreSQL ( 'hostname', 'database_name', 'username', 'password' );
* {@link http://dbscript.net/postgresql}
* @author Brian Hendrickson <brian@dbscript.net>
* @todo support array datatypes
'double precision' => 'float',
'serial primary key' => 'int',
'character varying' => 'char',
'timestamp without time zone' => 'time',
'timestamp with time zone' => 'time',
'time without time zone' => 'time',
'time with time zone' => 'time',
$argnames = array('host','dbname','user','password','port');
$this->alias_array = array();
for ($i = 0; $i < count($func_args); $i++ ) {
if (strlen($func_args[$i]) > 0)
$this->connstr .= $argnames[$i] . '=' . $func_args[$i] . ' ';
function connect() { // establish a connection to the database
if (!(strlen($string) > 0)) { return ""; }
function get_result( $sql, $returnfalse = NULL ) { /* run an SQL query */
if (isset ($request->params)) {
$request->set_param( 'currentquery', $sql );
if (!$result && $returnfalse === NULL)
elseif (!$result && $returnfalse)
if ($sequence_name == NULL) {
$sql = "SELECT relname FROM pg_class WHERE relkind='S' and substr(relname,1,". strlen($table). ")='$table'";
$pk_result = $this->get_result("SELECT nextval('$seq')");
function last_insert_id(&$result,$pkfield,$table) { // returns the id of the most recently modified record
$sql = "SELECT ". $pkfield . " FROM " . $table . " WHERE oid = " . $oid;
function result_value(&$result,$resultindex,$field) { // get a single value from a result set
if (!$return && $return != 0)
if ( isset ( $args[0] ) ) {
header( "Location:" . $args[0] );
if ( isset ( $this->models[$table] ) )
require_once $data_model;
function &model($model) {
return " LIMIT " . $limit . " OFFSET " . $offset;
$sql = "INSERT INTO " . $rec->table . " (";
foreach (array_unique($rec->modified_fields) AS $modified_field) {
$this->pre_insert( $rec, $modified_field, $datatype );
if ( !( $datatype == 'blob' && ( !(strlen( $rec->attributes[$modified_field] ) > 0 ) ) ) ) {
$fields .= $comma . $modified_field;
$sql .= $fields . ") VALUES (" . $values . ")";
$sql .= $rec->table . ' SET ';
foreach (array_unique($rec->modified_fields) AS $modified_field) {
$this->pre_update( $rec, $modified_field, $datatype );
if ( !( $datatype == 'blob' && ( !(strlen( $rec->attributes[$modified_field] ) > 0 ) ) ) ) {
$sql .= " WHERE " . $rec->primary_key . "='" . $rec->attributes[$rec->primary_key] . "'";
return "SELECT ". $rec->selecttext. " FROM ". $rec->table. " WHERE ". $rec->primary_key. " = '". $id. "'";
$pkfield = $rec->primary_key;
foreach ($rec->attributes as $key=> $value) {
if ($datatype == 'blob' && strlen($rec->attributes[$rec->primary_key]) > 0) {
$oid_result = $this->get_result("select ". $key. " from ". $rec->table. " where ". $rec->primary_key. " = '". $rec->attributes[$rec->primary_key]. "'");
if (isset ($prev_oid[0]) && $prev_oid[0] > 0)
$sql = 'DELETE FROM ' . $rec->table . ' WHERE ' . $pkfield . ' = ' . $rec->$pkfield;
return "SELECT DISTINCT $field, " . $this->models[$table]->primary_key . " FROM $table ORDER BY $orderby DESC";
return $modified_field . "='" . $this->escape_string($rec->attributes[$modified_field]) . "'";
return "'" . $this->escape_string($rec->attributes[$modified_field]) . "'";
function pre_insert( &$rec, $modified_field, $datatype ) {
if (isset ($this->models[$rec->table]->field_attrs[$modified_field]['required'])) {
if (!(strlen( $rec->attributes[$modified_field] ) > 0))
trigger_error( "$modified_field is a required field", E_USER_ERROR );
if (isset ($this->models[$rec->table]->field_attrs[$modified_field]['unique'])) {
$result = $this->get_result("select ". $modified_field. " from ". $rec->table. " where ". $modified_field. " = '". $rec->attributes[$modified_field]. "'");
trigger_error( "$modified_field must be unique!", E_USER_ERROR );
if ($datatype == 'time' && !(strlen($rec->attributes[$modified_field]) > 0))
$rec->attributes[$modified_field] = date("Y-m-d H:i:s",strtotime("now"));
if ($datatype == 'blob' && strlen($rec->attributes[$modified_field]) > 0) {
$rec->attributes[$modified_field] = $oid;
if ($datatype == 'bool') {
$rec->attributes[$modified_field] = "true";
$rec->attributes[$modified_field] = "false";
if ($modified_field == $rec->primary_key) {
if ( in_array( $rec->attributes[$rec->primary_key], array( '', 0, '0' ), true ))
$rec->attributes[$modified_field] = $this->next_primary_key( $rec->table, $modified_field);
function pre_update( &$rec, $modified_field, $datatype ) {
if (isset ($this->models[$rec->table]->field_attrs[$modified_field]['required'])) {
if (!(strlen( $rec->attributes[$modified_field] ) > 0))
trigger_error( "$modified_field is a required field", E_USER_ERROR );
if (isset ($this->models[$rec->table]->field_attrs[$modified_field]['unique'])) {
$result = $this->get_result("select ". $modified_field. " from ". $rec->table. " where ". $modified_field. " = '". $rec->attributes[$modified_field]. "' and ". $rec->primary_key. " != '". $rec->attributes[$rec->primary_key]. "'");
trigger_error( "$modified_field must be unique!", E_USER_ERROR );
if ($datatype == 'blob' && (strlen( $rec->attributes[$modified_field] ) > 0 )) {
$oid_result = $this->get_result("select ". $modified_field. " from ". $rec->table. " where ". $rec->primary_key. " = '". $rec->attributes[$rec->primary_key]. "'");
if (isset ($prev_oid[0]) && $prev_oid[0] > 0)
$rec->attributes[$modified_field] = $oid;
if (!$result) { trigger_error("Sorry, the record could not be saved due to a database error.", E_USER_ERROR ); }
if (!$filename) { trigger_error("Error determining base name of large object file $filename", E_USER_ERROR ); }
$handle = fopen($file,"r");
if (!$handle) { trigger_error("Error opening large object file $file", E_USER_ERROR ); }
if (!$buffer) { trigger_error("Error reading large object file $file", E_USER_ERROR ); }
#$result = pg_query($this->conn,"UPDATE $table SET $field = $oid WHERE $pkfield = '$pkvalue'");
#if (!$result) { trigger_error("Error updating file OID", E_USER_ERROR ); }
//$result = pg_query($this->conn,"SELECT $field FROM $table WHERE $");
//if (!$result) { trigger_error("Error in select file OID", E_USER_ERROR ); }
//$oid = pg_result($result,0,$fieldname);
//if (!$oid) { trigger_error("Error in file OID result", E_USER_ERROR ); }
#$result = pg_query($this->conn,"SELECT $field FROM $table WHERE $pkfield = '$pkvalue'");
#if (!$result) { trigger_error("Error in select file OID", E_USER_ERROR ); }
#$oid = pg_result($result,0,$field);
#if (!$oid) { trigger_error("Error in file OID result", E_USER_ERROR ); }
#$result = pg_query($this->conn,"DELETE FROM $table WHERE lo_oid = $oid");
#if (!$result) { trigger_error("Error deleting file OID", E_USER_ERROR ); }
if (!(count($field_array)> 0)) trigger_error( "Error creating table. No fields are defined. Use \$model->auto_field and \$model->text_field etc.", E_USER_ERROR );
$sql = "CREATE TABLE $table (";
foreach ( $field_array as $field => $data_type ) {
$sql .= "$comma $field $data_type";
function add_field( $table, $field, $data_type ) {
$sql = "ALTER TABLE $table ADD COLUMN $field $data_type";
#$sql = "SELECT a.relname AS Name FROM pg_class a, pg_user b ";
#$sql .= "WHERE ( relkind = 'r') and relname !~ '^pg_' AND relname !~ '^sql_' ";
#$sql .= "AND relname !~ '^xin[vx][0-9]+' AND b.usesysid = a.relowner ";
#$sql .= "AND NOT (EXISTS (SELECT viewname FROM pg_views WHERE viewname=a.relname))";
$sql = "SELECT tablename AS relname FROM pg_catalog.pg_tables";
$sql .= " WHERE schemaname NOT IN ('pg_catalog', 'information_schema',";
$sql .= " 'pg_toast') ORDER BY tablename";
foreach($arr as $key=> $value) {
#$sql = "SELECT column_name, data_type FROM information_schema.columns ";
#$sql .= "WHERE table_schema = 'public' AND table = '$table'";
$sql = "SELECT a.attname, pg_catalog.format_type(a.atttypid, a.atttypmod)";
$sql .= " as type FROM pg_catalog.pg_attribute a LEFT JOIN";
$sql .= " pg_catalog.pg_attrdef adef ON a.attrelid=adef.adrelid AND";
$sql .= " a.attnum=adef.adnum LEFT JOIN pg_catalog.pg_type t ON";
$sql .= " a.atttypid=t.oid WHERE a.attrelid = (SELECT oid FROM";
$sql .= " pg_catalog.pg_class WHERE relname='$table')";
$sql .= " and a.attname != 'tableoid' and a.attname != 'oid'";
$sql .= " and a.attname != 'xmax' and a.attname != 'xmin'";
$sql .= " and a.attname != 'cmax' and a.attname != 'cmin'";
$sql .= " and a.attname != 'ctid' and a.attname != 'otre'";
$sql .= " and a.attname not ilike '%..%' order by a.attnum ASC";
if (!$result) return $datatypes;
foreach($arr as $key=> $value) {
} elseif ($key == "type") {
$datatypes[$field] = $type;
$sql = "SELECT idx.indkey, idx.indisunique, idx.indisprimary";
$sql .= " FROM pg_catalog.pg_class c, pg_catalog.pg_class c2,";
$sql .= " pg_catalog.pg_index idx";
$sql .= " WHERE c.oid = idx.indrelid";
$sql .= " AND idx.indexrelid = c2.oid";
$sql .= " AND c.relname = '$table'";
#$sql .= " AND idx.isprimary = true";
$datatypes[$table. "_primary_key"] = $fieldindex[$row[0]];
* data model for a single PostgreSQL table
* $people = $db->get_table( 'people' );
* {@link http://dbscript.net/postgresqltable}
* @author Brian Hendrickson <brian@dbscript.net>
$db->models[$table] = & $this;
$this->params = array('resource'=> $table);
$this->set_field( $field, "serial primary key" );
$this->set_field( $field, "double precision" );
$this->set_field( $field, "timestamp with time zone" );
function get_query( $id= NULL, $find_by= NULL ) {
$sql .= "$table.$pkfield as \"$table.$pkfield\", " . "\n";
foreach ($this->field_array as $fieldname=> $datatypename) {
if (!(!(strpos($fieldname,".") === false)))
$fieldname = $table . "." . $fieldname;
$fieldstring .= "$fieldname as \"$fieldname\", " . "\n";
if (count($relfields) > 0) {
foreach ($relfields as $key=> $val) {
$spl = split("\.",$val["fkey"]);
if (($val["type"] != 'child-many') && isset ($db->models[$spl[0]]))
foreach ($relfields as $key=> $val) {
$spl = split("\.",$val["fkey"]);
if (($val["type"] == 'child-many') || !(isset ($db->models[$spl[0]]))) {
foreach ($db->models[$spl[0]]->field_array as $fieldname=> $datatypename) {
$fieldstring .= $spl[0]. ".". $fieldname. " as \"". $spl[0]. ".". $fieldname. "\", " . "\n";
$leftsql .= " left join " . $spl[0] . " on ". $table. ".". $val["col"]. " = " . $val["fkey"];
$fieldstring = substr($fieldstring,0,- 3) . " " . "\n";
$sql .= " WHERE $table.$find_by = '$id' ";
$this->orderby = $table . "." . $pkfield;
if (!(isset ($this->order)))
if (!(isset ($this->limit)))
$sql .= " ORDER BY " . $this->orderby . " ";
|