Browse Source

improve / fix postgres support.

Taylor Otwell 12 years ago
parent
commit
691d68ba54

+ 10 - 0
laravel/database/connection.php

@@ -89,6 +89,9 @@ class Connection {
 			case 'sqlsrv':
 			case 'sqlsrv':
 				return $this->grammar = new Query\Grammars\SQLServer($this);
 				return $this->grammar = new Query\Grammars\SQLServer($this);
 
 
+			case 'pgsql':
+				return $this->grammar = new Query\Grammars\Postgres($this);
+
 			default:
 			default:
 				return $this->grammar = new Query\Grammars\Grammar($this);
 				return $this->grammar = new Query\Grammars\Grammar($this);
 		}
 		}
@@ -190,6 +193,13 @@ class Connection {
 		{
 		{
 			return $statement->rowCount();
 			return $statement->rowCount();
 		}
 		}
+		// For insert statements that use the "returning" clause, which is allowed
+		// by databsae systems such as Postgres, we need to actually return the
+		// real query result so the consumer can get the ID.
+		elseif (stripos($sql, 'insert') === 0 and stripos($sql, 'returning') !== false)
+		{
+			return $this->fetch($statement, Config::get('database.fetch'));
+		}
 		else
 		else
 		{
 		{
 			return $result;
 			return $result;

+ 12 - 0
laravel/database/connectors/postgres.php

@@ -2,6 +2,18 @@
 
 
 class Postgres extends Connector {
 class Postgres extends Connector {
 
 
+	/**
+	 * The PDO connection options.
+	 *
+	 * @var array
+	 */
+	protected $options = array(
+			PDO::ATTR_CASE => PDO::CASE_LOWER,
+			PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
+			PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
+			PDO::ATTR_STRINGIFY_FETCHES => false,
+	);
+
 	/**
 	/**
 	 * Establish a PDO database connection.
 	 * Establish a PDO database connection.
 	 *
 	 *

+ 1 - 1
laravel/database/eloquent/model.php

@@ -399,7 +399,7 @@ abstract class Model {
 		// then we can consider the insert successful.
 		// then we can consider the insert successful.
 		else
 		else
 		{
 		{
-			$id = $this->query()->insert_get_id($this->attributes, $this->sequence());
+			$id = $this->query()->insert_get_id($this->attributes, $this->key());
 
 
 			$this->set_key($id);
 			$this->set_key($id);
 
 

+ 13 - 8
laravel/database/query.php

@@ -3,6 +3,7 @@
 use Closure;
 use Closure;
 use Laravel\Database;
 use Laravel\Database;
 use Laravel\Paginator;
 use Laravel\Paginator;
+use Laravel\Database\Query\Grammars\Postgres;
 use Laravel\Database\Query\Grammars\SQLServer;
 use Laravel\Database\Query\Grammars\SQLServer;
 
 
 class Query {
 class Query {
@@ -751,19 +752,23 @@ class Query {
 	 * Insert an array of values into the database table and return the ID.
 	 * Insert an array of values into the database table and return the ID.
 	 *
 	 *
 	 * @param  array   $values
 	 * @param  array   $values
-	 * @param  string  $sequence
+	 * @param  string  $column
 	 * @return int
 	 * @return int
 	 */
 	 */
-	public function insert_get_id($values, $sequence = null)
+	public function insert_get_id($values, $column = 'id')
 	{
 	{
-		$sql = $this->grammar->insert($this, $values);
+		$sql = $this->grammar->insert_get_id($this, $values, $column);
 
 
-		$this->connection->query($sql, array_values($values));
+		$result = $this->connection->query($sql, array_values($values));
 
 
-		// Some database systems (Postgres) require a sequence name to be
-		// given when retrieving the auto-incrementing ID, so we'll pass
-		// the given sequence into the method just in case.
-		return (int) $this->connection->pdo->lastInsertId($sequence);
+		if ($this->grammar instanceof Postgres)
+		{
+			return (int) $result[0]->$column;
+		}
+		else
+		{
+			return (int) $this->connection->pdo->lastInsertId();
+		}
 	}
 	}
 
 
 	/**
 	/**

+ 13 - 0
laravel/database/query/grammars/grammar.php

@@ -375,6 +375,19 @@ class Grammar extends \Laravel\Database\Grammar {
 		return "INSERT INTO {$table} ({$columns}) VALUES {$parameters}";
 		return "INSERT INTO {$table} ({$columns}) VALUES {$parameters}";
 	}
 	}
 
 
+	/**
+	 * Compile a SQL INSERT and get ID statment from a Query instance.
+	 *
+	 * @param  Query   $query
+	 * @param  array   $values
+	 * @param  string  $column
+	 * @return string
+	 */
+	public function insert_get_id(Query $query, $values, $column)
+	{
+		return $this->insert($query, $values);
+	}
+
 	/**
 	/**
 	 * Compile a SQL UPDATE statment from a Query instance.
 	 * Compile a SQL UPDATE statment from a Query instance.
 	 *
 	 *

+ 20 - 0
laravel/database/query/grammars/postgres.php

@@ -0,0 +1,20 @@
+<?php namespace Laravel\Database\Query\Grammars;
+
+use Laravel\Database\Query;
+
+class Postgres extends Grammar {
+
+	/**
+	 * Compile a SQL INSERT and get ID statment from a Query instance.
+	 *
+	 * @param  Query   $query
+	 * @param  array   $values
+	 * @param  string  $column
+	 * @return string
+	 */
+	public function insert_get_id(Query $query, $values, $column)
+	{
+		return $this->insert($query, $values)." RETURNING $column";
+	}
+
+}

+ 1 - 1
laravel/database/schema/grammars/postgres.php

@@ -324,7 +324,7 @@ class Postgres extends Grammar {
 	 */
 	 */
 	protected function type_integer(Fluent $column)
 	protected function type_integer(Fluent $column)
 	{
 	{
-		return ($column->increment) ? 'SERIAL' : 'INTEGER';
+		return ($column->increment) ? 'SERIAL' : 'BIGINT';
 	}
 	}
 
 
 	/**
 	/**

+ 3 - 1
laravel/database/schema/table.php

@@ -136,7 +136,9 @@ class Table {
 		// the index that can be used when dropping indexes.
 		// the index that can be used when dropping indexes.
 		if (is_null($name))
 		if (is_null($name))
 		{
 		{
-			$name = $this->name.'_'.implode('_', $columns).'_'.$type;
+			$name = str_replace(array('-', '.'), '_', $this->name);
+
+			$name = $name.'_'.implode('_', $columns).'_'.$type;
 		}
 		}
 
 
 		return $this->command($type, compact('name', 'columns'));
 		return $this->command($type, compact('name', 'columns'));