summaryrefslogtreecommitdiff
path: root/kohana/libraries
diff options
context:
space:
mode:
Diffstat (limited to 'kohana/libraries')
-rw-r--r--kohana/libraries/Controller.php16
-rw-r--r--kohana/libraries/Database.php45
-rw-r--r--kohana/libraries/Image.php50
-rw-r--r--kohana/libraries/Model.php4
-rw-r--r--kohana/libraries/ORM.php102
-rw-r--r--kohana/libraries/ORM_Tree.php18
-rw-r--r--kohana/libraries/View.php22
-rw-r--r--kohana/libraries/drivers/Database.php4
-rw-r--r--kohana/libraries/drivers/Database/Mssql.php7
-rw-r--r--kohana/libraries/drivers/Database/Mysql.php11
-rw-r--r--kohana/libraries/drivers/Database/Mysqli.php7
-rw-r--r--kohana/libraries/drivers/Database/Pgsql.php110
12 files changed, 213 insertions, 183 deletions
diff --git a/kohana/libraries/Controller.php b/kohana/libraries/Controller.php
index 5f946bde..317f5f0c 100644
--- a/kohana/libraries/Controller.php
+++ b/kohana/libraries/Controller.php
@@ -66,18 +66,10 @@ abstract class Controller_Core {
// Import the view variables to local namespace
extract($kohana_input_data, EXTR_SKIP);
- try
- {
- // Views are straight HTML pages with embedded PHP, so importing them
- // this way insures that $this can be accessed as if the user was in
- // the controller, which gives the easiest access to libraries in views
- include $kohana_view_filename;
- }
- catch (Exception $e)
- {
- // Display the exception using its internal __toString method
- echo $e;
- }
+ // Views are straight HTML pages with embedded PHP, so importing them
+ // this way insures that $this can be accessed as if the user was in
+ // the controller, which gives the easiest access to libraries in views
+ include $kohana_view_filename;
// Fetch the output and close the buffer
return ob_get_clean();
diff --git a/kohana/libraries/Database.php b/kohana/libraries/Database.php
index adbbcf56..0e02ec59 100644
--- a/kohana/libraries/Database.php
+++ b/kohana/libraries/Database.php
@@ -341,7 +341,20 @@ class Database_Core {
{
if (($val = trim($val)) === '') continue;
- $this->from[] = $this->config['table_prefix'].$val;
+ // TODO: Temporary solution, this should be moved to database driver (AS is checked for twice)
+ if (stripos($val, ' AS ') !== FALSE)
+ {
+ $val = str_ireplace(' AS ', ' AS ', $val);
+
+ list($table, $alias) = explode(' AS ', $val);
+
+ // Attach prefix to both sides of the AS
+ $this->from[] = $this->config['table_prefix'].$table.' AS '.$this->config['table_prefix'].$alias;
+ }
+ else
+ {
+ $this->from[] = $this->config['table_prefix'].$val;
+ }
}
return $this;
@@ -379,14 +392,36 @@ class Database_Core {
foreach ($keys as $key => $value)
{
$key = (strpos($key, '.') !== FALSE) ? $this->config['table_prefix'].$key : $key;
- $cond[] = $this->driver->where($key, $this->driver->escape_column($this->config['table_prefix'].$value), 'AND ', count($cond), FALSE);
+
+ if (is_string($value))
+ {
+ // Only escape if it's a string
+ $value = $this->driver->escape_column($this->config['table_prefix'].$value);
+ }
+
+ $cond[] = $this->driver->where($key, $value, 'AND ', count($cond), FALSE);
}
if( ! is_array($this->join)) { $this->join = array(); }
foreach ((array) $table as $t)
{
- $join['tables'][] = $this->driver->escape_column($this->config['table_prefix'].$t);
+ // TODO: Temporary solution, this should be moved to database driver (AS is checked for twice)
+ if (stripos($t, ' AS ') !== FALSE)
+ {
+ $t = str_ireplace(' AS ', ' AS ', $t);
+
+ list($table, $alias) = explode(' AS ', $t);
+
+ // Attach prefix to both sides of the AS
+ $t = $this->config['table_prefix'].$table.' AS '.$this->config['table_prefix'].$alias;
+ }
+ else
+ {
+ $t = $this->config['table_prefix'].$t;
+ }
+
+ $join['tables'][] = $this->driver->escape_column($t);
}
$join['conditions'] = '('.trim(implode(' ', $cond)).')';
@@ -1278,7 +1313,7 @@ class Database_Core {
* @return Database_Core This Databaes object
*/
public function push()
- {
+ {
array_push($this->query_history, array(
$this->select,
$this->from,
@@ -1310,7 +1345,7 @@ class Database_Core {
// No history
return $this;
}
-
+
list(
$this->select,
$this->from,
diff --git a/kohana/libraries/Image.php b/kohana/libraries/Image.php
index 6fcce090..c9e82a1c 100644
--- a/kohana/libraries/Image.php
+++ b/kohana/libraries/Image.php
@@ -134,7 +134,7 @@ class Image_Core {
}
else
{
- throw new Kohana_Exception('core.invalid_property', $column, get_class($this));
+ throw new Kohana_Exception('core.invalid_property', $property, get_class($this));
}
}
@@ -358,39 +358,39 @@ class Image_Core {
chmod($new_image, $chmod);
}
}
-
+
// Reset actions. Subsequent save() or render() will not apply previous actions.
if ($keep_actions === FALSE)
$this->actions = array();
-
+
return $status;
}
-
- /**
- * Output the image to the browser.
- *
+
+ /**
+ * Output the image to the browser.
+ *
* @param boolean keep or discard image process actions
- * @return object
- */
- public function render($keep_actions = FALSE)
- {
- $new_image = $this->image['file'];
-
- // Separate the directory and filename
- $dir = pathinfo($new_image, PATHINFO_DIRNAME);
- $file = pathinfo($new_image, PATHINFO_BASENAME);
-
- // Normalize the path
- $dir = str_replace('\\', '/', realpath($dir)).'/';
-
- // Process the image with the driver
- $status = $this->driver->process($this->image, $this->actions, $dir, $file, $render = TRUE);
-
+ * @return object
+ */
+ public function render($keep_actions = FALSE)
+ {
+ $new_image = $this->image['file'];
+
+ // Separate the directory and filename
+ $dir = pathinfo($new_image, PATHINFO_DIRNAME);
+ $file = pathinfo($new_image, PATHINFO_BASENAME);
+
+ // Normalize the path
+ $dir = str_replace('\\', '/', realpath($dir)).'/';
+
+ // Process the image with the driver
+ $status = $this->driver->process($this->image, $this->actions, $dir, $file, $render = TRUE);
+
// Reset actions. Subsequent save() or render() will not apply previous actions.
if ($keep_actions === FALSE)
$this->actions = array();
-
- return $status;
+
+ return $status;
}
/**
diff --git a/kohana/libraries/Model.php b/kohana/libraries/Model.php
index 4134ff2d..9c78507b 100644
--- a/kohana/libraries/Model.php
+++ b/kohana/libraries/Model.php
@@ -12,7 +12,7 @@
class Model_Core {
// Database object
- protected $db;
+ protected $db = 'default';
/**
* Loads the database instance, if the database is not already loaded.
@@ -24,7 +24,7 @@ class Model_Core {
if ( ! is_object($this->db))
{
// Load the default database
- $this->db = Database::instance('default');
+ $this->db = Database::instance($this->db);
}
}
diff --git a/kohana/libraries/ORM.php b/kohana/libraries/ORM.php
index 16ac16f2..64229ee2 100644
--- a/kohana/libraries/ORM.php
+++ b/kohana/libraries/ORM.php
@@ -278,15 +278,15 @@ class ORM_Core {
{
// This handles the has_one and belongs_to relationships
- if (array_key_exists($column.'_'.$model->primary_key, $this->object))
+ if (in_array($model->object_name, $this->belongs_to) OR ! isset($model->object[$this->foreign_key($column)]))
{
- // Use the FK that exists in this model as the PK
- $where = array($model->table_name.'.'.$model->primary_key => $this->object[$column.'_'.$model->primary_key]);
+ // Foreign key lies in this table (this model belongs_to target model) OR an invalid has_one relationship
+ $where = array($model->table_name.'.'.$model->primary_key => $this->object[$this->foreign_key($column)]);
}
else
{
- // Use this model PK as the FK
- $where = array($this->foreign_key() => $this->object[$this->primary_key]);
+ // Foreign key lies in the target table (this model has_one target model)
+ $where = array($this->foreign_key($column, $model->table_name) => $this->primary_key_value);
}
// one<>alias:one relationship
@@ -300,22 +300,23 @@ class ORM_Core {
// Load the "end" model
$model = ORM::factory(inflector::singular($column));
- // Load JOIN info
+ // Join ON target model's primary key set to 'through' model's foreign key
+ // User-defined foreign keys must be defined in the 'through' model
$join_table = $through->table_name;
- $join_col1 = $model->foreign_key(NULL, $join_table);
- $join_col2 = $model->foreign_key(TRUE);
+ $join_col1 = $through->foreign_key($model->object_name, $join_table);
+ $join_col2 = $model->table_name.'.'.$model->primary_key;
// one<>alias:many relationship
return $this->related[$column] = $model
->join($join_table, $join_col1, $join_col2)
- ->where($this->foreign_key(NULL, $join_table), $this->object[$this->primary_key])
+ ->where($through->foreign_key($this->object_name, $join_table), $this->object[$this->primary_key])
->find_all();
}
elseif (in_array($column, $this->has_many))
{
// one<>many relationship
return $this->related[$column] = ORM::factory(inflector::singular($column))
- ->where($this->foreign_key($column), $this->object[$this->primary_key])
+ ->where($this->foreign_key($column, $column), $this->object[$this->primary_key])
->find_all();
}
elseif (in_array($column, $this->has_and_belongs_to_many))
@@ -461,91 +462,83 @@ class ORM_Core {
* Binds another one-to-one object to this model. One-to-one objects
* can be nested using 'object1:object2' syntax
*
- * @param string $object
+ * @param string $target_path
* @return void
*/
- public function with($object)
+ public function with($target_path)
{
- if (isset($this->with_applied[$object]))
+ if (isset($this->with_applied[$target_path]))
{
// Don't join anything already joined
return $this;
}
- $prefix = $table = $object;
-
// Split object parts
- $objects = explode(':', $object);
- $object = $this;
- foreach ($objects as $object_part)
+ $objects = explode(':', $target_path);
+ $target = $this;
+ foreach ($objects as $object)
{
// Go down the line of objects to find the given target
- $parent = $object;
- $object = $parent->related_object($object_part);
+ $parent = $target;
+ $target = $parent->related_object($object);
- if ( ! $object)
+ if ( ! $target)
{
// Can't find related object
return $this;
}
}
- $table = $object_part;
-
- if ($this->table_names_plural)
- {
- $table = inflector::plural($table);
- }
+ $target_name = $object;
- // Pop-off top object to get the parent object (user:photo:tag's parent is user:photo)
+ // Pop-off top object to get the parent object (user:photo:tag becomes user:photo - the parent table prefix)
array_pop($objects);
- $parent_prefix = implode(':', $objects);
+ $parent_path = implode(':', $objects);
- if (empty($parent_prefix))
+ if (empty($parent_path))
{
- // Use this table name itself for the parent prefix
- $parent_prefix = $this->table_name;
+ // Use this table name itself for the parent object
+ $parent_path = $this->table_name;
}
else
{
- if( ! isset($this->with_applied[$parent_prefix]))
+ if( ! isset($this->with_applied[$parent_path]))
{
// If the parent object hasn't been joined yet, do it first (otherwise LEFT JOINs fail)
- $this->with($parent_prefix);
+ $this->with($parent_path);
}
}
// Add to with_applied to prevent duplicate joins
- $this->with_applied[$prefix] = TRUE;
+ $this->with_applied[$target_path] = TRUE;
// Use the keys of the empty object to determine the columns
- $select = array_keys($object->as_array());
+ $select = array_keys($target->as_array());
foreach ($select as $i => $column)
{
// Add the prefix so that load_result can determine the relationship
- $select[$i] = $prefix.'.'.$column.' AS '.$prefix.':'.$column;
+ $select[$i] = $target_path.'.'.$column.' AS '.$target_path.':'.$column;
}
+
// Select all of the prefixed keys in the object
$this->db->select($select);
-
- // Use last object part to generate foreign key
- $foreign_key = $object_part.'_'.$object->primary_key;
-
- if (array_key_exists($foreign_key, $parent->object))
+
+ if (in_array($target->object_name, $parent->belongs_to) OR ! isset($target->object[$parent->foreign_key($target_name)]))
{
- // Foreign key exists in the joined object's parent
- $join_col1 = $object->foreign_key(TRUE, $prefix);
- $join_col2 = $parent_prefix.'.'.$foreign_key;
+ // Parent belongs_to target, use target's primary key as join column
+ $join_col1 = $target->foreign_key(TRUE, $target_path);
+ $join_col2 = $parent->foreign_key($target_name, $parent_path);
}
else
{
- $join_col1 = $parent->foreign_key(NULL, $prefix);
- $join_col2 = $parent_prefix.'.'.$parent->primary_key;
+ // Parent has_one target, use parent's primary key as join column
+ $join_col2 = $parent->foreign_key(TRUE, $parent_path);
+ $join_col1 = $parent->foreign_key($target_name, $target_path);
}
// Join the related object into the result
- $this->db->join($object->table_name.' AS '.$this->db->table_prefix().$prefix, $join_col1, $join_col2, 'LEFT');
+ $this->db->join($target->table_name.' AS '.$this->db->table_prefix().$target_path, $join_col1, $join_col2, 'LEFT');
return $this;
}
@@ -1360,10 +1353,19 @@ class ORM_Core {
if ( ! empty($this->load_with))
{
- foreach ($this->load_with as $object)
+ foreach ($this->load_with as $alias => $object)
{
// Join each object into the results
- $this->with($object);
+ if (is_string($alias))
+ {
+ // Use alias
+ $this->with($alias);
+ }
+ else
+ {
+ // Use object
+ $this->with($object);
+ }
}
}
diff --git a/kohana/libraries/ORM_Tree.php b/kohana/libraries/ORM_Tree.php
index 72f55540..def5fd59 100644
--- a/kohana/libraries/ORM_Tree.php
+++ b/kohana/libraries/ORM_Tree.php
@@ -13,10 +13,10 @@
class ORM_Tree_Core extends ORM {
// Name of the child
- protected $children;
+ protected $ORM_Tree_children;
// Parent keyword name
- protected $parent_key = 'parent_id';
+ protected $ORM_Tree_parent_key = 'parent_id';
/**
* Overload ORM::__get to support "parent" and "children" properties.
@@ -31,12 +31,12 @@ class ORM_Tree_Core extends ORM {
if (empty($this->related[$column]))
{
// Load child model
- $model = ORM::factory(inflector::singular($this->children));
+ $model = ORM::factory(inflector::singular($this->ORM_Tree_children));
- if (array_key_exists($this->parent_key, $this->object))
+ if (array_key_exists($this->ORM_Tree_parent_key, $this->object))
{
// Find children of this parent
- $model->where($model->primary_key, $this->object[$this->parent_key])->find();
+ $model->where($model->primary_key, $this->object[$this->ORM_Tree_parent_key])->find();
}
$this->related[$column] = $model;
@@ -48,13 +48,13 @@ class ORM_Tree_Core extends ORM {
{
if (empty($this->related[$column]))
{
- $model = ORM::factory(inflector::singular($this->children));
+ $model = ORM::factory(inflector::singular($this->ORM_Tree_children));
- if ($this->children === $this->table_name)
+ if ($this->ORM_Tree_children === $this->table_name)
{
// Load children within this table
$this->related[$column] = $model
- ->where($this->parent_key, $this->object[$this->primary_key])
+ ->where($this->ORM_Tree_parent_key, $this->object[$this->primary_key])
->find_all();
}
else
@@ -62,7 +62,7 @@ class ORM_Tree_Core extends ORM {
// Find first selection of children
$this->related[$column] = $model
->where($this->foreign_key(), $this->object[$this->primary_key])
- ->where($this->parent_key, NULL)
+ ->where($this->ORM_Tree_parent_key, NULL)
->find_all();
}
}
diff --git a/kohana/libraries/View.php b/kohana/libraries/View.php
index c440be10..5dba706c 100644
--- a/kohana/libraries/View.php
+++ b/kohana/libraries/View.php
@@ -56,7 +56,7 @@ class View_Core {
$this->kohana_local_data = array_merge($this->kohana_local_data, $data);
}
}
-
+
/**
* Magic method access to test for view property
*
@@ -129,7 +129,7 @@ class View_Core {
}
/**
- * Checks for a property existence in the view locally or globally. Unlike the built in __isset(),
+ * Checks for a property existence in the view locally or globally. Unlike the built in __isset(),
* this method can take an array of properties to test simultaneously.
*
* @param string $key property name to test for
@@ -147,7 +147,7 @@ class View_Core {
{
// Set the result to an array
$result = array();
-
+
// Foreach key
foreach ($key as $property)
{
@@ -184,9 +184,9 @@ class View_Core {
*
* @param string|array name of variable or an array of variables
* @param mixed value when using a named variable
- * @return object
+ * @return void
*/
- public function set_global($name, $value = NULL)
+ public static function set_global($name, $value = NULL)
{
if (is_array($name))
{
@@ -199,8 +199,6 @@ class View_Core {
{
self::$kohana_global_data[$name] = $value;
}
-
- return $this;
}
/**
@@ -241,7 +239,15 @@ class View_Core {
*/
public function __toString()
{
- return $this->render();
+ try
+ {
+ return $this->render();
+ }
+ catch (Exception $e)
+ {
+ // Display the exception using its internal __toString method
+ return (string) $e;
+ }
}
/**
diff --git a/kohana/libraries/drivers/Database.php b/kohana/libraries/drivers/Database.php
index d478aa6a..96562240 100644
--- a/kohana/libraries/drivers/Database.php
+++ b/kohana/libraries/drivers/Database.php
@@ -154,7 +154,7 @@ abstract class Database_Driver {
* @param int number of likes
* @return string
*/
- public function like($field, $match = '', $auto = TRUE, $type = 'AND ', $num_likes)
+ public function like($field, $match, $auto, $type, $num_likes)
{
$prefix = ($num_likes == 0) ? '' : $type;
@@ -178,7 +178,7 @@ abstract class Database_Driver {
* @param int number of likes
* @return string
*/
- public function notlike($field, $match = '', $auto = TRUE, $type = 'AND ', $num_likes)
+ public function notlike($field, $match, $auto, $type, $num_likes)
{
$prefix = ($num_likes == 0) ? '' : $type;
diff --git a/kohana/libraries/drivers/Database/Mssql.php b/kohana/libraries/drivers/Database/Mssql.php
index 401770a2..3e89faba 100644
--- a/kohana/libraries/drivers/Database/Mssql.php
+++ b/kohana/libraries/drivers/Database/Mssql.php
@@ -74,7 +74,7 @@ class Database_Mssql_Driver extends Database_Driver
*/
// Clear password after successful connect
- $this->config['connection']['pass'] = NULL;
+ $this->db_config['connection']['pass'] = NULL;
return $this->link;
}
@@ -94,6 +94,11 @@ class Database_Mssql_Driver extends Database_Driver
// Set the cached object
self::$query_cache[$hash] = new Mssql_Result(mssql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql);
}
+ else
+ {
+ // Rewind cached result
+ self::$query_cache[$hash]->rewind();
+ }
// Return the cached query
return self::$query_cache[$hash];
diff --git a/kohana/libraries/drivers/Database/Mysql.php b/kohana/libraries/drivers/Database/Mysql.php
index f54b6d81..04d7ed65 100644
--- a/kohana/libraries/drivers/Database/Mysql.php
+++ b/kohana/libraries/drivers/Database/Mysql.php
@@ -74,7 +74,7 @@ class Database_Mysql_Driver extends Database_Driver {
}
// Clear password after successful connect
- $this->config['connection']['pass'] = NULL;
+ $this->db_config['connection']['pass'] = NULL;
return $this->link;
}
@@ -94,6 +94,11 @@ class Database_Mysql_Driver extends Database_Driver {
// Set the cached object
self::$query_cache[$hash] = new Mysql_Result(mysql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql);
}
+ else
+ {
+ // Rewind cached result
+ self::$query_cache[$hash]->rewind();
+ }
// Return the cached query
return self::$query_cache[$hash];
@@ -170,14 +175,14 @@ class Database_Mysql_Driver extends Database_Driver {
return $column;
}
- public function regex($field, $match = '', $type = 'AND ', $num_regexs)
+ public function regex($field, $match, $type, $num_regexs)
{
$prefix = ($num_regexs == 0) ? '' : $type;
return $prefix.' '.$this->escape_column($field).' REGEXP \''.$this->escape_str($match).'\'';
}
- public function notregex($field, $match = '', $type = 'AND ', $num_regexs)
+ public function notregex($field, $match, $type, $num_regexs)
{
$prefix = $num_regexs == 0 ? '' : $type;
diff --git a/kohana/libraries/drivers/Database/Mysqli.php b/kohana/libraries/drivers/Database/Mysqli.php
index 795c576b..3d6bbfbf 100644
--- a/kohana/libraries/drivers/Database/Mysqli.php
+++ b/kohana/libraries/drivers/Database/Mysqli.php
@@ -57,7 +57,7 @@ class Database_Mysqli_Driver extends Database_Mysql_Driver {
}
// Clear password after successful connect
- $this->config['connection']['pass'] = NULL;
+ $this->db_config['connection']['pass'] = NULL;
return $this->link;
}
@@ -77,6 +77,11 @@ class Database_Mysqli_Driver extends Database_Mysql_Driver {
// Set the cached object
self::$query_cache[$hash] = new Kohana_Mysqli_Result($this->link, $this->db_config['object'], $sql);
}
+ else
+ {
+ // Rewind cached result
+ self::$query_cache[$hash]->rewind();
+ }
// Return the cached query
return self::$query_cache[$hash];
diff --git a/kohana/libraries/drivers/Database/Pgsql.php b/kohana/libraries/drivers/Database/Pgsql.php
index ff0a5ed5..9758de3c 100644
--- a/kohana/libraries/drivers/Database/Pgsql.php
+++ b/kohana/libraries/drivers/Database/Pgsql.php
@@ -53,7 +53,7 @@ class Database_Pgsql_Driver extends Database_Driver {
}
// Clear password after successful connect
- $this->config['connection']['pass'] = NULL;
+ $this->db_config['connection']['pass'] = NULL;
return $this->link;
}
@@ -73,6 +73,11 @@ class Database_Pgsql_Driver extends Database_Driver {
// Set the cached object
self::$query_cache[$hash] = new Pgsql_Result(pg_query($this->link, $sql), $this->link, $this->db_config['object'], $sql);
}
+ else
+ {
+ // Rewind cached result
+ self::$query_cache[$hash]->rewind();
+ }
return self::$query_cache[$hash];
}
@@ -137,14 +142,14 @@ class Database_Pgsql_Driver extends Database_Driver {
return $column;
}
- public function regex($field, $match = '', $type = 'AND ', $num_regexs)
+ public function regex($field, $match, $type, $num_regexs)
{
$prefix = ($num_regexs == 0) ? '' : $type;
return $prefix.' '.$this->escape_column($field).' REGEXP \''.$this->escape_str($match).'\'';
}
- public function notregex($field, $match = '', $type = 'AND ', $num_regexs)
+ public function notregex($field, $match, $type, $num_regexs)
{
$prefix = $num_regexs == 0 ? '' : $type;
@@ -244,84 +249,57 @@ class Database_Pgsql_Driver extends Database_Driver {
return pg_last_error($this->link);
}
- public function list_fields($table, $query = FALSE)
+ public function list_fields($table)
{
static $tables;
- if (is_object($query))
+ if (empty($tables[$table]))
{
- if (empty($tables[$table]))
+ foreach ($this->field_data($table) as $row)
{
- $tables[$table] = array();
+ // Make an associative array
+ $tables[$table][$row->column_name] = $this->sql_type($row->data_type);
- foreach ($query as $row)
+ if (!strncmp($row->column_default, 'nextval(', 8))
{
- $tables[$table][] = $row->Field;
+ $tables[$table][$row->column_name]['sequenced'] = TRUE;
}
- }
- return $tables[$table];
- }
-
- // WOW...REALLY?!?
- // Taken from http://www.postgresql.org/docs/7.4/interactive/catalogs.html
- $query = $this->query('SELECT
- -- Field
- pg_attribute.attname AS "Field",
- -- Type
- CASE pg_type.typname
- WHEN \'int2\' THEN \'smallint\'
- WHEN \'int4\' THEN \'int\'
- WHEN \'int8\' THEN \'bigint\'
- WHEN \'varchar\' THEN \'varchar(\' || pg_attribute.atttypmod-4 || \')\'
- ELSE pg_type.typname
- END AS "Type",
- -- Null
- CASE WHEN pg_attribute.attnotnull THEN \'NO\'
- ELSE \'YES\'
- END AS "Null",
- -- Default
- CASE pg_type.typname
- WHEN \'varchar\' THEN substring(pg_attrdef.adsrc from \'^(.*).*$\')
- ELSE pg_attrdef.adsrc
- END AS "Default"
-FROM pg_class
- INNER JOIN pg_attribute
- ON (pg_class.oid=pg_attribute.attrelid)
- INNER JOIN pg_type
- ON (pg_attribute.atttypid=pg_type.oid)
- LEFT JOIN pg_attrdef
- ON (pg_class.oid=pg_attrdef.adrelid AND pg_attribute.attnum=pg_attrdef.adnum)
-WHERE pg_class.relname=\''.$this->escape_str($table).'\' AND pg_attribute.attnum>=1 AND NOT pg_attribute.attisdropped
-ORDER BY pg_attribute.attnum');
-
- // Load the result as objects
- $query->result(TRUE);
-
- $fields = array();
- foreach ($query as $row)
+ if ($row->is_nullable === 'YES')
{
- $fields[$row->Field] = $row->Type;
+ $tables[$table][$row->column_name]['null'] = TRUE;
}
+ }
+ }
+
+ if (!isset($tables[$table]))
+ throw new Kohana_Database_Exception('database.table_not_found', $table);
- return $fields;
+ return $tables[$table];
}
public function field_data($table)
{
- // TODO: This whole function needs to be debugged.
- $query = pg_query('SELECT * FROM '.$this->escape_table($table).' LIMIT 1', $this->link);
- $fields = pg_num_fields($query);
- $table = array();
-
- for ($i=0; $i < $fields; $i++)
+ $columns = array();
+
+ // http://www.postgresql.org/docs/8.3/static/infoschema-columns.html
+ $result = pg_query($this->link, '
+ SELECT column_name, column_default, is_nullable, data_type, udt_name,
+ character_maximum_length, numeric_precision, numeric_precision_radix, numeric_scale
+ FROM information_schema.columns
+ WHERE table_name = \''. $this->escape_str($table) .'\'
+ ORDER BY ordinal_position
+ ');
+
+ if ($result)
{
- $table[$i]['type'] = pg_field_type($query, $i);
- $table[$i]['name'] = pg_field_name($query, $i);
- $table[$i]['len'] = pg_field_prtlen($query, $i);
+ while ($row = pg_fetch_object($result))
+ {
+ $columns[] = $row;
+ }
}
- return $table;
+ return $columns;
}
} // End Database_Pgsql_Driver Class
@@ -463,7 +441,7 @@ class Pgsql_Result extends Database_Result {
// tables that have no serial column.
$ER = error_reporting(0);
- $result = pg_query($query);
+ $result = pg_query($this->link, $query);
$insert_id = pg_fetch_array($result, NULL, PGSQL_ASSOC);
$this->insert_id = $insert_id['insert_id'];
@@ -486,9 +464,11 @@ class Pgsql_Result extends Database_Result {
public function list_fields()
{
$field_names = array();
- while ($field = pg_field_name($this->result))
+
+ $fields = pg_num_fields($this->result);
+ for ($i = 0; $i < $fields; ++$i)
{
- $field_names[] = $field->name;
+ $field_names[] = pg_field_name($this->result, $i);
}
return $field_names;