Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[11.x] Use Default Schema Name on SQL Server #50855

Merged
10 changes: 10 additions & 0 deletions src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php
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
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
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