Skip to content

Commit

Permalink
[11.x] Use Default Schema Name on SQL Server (#50855)
Browse files Browse the repository at this point in the history
* get default schema name on sqlsrv

* force re-run tests

* add test

* wip

* wip

* wip

* wip

* revert adding test

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* formatting

---------

Co-authored-by: Taylor Otwell <taylor@laravel.com>
  • Loading branch information
hafezdivandari and taylorotwell authored Apr 1, 2024
1 parent 978ee88 commit 9e7ba35
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
10 changes: 10 additions & 0 deletions src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ class SqlServerGrammar extends Grammar
*/
protected $fluentCommands = ['Default'];

/**
* Compile a query to determine the name of the default schema.
*
* @return string
*/
public function compileDefaultSchema()
{
return 'select schema_name()';
}

/**
* Compile a create database command.
*
Expand Down
14 changes: 13 additions & 1 deletion src/Illuminate/Database/Schema/SqlServerBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public function hasTable($table)
{
[$schema, $table] = $this->parseSchemaAndTable($table);

$schema ??= $this->getDefaultSchema();
$table = $this->connection->getTablePrefix().$table;

foreach ($this->getTables() as $value) {
Expand All @@ -64,6 +65,7 @@ public function hasView($view)
{
[$schema, $view] = $this->parseSchemaAndTable($view);

$schema ??= $this->getDefaultSchema();
$view = $this->connection->getTablePrefix().$view;

foreach ($this->getViews() as $value) {
Expand Down Expand Up @@ -151,6 +153,16 @@ public function getForeignKeys($table)
);
}

/**
* Get the default schema for the connection.
*
* @return string
*/
protected function getDefaultSchema()
{
return $this->connection->scalar($this->grammar->compileDefaultSchema());
}

/**
* Parse the database object reference and extract the schema and table.
*
Expand All @@ -159,7 +171,7 @@ public function getForeignKeys($table)
*/
protected function parseSchemaAndTable($reference)
{
$parts = array_pad(explode('.', $reference, 2), -2, 'dbo');
$parts = array_pad(explode('.', $reference, 2), -2, null);

if (str_contains($parts[1], '.')) {
$database = $parts[0];
Expand Down
37 changes: 37 additions & 0 deletions tests/Integration/Database/SchemaBuilderSchemaNameTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,43 @@ public function testAutoIncrementStartingValue($connection)
});
}

#[DataProvider('connectionProvider')]
public function testHasTable($connection)
{
if ($this->driver !== 'sqlsrv') {
$this->markTestSkipped('Test requires a SQL Server connection.');
}

$db = DB::connection($connection);
$schema = $db->getSchemaBuilder();

try {
$db->statement("create login my_user with password = 'Passw0rd'");
$db->statement('create user my_user for login my_user');
} catch(\Illuminate\Database\QueryException $e) {
//
}

$db->statement('grant create table to my_user');
$db->statement('grant alter on SCHEMA::my_schema to my_user');
$db->statement("alter user my_user with default_schema = my_schema execute as user='my_user'");

config([
'database.connections.'.$connection.'.username' => 'my_user',
'database.connections.'.$connection.'.password' => 'Passw0rd',
]);

$this->assertEquals('my_schema', $db->scalar('select schema_name()'));

$schema->create('table', function (Blueprint $table) {
$table->id();
});

$this->assertTrue($schema->hasTable('table'));
$this->assertTrue($schema->hasTable('my_schema.table'));
$this->assertFalse($schema->hasTable('dbo.table'));
}

public static function connectionProvider(): array
{
return [
Expand Down

0 comments on commit 9e7ba35

Please sign in to comment.