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__); // Setup the client-server character set (UTF-8) if (!defined('PUN_NO_SET_NAMES')) pg_send_query($this->link_id, 'SET NAMES \'utf8\'') or error(__FILE__, __LINE__); 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']; } else if (isset($query['REPLACE'])) { $sql = 'INSERT INTO '.(isset($query['PARAMS']['NO_PREFIX']) ? '' : $this->prefix).$query['INTO']; if (!empty($query['REPLACE'])) $sql .= ' ('.$query['REPLACE'].')'; $sql .= ' SELECT '.$query['VALUES'].' WHERE NOT EXISTS (SELECT 1 FROM '.(isset($query['PARAMS']['NO_PREFIX']) ? '' : $this->prefix).$query['INTO'].' WHERE '.$query['UNIQUE'].')'; } 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__); } }