From c5bfbb3b5ea4090caf7b207fad64b44809f001b3 Mon Sep 17 00:00:00 2001 From: Donny Kurnia Date: Mon, 10 Aug 2015 10:01:15 +0700 Subject: [PATCH 1/6] add compileInsertGetId and processInsertGetId method taken from PostgresGrammar and PostgresProcessor classes as-is I've check it in my project using php artisan tinker and it's working well PS: this library need tests to make sure all methods working well Signed-off-by: Donny Kurnia --- .../Query/Grammars/FirebirdGrammar.php | 17 ++++++++++++++ .../Query/Processors/FirebirdProcessor.php | 22 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/Firebird/Query/Grammars/FirebirdGrammar.php b/src/Firebird/Query/Grammars/FirebirdGrammar.php index 5ca4cca..49a6acf 100644 --- a/src/Firebird/Query/Grammars/FirebirdGrammar.php +++ b/src/Firebird/Query/Grammars/FirebirdGrammar.php @@ -106,4 +106,21 @@ protected function compileOffset(Builder $query, $limit) return 'skip '.(int) $limit; } + /** + * Compile an insert and get ID statement into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $values + * @param string $sequence + * @return string + */ + public function compileInsertGetId(Builder $query, $values, $sequence) + { + if (is_null($sequence)) { + $sequence = 'id'; + } + + return $this->compileInsert($query, $values).' returning '.$this->wrap($sequence); + } + } \ No newline at end of file diff --git a/src/Firebird/Query/Processors/FirebirdProcessor.php b/src/Firebird/Query/Processors/FirebirdProcessor.php index c114ca8..1022383 100644 --- a/src/Firebird/Query/Processors/FirebirdProcessor.php +++ b/src/Firebird/Query/Processors/FirebirdProcessor.php @@ -1,7 +1,29 @@ getConnection()->selectFromWriteConnection($sql, $values); + + $sequence = $sequence ?: 'id'; + + $result = (array) $results[0]; + + $id = $result[$sequence]; + + return is_numeric($id) ? (int) $id : $id; + } } \ No newline at end of file From 8d7253d7b1afe06a2f9670c787e39a553495533d Mon Sep 17 00:00:00 2001 From: Donny Kurnia Date: Wed, 25 Nov 2015 15:09:56 +0700 Subject: [PATCH 2/6] add processColumnListing Processor --- .../Query/Processors/FirebirdProcessor.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Firebird/Query/Processors/FirebirdProcessor.php b/src/Firebird/Query/Processors/FirebirdProcessor.php index 1022383..11a928d 100644 --- a/src/Firebird/Query/Processors/FirebirdProcessor.php +++ b/src/Firebird/Query/Processors/FirebirdProcessor.php @@ -26,4 +26,21 @@ public function processInsertGetId(Builder $query, $sql, $values, $sequence = nu return is_numeric($id) ? (int) $id : $id; } + /** + * Process the results of a column listing query. + * + * @param array $results + * @return array + */ + public function processColumnListing($results) + { + $mapping = function ($r) { + $r = (object) $r; + + return $r->{'RDB$FIELD_NAME'}; + }; + + return array_map($mapping, $results); + } + } \ No newline at end of file From e64e4ea179a9412ce652085375254f6669326e9e Mon Sep 17 00:00:00 2001 From: Donny Kurnia Date: Wed, 25 Nov 2015 15:11:57 +0700 Subject: [PATCH 3/6] add --- .../Schema/Grammars/FirebirdGrammar.php | 885 +++++++++--------- 1 file changed, 448 insertions(+), 437 deletions(-) diff --git a/src/Firebird/Schema/Grammars/FirebirdGrammar.php b/src/Firebird/Schema/Grammars/FirebirdGrammar.php index b00fdcd..26b73f1 100644 --- a/src/Firebird/Schema/Grammars/FirebirdGrammar.php +++ b/src/Firebird/Schema/Grammars/FirebirdGrammar.php @@ -1,437 +1,448 @@ -getColumns($blueprint)); - - $sql = 'create table '.$this->wrapTable($blueprint)." ($columns)"; - - return $sql; - } - - /** - * Compile a drop table command. - * - * @param \Illuminate\Database\Schema\Blueprint $blueprint - * @param \Illuminate\Support\Fluent $command - * @return string - */ - public function compileDrop(Blueprint $blueprint, Fluent $command) - { - return 'drop table '.$this->wrapTable($blueprint); - } - - /** - * Compile a primary key command. - * - * @param \Illuminate\Database\Schema\Blueprint $blueprint - * @param \Illuminate\Support\Fluent $command - * @return string - */ - public function compilePrimary(Blueprint $blueprint, Fluent $command) - { - $command->name(null); - - return $this->compileKey($blueprint, $command, 'primary key'); - } - - /** - * Compile a unique key command. - * - * @param \Illuminate\Database\Schema\Blueprint $blueprint - * @param \Illuminate\Support\Fluent $command - * @return string - */ - public function compileUnique(Blueprint $blueprint, Fluent $command) - { - $columns = $this->columnize($command->columns); - - $table = $this->wrapTable($blueprint); - - return "CREATE UNIQUE INDEX ".strtoupper(substr($command->index, 0, 31))." ON {$table} ($columns)"; - } - - /** - * Compile a plain index key command. - * - * @param \Illuminate\Database\Schema\Blueprint $blueprint - * @param \Illuminate\Support\Fluent $command - * @return string - */ - public function compileIndex(Blueprint $blueprint, Fluent $command) - { - $columns = $this->columnize($command->columns); - - $table = $this->wrapTable($blueprint); - - return "CREATE INDEX ".strtoupper(substr($command->index, 0, 31))." ON {$table} ($columns)"; - } - - /** - * Compile an index creation command. - * - * @param \Illuminate\Database\Schema\Blueprint $blueprint - * @param \Illuminate\Support\Fluent $command - * @param string $type - * @return string - */ - protected function compileKey(Blueprint $blueprint, Fluent $command, $type) - { - $columns = $this->columnize($command->columns); - - $table = $this->wrapTable($blueprint); - - return "alter table {$table} add {$type} ($columns)"; - } - - /** - * Compile a foreign key command. - * - * @param \Illuminate\Database\Schema\Blueprint $blueprint - * @param \Illuminate\Support\Fluent $command - * @return string - */ - public function compileForeign(Blueprint $blueprint, Fluent $command) - { - $table = $this->wrapTable($blueprint); - - $on = $this->wrapTable($command->on); - - // We need to prepare several of the elements of the foreign key definition - // before we can create the SQL, such as wrapping the tables and convert - // an array of columns to comma-delimited strings for the SQL queries. - $columns = $this->columnize($command->columns); - - $onColumns = $this->columnize((array) $command->references); - - $sql = "alter table {$table} add constraint ".strtoupper(substr($command->index, 0, 31))." "; - - $sql .= "foreign key ({$columns}) references {$on} ({$onColumns})"; - - // Once we have the basic foreign key creation statement constructed we can - // build out the syntax for what should happen on an update or delete of - // the affected columns, which will get something like "cascade", etc. - if ( ! is_null($command->onDelete)) - { - $sql .= " on delete {$command->onDelete}"; - } - - if ( ! is_null($command->onUpdate)) - { - $sql .= " on update {$command->onUpdate}"; - } - - return $sql; - } - - /** - * Compile a drop foreign key command. - * - * @param \Illuminate\Database\Schema\Blueprint $blueprint - * @param \Illuminate\Support\Fluent $command - * @return string - */ - public function compileDropForeign(Blueprint $blueprint, Fluent $command) - { - $table = $this->wrapTable($blueprint); - - return "alter table {$table} drop constraint {$command->index}"; - } - - /** - * Get the SQL for a nullable column modifier. - * - * @param \Illuminate\Database\Schema\Blueprint $blueprint - * @param \Illuminate\Support\Fluent $column - * @return string|null - */ - protected function modifyNullable(Blueprint $blueprint, Fluent $column) - { - return $column->nullable ? '' : ' not null'; - } - - /** - * Get the SQL for a default column modifier. - * - * @param \Illuminate\Database\Schema\Blueprint $blueprint - * @param \Illuminate\Support\Fluent $column - * @return string|null - */ - protected function modifyDefault(Blueprint $blueprint, Fluent $column) - { - if ( ! is_null($column->default)) - { - return " default ".$this->getDefaultValue($column->default); - } - } - - /** - * Create the column definition for a char type. - * - * @param \Illuminate\Support\Fluent $column - * @return string - */ - protected function typeChar(Fluent $column) - { - return 'VARCHAR'; - } - - /** - * Create the column definition for a string type. - * - * @param \Illuminate\Support\Fluent $column - * @return string - */ - protected function typeString(Fluent $column) - { - return 'VARCHAR ('.$column->length.')'; - } - - /** - * Create the column definition for a text type. - * - * @param \Illuminate\Support\Fluent $column - * @return string - */ - protected function typeText(Fluent $column) - { - return 'BLOB SUB_TYPE TEXT'; - } - - /** - * Create the column definition for a medium text type. - * - * @param \Illuminate\Support\Fluent $column - * @return string - */ - protected function typeMediumText(Fluent $column) - { - return 'BLOB SUB_TYPE TEXT'; - } - - /** - * Create the column definition for a long text type. - * - * @param \Illuminate\Support\Fluent $column - * @return string - */ - protected function typeLongText(Fluent $column) - { - return 'BLOB SUB_TYPE TEXT'; - } - - /** - * Create the column definition for a integer type. - * - * @param \Illuminate\Support\Fluent $column - * @return string - */ - protected function typeInteger(Fluent $column) - { - return 'INTEGER'; - } - - /** - * Create the column definition for a big integer type. - * - * @param \Illuminate\Support\Fluent $column - * @return string - */ - protected function typeBigInteger(Fluent $column) - { - return 'INTEGER'; - } - - /** - * Create the column definition for a medium integer type. - * - * @param \Illuminate\Support\Fluent $column - * @return string - */ - protected function typeMediumInteger(Fluent $column) - { - return 'INTEGER'; - } - - /** - * Create the column definition for a tiny integer type. - * - * @param \Illuminate\Support\Fluent $column - * @return string - */ - protected function typeTinyInteger(Fluent $column) - { - return 'SMALLINT'; - } - - /** - * Create the column definition for a small integer type. - * - * @param \Illuminate\Support\Fluent $column - * @return string - */ - protected function typeSmallInteger(Fluent $column) - { - return 'SMALLINT'; - } - - /** - * Create the column definition for a float type. - * - * @param \Illuminate\Support\Fluent $column - * @return string - */ - protected function typeFloat(Fluent $column) - { - return 'FLOAT'; - } - - /** - * Create the column definition for a double type. - * - * @param \Illuminate\Support\Fluent $column - * @return string - */ - protected function typeDouble(Fluent $column) - { - return 'DOUBLE'; - } - - /** - * Create the column definition for a decimal type. - * - * @param \Illuminate\Support\Fluent $column - * @return string - */ - protected function typeDecimal(Fluent $column) - { - return 'DECIMAL'; - } - - /** - * Create the column definition for a boolean type. - * - * @param \Illuminate\Support\Fluent $column - * @return string - */ - protected function typeBoolean(Fluent $column) - { - return 'CHAR(1)'; - } - - /** - * Create the column definition for an enum type. - * - * @param \Illuminate\Support\Fluent $column - * @return string - */ - protected function typeEnum(Fluent $column) - { - return 'VARCHAR'; - } - - /** - * Create the column definition for a json type. - * - * @param \Illuminate\Support\Fluent $column - * @return string - */ - protected function typeJson(Fluent $column) - { - return 'BLOB SUB_TYPE 0'; - } - - /** - * Create the column definition for a date type. - * - * @param \Illuminate\Support\Fluent $column - * @return string - */ - protected function typeDate(Fluent $column) - { - return 'TIMESTAMP'; - } - - /** - * Create the column definition for a date-time type. - * - * @param \Illuminate\Support\Fluent $column - * @return string - */ - protected function typeDateTime(Fluent $column) - { - return 'TIMESTAMP'; - } - - /** - * Create the column definition for a time type. - * - * @param \Illuminate\Support\Fluent $column - * @return string - */ - protected function typeTime(Fluent $column) - { - return 'TIMESTAMP'; - } - - /** - * Create the column definition for a timestamp type. - * - * @param \Illuminate\Support\Fluent $column - * @return string - */ - protected function typeTimestamp(Fluent $column) - { - return 'TIMESTAMP'; - } - - /** - * Create the column definition for a binary type. - * - * @param \Illuminate\Support\Fluent $column - * @return string - */ - protected function typeBinary(Fluent $column) - { - return 'BLOB SUB_TYPE 0'; - } -} +getColumns($blueprint)); + + $sql = 'create table '.$this->wrapTable($blueprint)." ($columns)"; + + return $sql; + } + + /** + * Compile a drop table command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDrop(Blueprint $blueprint, Fluent $command) + { + return 'drop table '.$this->wrapTable($blueprint); + } + + /** + * Compile a primary key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compilePrimary(Blueprint $blueprint, Fluent $command) + { + $command->name(null); + + return $this->compileKey($blueprint, $command, 'primary key'); + } + + /** + * Compile a unique key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileUnique(Blueprint $blueprint, Fluent $command) + { + $columns = $this->columnize($command->columns); + + $table = $this->wrapTable($blueprint); + + return "CREATE UNIQUE INDEX ".strtoupper(substr($command->index, 0, 31))." ON {$table} ($columns)"; + } + + /** + * Compile a plain index key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileIndex(Blueprint $blueprint, Fluent $command) + { + $columns = $this->columnize($command->columns); + + $table = $this->wrapTable($blueprint); + + return "CREATE INDEX ".strtoupper(substr($command->index, 0, 31))." ON {$table} ($columns)"; + } + + /** + * Compile an index creation command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @param string $type + * @return string + */ + protected function compileKey(Blueprint $blueprint, Fluent $command, $type) + { + $columns = $this->columnize($command->columns); + + $table = $this->wrapTable($blueprint); + + return "alter table {$table} add {$type} ($columns)"; + } + + /** + * Compile a foreign key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileForeign(Blueprint $blueprint, Fluent $command) + { + $table = $this->wrapTable($blueprint); + + $on = $this->wrapTable($command->on); + + // We need to prepare several of the elements of the foreign key definition + // before we can create the SQL, such as wrapping the tables and convert + // an array of columns to comma-delimited strings for the SQL queries. + $columns = $this->columnize($command->columns); + + $onColumns = $this->columnize((array) $command->references); + + $sql = "alter table {$table} add constraint ".strtoupper(substr($command->index, 0, 31))." "; + + $sql .= "foreign key ({$columns}) references {$on} ({$onColumns})"; + + // Once we have the basic foreign key creation statement constructed we can + // build out the syntax for what should happen on an update or delete of + // the affected columns, which will get something like "cascade", etc. + if ( ! is_null($command->onDelete)) + { + $sql .= " on delete {$command->onDelete}"; + } + + if ( ! is_null($command->onUpdate)) + { + $sql .= " on update {$command->onUpdate}"; + } + + return $sql; + } + + /** + * Compile a drop foreign key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileDropForeign(Blueprint $blueprint, Fluent $command) + { + $table = $this->wrapTable($blueprint); + + return "alter table {$table} drop constraint {$command->index}"; + } + + /** + * Get the SQL for a nullable column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + protected function modifyNullable(Blueprint $blueprint, Fluent $column) + { + return $column->nullable ? '' : ' not null'; + } + + /** + * Get the SQL for a default column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + protected function modifyDefault(Blueprint $blueprint, Fluent $column) + { + if ( ! is_null($column->default)) + { + return " default ".$this->getDefaultValue($column->default); + } + } + + /** + * Create the column definition for a char type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeChar(Fluent $column) + { + return 'VARCHAR'; + } + + /** + * Create the column definition for a string type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeString(Fluent $column) + { + return 'VARCHAR ('.$column->length.')'; + } + + /** + * Create the column definition for a text type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeText(Fluent $column) + { + return 'BLOB SUB_TYPE TEXT'; + } + + /** + * Create the column definition for a medium text type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeMediumText(Fluent $column) + { + return 'BLOB SUB_TYPE TEXT'; + } + + /** + * Create the column definition for a long text type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeLongText(Fluent $column) + { + return 'BLOB SUB_TYPE TEXT'; + } + + /** + * Create the column definition for a integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeInteger(Fluent $column) + { + return 'INTEGER'; + } + + /** + * Create the column definition for a big integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeBigInteger(Fluent $column) + { + return 'INTEGER'; + } + + /** + * Create the column definition for a medium integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeMediumInteger(Fluent $column) + { + return 'INTEGER'; + } + + /** + * Create the column definition for a tiny integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTinyInteger(Fluent $column) + { + return 'SMALLINT'; + } + + /** + * Create the column definition for a small integer type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeSmallInteger(Fluent $column) + { + return 'SMALLINT'; + } + + /** + * Create the column definition for a float type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeFloat(Fluent $column) + { + return 'FLOAT'; + } + + /** + * Create the column definition for a double type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDouble(Fluent $column) + { + return 'DOUBLE'; + } + + /** + * Create the column definition for a decimal type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDecimal(Fluent $column) + { + return 'DECIMAL'; + } + + /** + * Create the column definition for a boolean type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeBoolean(Fluent $column) + { + return 'CHAR(1)'; + } + + /** + * Create the column definition for an enum type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeEnum(Fluent $column) + { + return 'VARCHAR'; + } + + /** + * Create the column definition for a json type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeJson(Fluent $column) + { + return 'BLOB SUB_TYPE 0'; + } + + /** + * Create the column definition for a date type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDate(Fluent $column) + { + return 'TIMESTAMP'; + } + + /** + * Create the column definition for a date-time type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeDateTime(Fluent $column) + { + return 'TIMESTAMP'; + } + + /** + * Create the column definition for a time type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTime(Fluent $column) + { + return 'TIMESTAMP'; + } + + /** + * Create the column definition for a timestamp type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeTimestamp(Fluent $column) + { + return 'TIMESTAMP'; + } + + /** + * Create the column definition for a binary type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeBinary(Fluent $column) + { + return 'BLOB SUB_TYPE 0'; + } +} From df97f180aa194b3349ea6eb9bd32c47e0eae2131 Mon Sep 17 00:00:00 2001 From: Donny Kurnia Date: Thu, 26 Nov 2015 10:42:14 +0700 Subject: [PATCH 4/6] trim the column name --- src/Firebird/Query/Processors/FirebirdProcessor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Firebird/Query/Processors/FirebirdProcessor.php b/src/Firebird/Query/Processors/FirebirdProcessor.php index 11a928d..4c95111 100644 --- a/src/Firebird/Query/Processors/FirebirdProcessor.php +++ b/src/Firebird/Query/Processors/FirebirdProcessor.php @@ -37,7 +37,7 @@ public function processColumnListing($results) $mapping = function ($r) { $r = (object) $r; - return $r->{'RDB$FIELD_NAME'}; + return trim($r->{'RDB$FIELD_NAME'}); }; return array_map($mapping, $results); From 15c81ee6ec2c5efba36d474fada0219f4067fb40 Mon Sep 17 00:00:00 2001 From: Donny Kurnia Date: Wed, 2 Mar 2016 09:35:25 +0700 Subject: [PATCH 5/6] handle pdo_firebase errors "already an active transaction" Reference: https://secure.php.net/manual/en/pdo.begintransaction.php#114788 https://stackoverflow.com/questions/19216375/transaction-not-working/19220044#19220044 --- src/Firebird/Connection.php | 330 +++++++++++++++++++----------------- 1 file changed, 174 insertions(+), 156 deletions(-) diff --git a/src/Firebird/Connection.php b/src/Firebird/Connection.php index 7940cdf..85117d6 100644 --- a/src/Firebird/Connection.php +++ b/src/Firebird/Connection.php @@ -1,156 +1,174 @@ -pdo = $pdo; - - $this->config = $config; - - // First we will setup the default properties. We keep track of the DB - // name we are connected to since it is needed when some reflective - // type commands are run such as checking whether a table exists. - $this->database = $database; - - $this->tablePrefix = $tablePrefix; - - $this->config = $config; - - // The connection string - $dsn = $this->getDsn($config); - - // Create the connection - $this->connection = $this->createConnection($dsn, $config); - - // Set the database - $this->db = $this->connection; - - // We need to initialize a query grammar and the query post processors - // which are both very important parts of the database abstractions - // so we initialize these to their default values while starting. - $this->useDefaultQueryGrammar(); - - $this->useDefaultPostProcessor(); - } - /** - * Return the DSN string from configuration - * - * @param array $config - * @return string - */ - protected function getDsn(array $config) - { - // Check that the host and database are not empty - if( ! empty($config['host']) && ! empty ($config['database']) ) - { - return 'firebird:dbname='.$config['host'].':'.$config['database'].';charset='.$config['charset']; - } - else - { - trigger_error( 'Cannot connect to Firebird Database, no host or path supplied' ); - } - } - - /** - * Create the Firebird Connection - * - * @param string $dsn - * @param array $config - * @return PDO - */ - public function createConnection($dsn, array $config) - { - //Check the username and password - if (!empty($config['username']) && !empty($config['password'])) - { - try { - return new PDO($dsn, $config['username'], $config['password']); - } catch (PDOException $e) { - trigger_error($e->getMessage()); - } - } - else - { - trigger_error('Cannot connect to Firebird Database, no username or password supplied'); - } - return null; - } - - /** - * Get the default query grammar instance - * - * @return Query\Grammars\FirebirdGrammar - */ - protected function getDefaultQueryGrammar() - { - return new Query\Grammars\FirebirdGrammar; - } - - /** - * Get the default post processor instance. - * - * @return Query\Processors\FirebirdProcessor - */ - protected function getDefaultPostProcessor() - { - return new Query\Processors\FirebirdProcessor; - } - - /** - * Get a schema builder instance for this connection. - * @return Schema\Builder - */ - public function getSchemaBuilder() - { - if (is_null($this->schemaGrammar)) { $this->useDefaultSchemaGrammar(); } - - return new Schema\Builder($this); - } - - /** - * Get the default schema grammar instance. - * - * @return SchemaGrammar; - */ - protected function getDefaultSchemaGrammar() { - return $this->withTablePrefix(new SchemaGrammar); - } - - /** - * Begin a fluent query against a database table. - * - * @param string $table - * @return Firebird\Query\Builder - */ - public function table($table) - { - $processor = $this->getPostProcessor(); - - $query = new Query\Builder($this, $this->getQueryGrammar(), $processor); - - return $query->from($table); - } -} +pdo = $pdo; + + $this->config = $config; + + // First we will setup the default properties. We keep track of the DB + // name we are connected to since it is needed when some reflective + // type commands are run such as checking whether a table exists. + $this->database = $database; + + $this->tablePrefix = $tablePrefix; + + $this->config = $config; + + // The connection string + $dsn = $this->getDsn($config); + + // Create the connection + $this->connection = $this->createConnection($dsn, $config); + + // Set the database + $this->db = $this->connection; + + // We need to initialize a query grammar and the query post processors + // which are both very important parts of the database abstractions + // so we initialize these to their default values while starting. + $this->useDefaultQueryGrammar(); + + $this->useDefaultPostProcessor(); + } + /** + * Return the DSN string from configuration + * + * @param array $config + * @return string + */ + protected function getDsn(array $config) + { + // Check that the host and database are not empty + if( ! empty($config['host']) && ! empty ($config['database']) ) + { + return 'firebird:dbname='.$config['host'].':'.$config['database'].';charset='.$config['charset']; + } + else + { + trigger_error( 'Cannot connect to Firebird Database, no host or path supplied' ); + } + } + + /** + * Create the Firebird Connection + * + * @param string $dsn + * @param array $config + * @return PDO + */ + public function createConnection($dsn, array $config) + { + //Check the username and password + if (!empty($config['username']) && !empty($config['password'])) + { + try { + return new PDO($dsn, $config['username'], $config['password']); + } catch (PDOException $e) { + trigger_error($e->getMessage()); + } + } + else + { + trigger_error('Cannot connect to Firebird Database, no username or password supplied'); + } + return null; + } + + /** + * Get the default query grammar instance + * + * @return Query\Grammars\FirebirdGrammar + */ + protected function getDefaultQueryGrammar() + { + return new Query\Grammars\FirebirdGrammar; + } + + /** + * Get the default post processor instance. + * + * @return Query\Processors\FirebirdProcessor + */ + protected function getDefaultPostProcessor() + { + return new Query\Processors\FirebirdProcessor; + } + + /** + * Get a schema builder instance for this connection. + * @return Schema\Builder + */ + public function getSchemaBuilder() + { + if (is_null($this->schemaGrammar)) { $this->useDefaultSchemaGrammar(); } + + return new Schema\Builder($this); + } + + /** + * Get the default schema grammar instance. + * + * @return SchemaGrammar; + */ + protected function getDefaultSchemaGrammar() { + return $this->withTablePrefix(new SchemaGrammar); + } + + /** + * Begin a fluent query against a database table. + * + * @param string $table + * @return Firebird\Query\Builder + */ + public function table($table) + { + $processor = $this->getPostProcessor(); + + $query = new Query\Builder($this, $this->getQueryGrammar(), $processor); + + return $query->from($table); + } + + public function beginTransaction() + { + $this->pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 0); + parent::beginTransaction(); + } + + public function commit() + { + parent::commit(); + $this->pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 1); + } + + public function rollBack() + { + parent::rollBack(); + $this->pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 1); + } +} From d1e9bd4975a0b2712397a96b51553907dd707c8d Mon Sep 17 00:00:00 2001 From: Donny Kurnia Date: Thu, 3 Mar 2016 16:38:37 +0700 Subject: [PATCH 6/6] additional checking before set PDO::ATTR_AUTOCOMMIT attribute --- src/Firebird/Connection.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Firebird/Connection.php b/src/Firebird/Connection.php index 85117d6..eec67b0 100644 --- a/src/Firebird/Connection.php +++ b/src/Firebird/Connection.php @@ -156,19 +156,25 @@ public function table($table) public function beginTransaction() { - $this->pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 0); + if ( $this->transactions == 0 && $this->pdo->getAttribute(PDO::ATTR_AUTOCOMMIT) == 1 ) { + $this->pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 0); + } parent::beginTransaction(); } public function commit() { parent::commit(); - $this->pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 1); + if ( $this->transactions == 0 && $this->pdo->getAttribute(PDO::ATTR_AUTOCOMMIT) == 0 ) { + $this->pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 1); + } } public function rollBack() { parent::rollBack(); - $this->pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 1); + if ( $this->transactions == 0 && $this->pdo->getAttribute(PDO::ATTR_AUTOCOMMIT) == 0 ) { + $this->pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 1); + } } }