diff --git a/README.md b/README.md index f31dc92..ae156dc 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,9 @@ Add the following in the require section of your **composer.json**: -### Laravel >=7.x +### Laravel 11 >= ```json -"uepg/laravel-sybase": "~4.0" +"uepg/laravel-sybase": "~5.0" ``` Update the package dependencies executing: @@ -47,12 +47,6 @@ Update your **config/database.php's** default driver with the settings for the * return [ ... - 'sybase' => - [ - 'application_encoding' => false, - 'application_charset' => '', - 'database_charset' => '' - ], 'connections' => [ ... @@ -67,7 +61,9 @@ return [ 'charset' => 'utf8', 'prefix' => '', 'cache_tables' => true, - 'cache_time' => 3600 + 'cache_time' => 3600, + 'application_encoding' => false, + 'application_charset' => '', ], ... @@ -107,18 +103,13 @@ The file is usualy found in **/etc/freetds/freetds.conf**. Set the configuration ## Configuring the charset conversion This package offers to method to charset conversion, it can be converted in application layer or in database layer, we offered both methods because it can be useful for debugging, to config the application layer conversion you need to set up the following entries on the `database.php` file. You can view an example of the application encoding setup below: -```database -'sybase' => - [ - 'application_encoding' => true, - 'application_charset' => '', - 'database_charset' => '' - ], ``` To use the database layer conversion add the property charset to connection configuration on the sybase configuration array ```charset 'charset' => 'utf8', + 'application_encoding' => false, + 'application_charset' => '', ``` diff --git a/src/Database/Connection.php b/src/Database/Connection.php index 8b89bca..7cd1a03 100644 --- a/src/Database/Connection.php +++ b/src/Database/Connection.php @@ -23,11 +23,72 @@ class Connection extends IlluminateConnection * * @var array */ - private array $numeric = [ - 'int', 'numeric', 'bigint', 'integer', 'smallint', 'tinyint', 'decimal', 'double', 'float', 'real', 'bit', - 'binary', 'varbinary', 'timestamp', 'money', + private $numeric = [ + 'int', + 'numeric', + 'bigint', + 'integer', + 'smallint', + 'tinyint', + 'decimal', + 'double', + 'float', + 'real', + 'bit', + 'binary', + 'varbinary', + 'timestamp', + 'money', ]; + + /** + * @var string The application charset + */ + private $applicationCharset; + + /** + * @var string The database charset + */ + private $databaseCharset; + + private $applicationEncoding = false; + + /** + * Create a new database connection instance. + * + * @param \PDO|\Closure $pdo + * @param string $database + * @param string $tablePrefix + * @param array $config + * @return void + */ + public function __construct($pdo, $database = '', $tablePrefix = '', array $config = []) + { + parent::__construct($pdo, $database, $tablePrefix, $config); + $this->configureExtraSettings($config); + } + + /** + * Configures the encoding for the connection. + * + * @param array $config + * @return void + */ + public function configureExtraSettings($config = []) + { + $this->applicationEncoding = key_exists('application_encoding',$config) ? $config['application_encoding'] : false; + if ($this->applicationEncoding) + { + if (!key_exists('application_charset',$config,) || !key_exists('database_charset',$config)) + { + throw new \Exception('When application encoding is configured, you need to set up application_charset and database_charset'); + } + $this->applicationCharset = $config['application_charset']; + $this->databaseCharset = $config['charset']; + } + } + /** * Execute a Closure within a transaction. * @@ -54,10 +115,10 @@ public function transaction(Closure $callback, $attempts = 1) $this->pdo->exec('COMMIT TRAN'); } - // If we catch an exception, we will roll back so nothing gets messed - // up in the database. Then we'll re-throw the exception so it can - // be handled how the developer sees fit for their applications. - catch (Exception $e) { + // If we catch an exception, we will roll back so nothing gets messed + // up in the database. Then we'll re-throw the exception so it can + // be handled how the developer sees fit for their applications. + catch (\Exception|\PDOException $e) { $this->pdo->exec('ROLLBACK TRAN'); throw $e; @@ -69,9 +130,9 @@ public function transaction(Closure $callback, $attempts = 1) /** * Run a select statement against the database. * - * @param string $query - * @param array $bindings - * @param bool $useReadPdo + * @param string $query + * @param array $bindings + * @param bool $useReadPdo * @return array */ public function select($query, $bindings = [], $useReadPdo = true) @@ -84,8 +145,10 @@ public function select($query, $bindings = [], $useReadPdo = true) return []; } - $statement = $this->getPdo() - ->prepare($this->compileNewQuery($query, $bindings)); + $statement = $this->getPdo()->prepare($this->compileNewQuery( + $query, + $bindings + )); $statement->execute(); @@ -95,24 +158,23 @@ public function select($query, $bindings = [], $useReadPdo = true) do { $result += $statement->fetchAll($this->getFetchMode()); } while ($statement->nextRowset()); - } catch (Exception $e) { + } catch (\Exception $e) { } $result = [...$result]; $application_encoding = config('database.sybase.application_encoding'); - if (!$application_encoding) { + if (is_null($application_encoding) || $application_encoding == false) { return $result; } $database_charset = config('database.sybase.database_charset'); $application_charset = config('database.sybase.application_charset'); if (is_null($database_charset) || is_null($application_charset)) { - throw new Exception('[SYBASE] Database Charset and App Charset not set'); + throw new \Exception('[SYBASE] Database Charset and App Charset not set'); } foreach ($result as &$r) { foreach ($r as $k => &$v) { - $v = gettype($v) === 'string' ? mb_convert_encoding($v, $application_charset, - $database_charset) : $v; + $v = gettype($v) === 'string' ? mb_convert_encoding($v, $application_charset, $database_charset) : $v; } } @@ -120,6 +182,7 @@ public function select($query, $bindings = [], $useReadPdo = true) }); } + /** * Set new bindings with specified column types to Sybase. * @@ -129,13 +192,14 @@ public function select($query, $bindings = [], $useReadPdo = true) * * @link http://stackoverflow.com/questions/2718628/pdoparam-for-type-decimal * - * @param string $query - * @param array $bindings + * @param string $query + * @param array $bindings * @return string $query - * @throws Exception */ - private function compileNewQuery(string $query, array $bindings) + private function compileNewQuery($query, $bindings) { + $newQuery = ''; + $bindings = $this->compileBindings($query, $bindings); $partQuery = explode('?', $query); @@ -143,28 +207,32 @@ private function compileNewQuery(string $query, array $bindings) $bindings = array_map(fn($v) => gettype($v) === 'string' ? "'{$v}'" : $v, $bindings); $bindings = array_map(fn($v) => gettype($v) === 'NULL' ? 'NULL' : $v, $bindings); - $newQuery = join(array_map(fn($k1, $k2) => $k1.$k2, $partQuery, $bindings)); + $newQuery = join(array_map(fn($k1, $k2) => $k1 . $k2, $partQuery, $bindings)); $newQuery = str_replace('[]', '', $newQuery); $application_encoding = config('database.sybase.application_encoding'); - if (!$application_encoding) { + + if (is_null($application_encoding) || $application_encoding == false) { return $newQuery; } $database_charset = config('database.sybase.database_charset'); $application_charset = config('database.sybase.application_charset'); if (is_null($database_charset) || is_null($application_charset)) { - throw new Exception('[SYBASE] Database Charset and App Charset not set'); + throw new \Exception('[SYBASE] Database Charset and App Charset not set'); } - return mb_convert_encoding($newQuery, $database_charset, $application_charset); + $newQuery = mb_convert_encoding($newQuery, $database_charset, $application_charset); + + return $newQuery; } + /** * Set new bindings with specified column types to Sybase. * - * @param string $query - * @param array $bindings - * @return array $newBinds + * @param string $query + * @param array $bindings + * @return mixed $newBinds */ - private function compileBindings(string $query, array $bindings) + private function compileBindings($query, $bindings) { if (count($bindings) == 0) { return []; @@ -180,6 +248,7 @@ private function compileBindings(string $query, array $bindings) } } + /** * Compile the bindings for select/insert/update/delete. * @@ -210,7 +279,7 @@ private function compile(Builder $builder) } } - $cache = $builder->connection->config['cache_tables']; + $cache = key_exists('cache_tables',$builder->connection->config) ? $builder->connection->config['cache_tables'] : false; $types = []; foreach ($arrTables as $tables) { @@ -305,7 +374,6 @@ private function compile(Builder $builder) } } } - return $keys; } @@ -347,11 +415,7 @@ private function queryString(string $tables) } } - /** - * Get the default fetch mode for the connection. - * - * @return int - */ + public function getFetchMode() { return $this->fetchMode; @@ -451,28 +515,37 @@ protected function getDefaultPostProcessor() * * @param string $query * @param array $bindings - * @param Closure $callback + * @param \Closure $callback * @return mixed * - * @throws QueryException + * @throws \Illuminate\Database\QueryException */ protected function runQueryCallback($query, $bindings, Closure $callback) { try { $result = $callback($query, $bindings); - if ($result instanceof PDOStatement) { + if ($result instanceof \PDOStatement) { $errorInfo = $result->errorInfo(); if (isset($errorInfo[0]) && $errorInfo[0] !== '00000') { - $finalErrorMessage = sprintf('SQLSTATE[%s] [%d] %s', $errorInfo[0], (int) $errorInfo[1], - trim(preg_replace(['/^\[\d+]\s\(severity\s\d+\)\s/', '/\s+/'], ['', ' '], $errorInfo[2]))); - throw new PDOException($finalErrorMessage, (int) $errorInfo[1]); + $finalErrorMessage = sprintf( + 'SQLSTATE[%s] [%d] %s', + $errorInfo[0], + (int)$errorInfo[1], + trim(preg_replace(['/^\[\d+\]\s\(severity\s\d+\)\s/', '/\s+/'], ['', ' '], $errorInfo[2])) + ); + throw new \PDOException($finalErrorMessage, (int)$errorInfo[1]); } } return $result; } catch (Throwable $e) { - throw new QueryException($this->getName(), $query, $this->prepareBindings($bindings), $e); + throw new QueryException( + $this->getName(), + $query, + $this->prepareBindings($bindings), + $e + ); } } } diff --git a/src/Database/Schema/Grammar.php b/src/Database/Schema/Grammar.php index 6f20482..0ab2972 100644 --- a/src/Database/Schema/Grammar.php +++ b/src/Database/Schema/Grammar.php @@ -3,17 +3,25 @@ namespace Uepg\LaravelSybase\Database\Schema; use Illuminate\Database\Schema\Grammars\Grammar as IlluminateGrammar; +use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Fluent; class Grammar extends IlluminateGrammar { + /** + * The possible column modifiers. + * + * @var array + */ /** * The possible column modifiers. * * @var array */ protected $modifiers = [ - 'Increment', 'Nullable', 'Default', + 'Increment', + 'Nullable', + 'Default', ]; /** @@ -22,27 +30,19 @@ class Grammar extends IlluminateGrammar * @var array */ protected array $serials = [ - 'bigInteger', 'integer', 'numeric', + 'bigInteger', + 'integer', + 'numeric', ]; /** * Compile the query to determine if a table exists. - * @param string|null $schema - * @param string $table + * * @return string */ - public function compileTableExists($schema, $table) + public function compileTableExists($schema,$table) { - return sprintf(' - SELECT - COUNT(*) AS [exists] - FROM - sysobjects - WHERE - type = \'U\' - AND - name = \'%s\'; - ', $schema ? $schema.'.'.$table : $table); + return "SELECT id FROM sysobjects WHERE type = 'U' AND name = '$table'"; } /** @@ -105,7 +105,7 @@ public function compileAdd(Blueprint $blueprint, Fluent $command) * @return string * Functions do compile the columns of a given table */ - public function compileColumns($table) + public function compileColumns($schema,$table) { return "SELECT col.name, @@ -141,7 +141,7 @@ public function compileColumns($table) * @return string * Functions that return the indexes of a given table */ - public function compileIndexes($table) + public function compileIndexes($schema,$table) { return "SELECT DISTINCT i.name, @@ -239,8 +239,6 @@ public function compileIndex(Blueprint $blueprint, Fluent $command) /** * Compile a drop table command. * - * @param Blueprint $blueprint - * @param Fluent $command * @return string */ public function compileDrop(Blueprint $blueprint, Fluent $command) @@ -251,8 +249,6 @@ public function compileDrop(Blueprint $blueprint, Fluent $command) /** * Compile a drop table (if exists) command. * - * @param Blueprint $blueprint - * @param Fluent $command * @return string */ public function compileDropIfExists(Blueprint $blueprint, Fluent $command) @@ -270,6 +266,18 @@ public function compileDropIfExists(Blueprint $blueprint, Fluent $command) ) DROP TABLE ".$blueprint->getTable(); } + public function compileTables($schema) + { + return "select + o.name as name, + user_name(o.uid) as [schema], + cast(reserved_pages(db_id(), o.id) as bigint) * @@maxpagesize as size_bytes +from sysobjects o +where o.type = 'U' +order by o.name + "; + } + /** * Compile a drop column command. * @@ -283,7 +291,8 @@ public function compileDropColumn(Blueprint $blueprint, Fluent $command) $table = $this->wrapTable($blueprint); - return 'ALTER TABLE '.$table.' DROP COLUMN '.implode(', ', $columns); + return 'ALTER TABLE '.$table. + ' DROP COLUMN '.implode(', ', $columns); } /** @@ -331,14 +340,15 @@ public function compileDropIndex(Blueprint $blueprint, Fluent $command) /** * Compile a drop foreign key command. * - * @param Blueprint $blueprint - * @param Fluent $command + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command * @return string */ - public function compileDropForeign(Blueprint $blueprint, Fluent $command) + public function compileDropForeign(Blueprint $blueprint, Fluent $command): string { $table = $this->wrapTable($blueprint); + // O SQL que vocĂȘ postou antes: return "ALTER TABLE {$table} DROP CONSTRAINT {$command->index}"; } @@ -665,7 +675,7 @@ protected function modifyNullable(Blueprint $blueprint, Fluent $column) */ protected function modifyDefault(Blueprint $blueprint, Fluent $column) { - if (!is_null($column->default)) { + if (! is_null($column->default)) { return ' default '.$this->getDefaultValue($column->default); } } @@ -679,7 +689,10 @@ protected function modifyDefault(Blueprint $blueprint, Fluent $column) */ protected function modifyIncrement(Blueprint $blueprint, Fluent $column) { - if (in_array($column->type, $this->serials) && $column->autoIncrement) { + if ( + in_array($column->type, $this->serials) && + $column->autoIncrement + ) { return ' identity primary key'; } }