diff -r 5e1f1e916419 -r 98bbc533541c punbb/include/dblayer/pgsql.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/include/dblayer/pgsql.php Sun Apr 06 00:28:50 2008 -0400 @@ -0,0 +1,376 @@ +prefix = $db_prefix; + + if ($db_host != '') + { + if (strpos($db_host, ':') !== false) + { + list($db_host, $dbport) = explode(':', $db_host); + $connect_str[] = 'host='.$db_host.' port='.$dbport; + } + else + { + if ($db_host != 'localhost') + $connect_str[] = 'host='.$db_host; + } + } + + if ($db_name) + $connect_str[] = 'dbname='.$db_name; + + if ($db_username != '') + $connect_str[] = 'user='.$db_username; + + if ($db_password != '') + $connect_str[] = 'password='.$db_password; + + if ($p_connect) + $this->link_id = @pg_pconnect(implode(' ', $connect_str)); + else + $this->link_id = @pg_connect(implode(' ', $connect_str)); + + if (!$this->link_id) + error('Unable to connect to PostgreSQL server.', __FILE__, __LINE__); + else + return $this->link_id; + } + + + function start_transaction() + { + ++$this->in_transaction; + + return (@pg_query($this->link_id, 'BEGIN')) ? true : false; + } + + + function end_transaction() + { + --$this->in_transaction; + + if (@pg_query($this->link_id, 'COMMIT')) + return true; + else + { + @pg_query($this->link_id, 'ROLLBACK'); + return false; + } + } + + + function query($sql, $unbuffered = false) // $unbuffered is ignored since there is no pgsql_unbuffered_query() + { + if (strlen($sql) > 140000) + exit('Insane query. Aborting.'); + + if (strrpos($sql, 'LIMIT') !== false) + $sql = preg_replace('#LIMIT ([0-9]+),([ 0-9]+)#', 'LIMIT \\2 OFFSET \\1', $sql); + + if (defined('PUN_SHOW_QUERIES')) + $q_start = get_microtime(); + + @pg_send_query($this->link_id, $sql); + $this->query_result = @pg_get_result($this->link_id); + + if (pg_result_status($this->query_result) != PGSQL_FATAL_ERROR) + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, sprintf('%.5f', get_microtime() - $q_start)); + + ++$this->num_queries; + + $this->last_query_text[$this->query_result] = $sql; + + return $this->query_result; + } + else + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array($sql, 0); + + $this->error_msg = @pg_result_error($this->query_result); + + if ($this->in_transaction) + @pg_query($this->link_id, 'ROLLBACK'); + + --$this->in_transaction; + + return false; + } + } + + + function query_build($query, $unbuffered = false) + { + $sql = ''; + + if (isset($query['SELECT'])) + { + $sql = 'SELECT '.$query['SELECT'].' FROM '.(isset($query['PARAMS']['NO_PREFIX']) ? '' : $this->prefix).$query['FROM']; + + if (isset($query['JOINS'])) + { + foreach ($query['JOINS'] as $cur_join) + $sql .= ' '.key($cur_join).' '.(isset($query['PARAMS']['NO_PREFIX']) ? '' : $this->prefix).current($cur_join).' ON '.$cur_join['ON']; + } + + if (!empty($query['WHERE'])) + $sql .= ' WHERE '.$query['WHERE']; + if (!empty($query['GROUP BY'])) + $sql .= ' GROUP BY '.$query['GROUP BY']; + if (!empty($query['HAVING'])) + $sql .= ' HAVING '.$query['HAVING']; + if (!empty($query['ORDER BY'])) + $sql .= ' ORDER BY '.$query['ORDER BY']; + if (!empty($query['LIMIT'])) + $sql .= ' LIMIT '.$query['LIMIT']; + } + else if (isset($query['INSERT'])) + { + $sql = 'INSERT INTO '.(isset($query['PARAMS']['NO_PREFIX']) ? '' : $this->prefix).$query['INTO']; + + if (!empty($query['INSERT'])) + $sql .= ' ('.$query['INSERT'].')'; + + $sql .= ' VALUES('.$query['VALUES'].')'; + } + else if (isset($query['UPDATE'])) + { + $query['UPDATE'] = (isset($query['PARAMS']['NO_PREFIX']) ? '' : $this->prefix).$query['UPDATE']; + + $sql = 'UPDATE '.$query['UPDATE'].' SET '.$query['SET']; + + if (!empty($query['WHERE'])) + $sql .= ' WHERE '.$query['WHERE']; + } + else if (isset($query['DELETE'])) + { + $sql = 'DELETE FROM '.(isset($query['PARAMS']['NO_PREFIX']) ? '' : $this->prefix).$query['DELETE']; + + if (!empty($query['WHERE'])) + $sql .= ' WHERE '.$query['WHERE']; + } + + return $this->query($sql, $unbuffered); + } + + + function result($query_id = 0, $row = 0) + { + return ($query_id) ? @pg_fetch_result($query_id, $row, 0) : false; + } + + + function fetch_assoc($query_id = 0) + { + return ($query_id) ? @pg_fetch_assoc($query_id) : false; + } + + + function fetch_row($query_id = 0) + { + return ($query_id) ? @pg_fetch_row($query_id) : false; + } + + + function num_rows($query_id = 0) + { + return ($query_id) ? @pg_num_rows($query_id) : false; + } + + + function affected_rows() + { + return ($this->query_result) ? @pg_affected_rows($this->query_result) : false; + } + + + function insert_id() + { + $query_id = $this->query_result; + + if ($query_id && $this->last_query_text[$query_id] != '') + { + if (preg_match('/^INSERT INTO ([a-z0-9\_\-]+)/is', $this->last_query_text[$query_id], $table_name)) + { + // Hack (don't ask) + if (substr($table_name[1], -6) == 'groups') + $table_name[1] .= '_g'; + + $temp_q_id = @pg_query($this->link_id, 'SELECT currval(\''.$table_name[1].'_id_seq\')'); + return ($temp_q_id) ? intval(@pg_fetch_result($temp_q_id, 0)) : false; + } + } + + return false; + } + + + function get_num_queries() + { + return $this->num_queries; + } + + + function get_saved_queries() + { + return $this->saved_queries; + } + + + function free_result($query_id = false) + { + if (!$query_id) + $query_id = $this->query_result; + + return ($query_id) ? @pg_free_result($query_id) : false; + } + + + function escape($str) + { + return is_array($str) ? '' : pg_escape_string($str); + } + + + function error() + { + $result['error_sql'] = @current(@end($this->saved_queries)); + $result['error_no'] = false; +/* + if (!empty($this->query_result)) + { + $result['error_msg'] = trim(@pg_result_error($this->query_result)); + if ($result['error_msg'] != '') + return $result; + } + + $result['error_msg'] = (!empty($this->link_id)) ? trim(@pg_last_error($this->link_id)) : trim(@pg_last_error()); +*/ + $result['error_msg'] = $this->error_msg; + + return $result; + } + + + function close() + { + if ($this->link_id) + { + if ($this->in_transaction) + { + if (defined('PUN_SHOW_QUERIES')) + $this->saved_queries[] = array('COMMIT', 0); + + @pg_query($this->link_id, 'COMMIT'); + } + + if ($this->query_result) + @pg_free_result($this->query_result); + + return @pg_close($this->link_id); + } + else + return false; + } + + + function table_exists($table_name) + { + $result = $this->query('SELECT 1 FROM pg_class WHERE relname = \''.$this->escape($table_name).'\''); + return $this->num_rows($result) > 0; + } + + + function field_exists($table_name, $field_name) + { + $result = $this->query('SELECT 1 FROM pg_class c INNER JOIN pg_attribute a ON a.attrelid = c.oid WHERE c.relname = \''.$this->escape($table_name).'\' AND a.attname = \''.$this->escape($field_name).'\''); + return $this->num_rows($result) > 0; + } + + + function index_exists($table_name, $index_name) + { + $result = $this->query('SELECT 1 FROM pg_index i INNER JOIN pg_class c1 ON c1.oid = i.indrelid INNER JOIN pg_class c2 ON c2.oid = i.indexrelid WHERE c1.relname = \''.$this->escape($table_name).'\' AND c2.relname = \''.$this->escape($index_name).'\''); + return $this->num_rows($result) > 0; + } + + + function add_field($table_name, $field_name, $field_type, $allow_null, $default_value = null, $after_field = null) + { + if ($this->field_exists($table_name, $field_name)) + return; + + $field_type = str_replace(array('TINY', 'FLOAT'), array('SMALL', 'REAL'), strtoupper($field_type)); + $field_type = preg_replace('/(.*?INT)(\([0-9]+)\)/', '$1', $field_type); + + $this->query('ALTER TABLE '.$table_name.' ADD '.$field_name.' '.$field_type) or error(__FILE__, __LINE__); + + if ($default_value !== null) + { + if (!is_int($default_value) && !is_float($default_value)) + $default_value = '\''.$this->escape($default_value).'\''; + + $this->query('ALTER TABLE '.$table_name.' ALTER '.$field_name.' SET DEFAULT '.$default_value) or error(__FILE__, __LINE__); + $this->query('UPDATE '.$table_name.' SET '.$field_name.'='.$default_value) or error(__FILE__, __LINE__); + } + + if (!$allow_null) + $this->query('ALTER TABLE '.$table_name.' ALTER '.$field_name.' SET NOT NULL') or error(__FILE__, __LINE__); + } + + + function drop_field($table_name, $field_name) + { + if (!$this->field_exists($table_name, $field_name)) + return; + + $this->query('ALTER TABLE '.$table_name.' DROP '.$field_name) or error(__FILE__, __LINE__); + } +}