| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 | <?php namespace Laravel\Database;use PDO, PDOStatement, Laravel\Config, Laravel\Event;class Connection {	/**	 * The raw PDO connection instance.	 *	 * @var PDO	 */	public $pdo;	/**	 * The connection configuration array.	 *	 * @var array	 */	public $config;	/**	 * The query grammar instance for the connection.	 *	 * @var Grammars\Grammar	 */	protected $grammar;	/**	 * All of the queries that have been executed on all connections.	 *	 * @var array	 */	public static $queries = array();	/**	 * Create a new database connection instance.	 *	 * @param  PDO    $pdo	 * @param  array  $config	 * @return void	 */	public function __construct(PDO $pdo, $config)	{		$this->pdo = $pdo;		$this->config = $config;	}	/**	 * Begin a fluent query against a table.	 *	 * <code>	 *		// Start a fluent query against the "users" table	 *		$query = DB::connection()->table('users');	 *	 *		// Start a fluent query against the "users" table and get all the users	 *		$users = DB::connection()->table('users')->get();	 * </code>	 *	 * @param  string  $table	 * @return Query	 */	public function table($table)	{		return new Query($this, $this->grammar(), $table);	}	/**	 * Create a new query grammar for the connection.	 *	 * @return Query\Grammars\Grammar	 */	protected function grammar()	{		if (isset($this->grammar)) return $this->grammar;		if (isset(\Laravel\Database::$registrar[$this->driver()]))		{			\Laravel\Database::$registrar[$this->driver()]['query']();		}		switch ($this->driver())		{			case 'mysql':				return $this->grammar = new Query\Grammars\MySQL($this);			case 'sqlite':				return $this->grammar = new Query\Grammars\SQLite($this);			case 'sqlsrv':				return $this->grammar = new Query\Grammars\SQLServer($this);			default:				return $this->grammar = new Query\Grammars\Grammar($this);		}	}	/**	 * Execute a callback wrapped in a database transaction.	 *	 * @param  callback  $callback	 * @return void	 */	public function transaction($callback)	{		$this->pdo->beginTransaction();		// After beginning the database transaction, we will call the callback		// so that it can do its database work. If an exception occurs we'll		// rollback the transaction and re-throw back to the developer.		try		{			call_user_func($callback);		}		catch (\Exception $e)		{			$this->pdo->rollBack();			throw $e;		}		$this->pdo->commit();	}	/**	 * Execute a SQL query against the connection and return a single column result.	 *	 * <code>	 *		// Get the total number of rows on a table	 *		$count = DB::connection()->only('select count(*) from users');	 *	 *		// Get the sum of payment amounts from a table	 *		$sum = DB::connection()->only('select sum(amount) from payments')	 * </code>	 *	 * @param  string  $sql	 * @param  array   $bindings	 * @return mixed	 */	public function only($sql, $bindings = array())	{		$results = (array) $this->first($sql, $bindings);		return reset($results);	}	/**	 * Execute a SQL query against the connection and return the first result.	 *	 * <code>	 *		// Execute a query against the database connection	 *		$user = DB::connection()->first('select * from users');	 *	 *		// Execute a query with bound parameters	 *		$user = DB::connection()->first('select * from users where id = ?', array($id));	 * </code>	 *	 * @param  string  $sql	 * @param  array   $bindings	 * @return object	 */	public function first($sql, $bindings = array())	{		if (count($results = $this->query($sql, $bindings)) > 0)		{			return $results[0];		}	}	/**	 * Execute a SQL query and return an array of StdClass objects.	 *	 * @param  string  $sql	 * @param  array   $bindings	 * @return array	 */	public function query($sql, $bindings = array())	{		$sql = trim($sql);		list($statement, $result) = $this->execute($sql, $bindings);		// The result we return depends on the type of query executed against the		// database. On SELECT clauses, we will return the result set, for update		// and deletes we will return the affected row count.		if (stripos($sql, 'select') === 0)		{			return $this->fetch($statement, Config::get('database.fetch'));		}		elseif (stripos($sql, 'update') === 0 or stripos($sql, 'delete') === 0)		{			return $statement->rowCount();		}		else		{			return $result;		}	}	/**	 * Execute a SQL query against the connection.	 *	 * The PDO statement and boolean result will be return in an array.	 *	 * @param  string  $sql	 * @param  array   $bindings	 * @return array	 */	protected function execute($sql, $bindings = array())	{		$bindings = (array) $bindings;		// Since expressions are injected into the query as strings, we need to		// remove them from the array of bindings. After we have removed them,		// we'll reset the array so there are not gaps within the keys.		$bindings = array_filter($bindings, function($binding)		{			return ! $binding instanceof Expression;		});		$bindings = array_values($bindings);		$sql = $this->grammar()->shortcut($sql, $bindings);		// Next we need to translate all DateTime bindings to their date-time		// strings that are compatible with the database. Each grammar may		// define it's own date-time format according to its needs.		$datetime = $this->grammar()->datetime;		for ($i = 0; $i < count($bindings); $i++)		{			if ($bindings[$i] instanceof \DateTime)			{				$bindings[$i] = $bindings[$i]->format($datetime);			}		}		// Each database operation is wrapped in a try / catch so we can wrap		// any database exceptions in our custom exception class, which will		// set the message to include the SQL and query bindings.		try		{			$statement = $this->pdo->prepare($sql);			$start = microtime(true);			$result = $statement->execute($bindings);		}		// If an exception occurs, we'll pass it into our custom exception		// and set the message to include the SQL and query bindings so		// debugging is much easier on the developer.		catch (\Exception $exception)		{			$exception = new Exception($sql, $bindings, $exception);			throw $exception;		}		// Once we have execute the query, we log the SQL, bindings, and		// execution time in a static array that is accessed by all of		// the connections actively being used by the application.		if (Config::get('database.profile'))		{			$this->log($sql, $bindings, $start);		}		return array($statement, $result);	}	/**	 * Fetch all of the rows for a given statement.	 *	 * @param  PDOStatement  $statement	 * @param  int           $style	 * @return array	 */	protected function fetch($statement, $style)	{		// If the fetch style is "class", we'll hydrate an array of PHP		// stdClass objects as generic containers for the query rows,		// otherwise we'll just use the fetch styel value.		if ($style === PDO::FETCH_CLASS)		{			return $statement->fetchAll(PDO::FETCH_CLASS, 'stdClass');		}		else		{			return $statement->fetchAll($style);		}	}	/**	 * Log the query and fire the core query event.	 *	 * @param  string  $sql	 * @param  array   $bindings	 * @param  int     $start	 * @return void	 */	protected function log($sql, $bindings, $start)	{		$time = number_format((microtime(true) - $start) * 1000, 2);		Event::fire('laravel.query', array($sql, $bindings, $time));		static::$queries[] = compact('sql', 'bindings', 'time');	}	/**	 * Get the driver name for the database connection.	 *	 * @return string	 */	public function driver()	{		return $this->config['driver'];	}	/**	 * Magic Method for dynamically beginning queries on database tables.	 */	public function __call($method, $parameters)	{		return $this->table($method);	}		/**	 * Get the last query that was executed.	 * 	 * Returns false if no queries have been executed yet.	 *	 * @return string	 */	public static function last_query()	{		return end(static::$queries);	}}
 |