Passed
Push — feature/collation ( 3b40b8...35613b )
by Kit Loong
64:11
created

SQLSrvRepository::getSpatialIndexNames()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 21
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 3
eloc 10
c 2
b 0
f 0
nc 2
nop 1
dl 0
loc 21
rs 9.9332
1
<?php
2
3
namespace KitLoong\MigrationsGenerator\Repositories;
4
5
use Illuminate\Support\Collection;
6
use KitLoong\MigrationsGenerator\MigrationsGeneratorSetting;
7
use KitLoong\MigrationsGenerator\Schema\SQLSrv\Column;
8
9
class SQLSrvRepository extends Repository
10
{
11
    const INDEX_TYPE_SPATIAL = 4;
12
13
    public function getSpatialIndexNames(string $table): Collection
14
    {
15
        $setting = app(MigrationsGeneratorSetting::class);
16
        $columns = $setting->getConnection()
17
            ->select("
18
                SELECT idx.name AS indexname
19
                FROM sys.tables AS tbl
20
                    JOIN sys.schemas AS scm ON tbl.schema_id = scm.schema_id
21
                    JOIN sys.indexes AS idx ON tbl.object_id = idx.object_id
22
                    JOIN sys.index_columns AS idxcol ON idx.object_id = idxcol.object_id AND idx.index_id = idxcol.index_id
23
                    JOIN sys.columns AS col ON idxcol.object_id = col.object_id AND idxcol.column_id = col.column_id
24
                WHERE ".$this->getTableWhereClause($table, 'scm.name', 'tbl.name')."
25
                    AND idx.type = ".self::INDEX_TYPE_SPATIAL."
26
                ");
27
        $definitions = collect([]);
28
        if (count($columns) > 0) {
29
            foreach ($columns as $column) {
30
                $definitions->push($column->indexname);
31
            }
32
        }
33
        return $definitions;
34
    }
35
36
    /**
37
     * @param  string  $table
38
     * @param  string  $column
39
     * @return \KitLoong\MigrationsGenerator\Schema\SQLSrv\Column|null
40
     */
41
    public function getColumnDefinition(string $table, string $column): ?Column
42
    {
43
        $setting = app(MigrationsGeneratorSetting::class);
44
        $columns = $setting->getConnection()
45
            ->select("
46
                SELECT col.name,
47
                       type.name AS type,
48
                       col.max_length AS length,
49
                       ~col.is_nullable AS notnull,
50
                       def.definition AS [default],
51
                       col.scale,
52
                       col.precision,
53
                       col.is_identity AS autoincrement,
54
                       col.collation_name AS collation,
55
                       CAST(prop.value AS NVARCHAR(MAX)) AS comment -- CAST avoids driver error for sql_variant type
56
                FROM sys.columns AS col
57
                    JOIN sys.types AS type
58
                        ON col.user_type_id = type.user_type_id
59
                    JOIN sys.objects AS obj
60
                        ON col.object_id = obj.object_id
61
                    JOIN sys.schemas AS scm
62
                        ON obj.schema_id = scm.schema_id
63
                    LEFT JOIN sys.default_constraints def
64
                        ON col.default_object_id = def.object_id
65
                            AND col.object_id = def.parent_object_id
66
                    LEFT JOIN sys.extended_properties AS prop
67
                        ON obj.object_id = prop.major_id
68
                            AND col.column_id = prop.minor_id
69
                            AND prop.name = 'MS_Description'
70
                WHERE obj.type = 'U'
71
                    AND ".$this->getTableWhereClause($table, 'scm.name', 'obj.name')."
72
                    AND col.name = ".$this->quoteStringLiteral($column)."
73
            ");
74
        if (count($columns) > 0) {
75
            $column = $columns[0];
76
            return new Column(
77
                $column->name,
78
                $column->type,
79
                $column->length,
80
                $column->notnull,
81
                $column->scale,
82
                $column->precision,
83
                $column->autoincrement,
84
                $column->default,
85
                $column->collation,
86
                $column->comment
87
            );
88
        }
89
        return null;
90
    }
91
92
    /**
93
     * Returns the where clause to filter schema and table name in a query.
94
     *
95
     * @param  string  $table  The full qualified name of the table.
96
     * @param  string  $schemaColumn  The name of the column to compare the schema to in the where clause.
97
     * @param  string  $tableColumn  The name of the column to compare the table to in the where clause.
98
     *
99
     * @return string
100
     */
101
    private function getTableWhereClause(string $table, string $schemaColumn, string $tableColumn): string
102
    {
103
        if (strpos($table, '.') !== false) {
104
            [$schema, $table] = explode('.', $table);
105
            $schema = $this->quoteStringLiteral($schema);
106
        } else {
107
            $schema = 'SCHEMA_NAME()';
108
        }
109
        $table = $this->quoteStringLiteral($table);
110
111
        return sprintf('(%s = %s AND %s = %s)', $tableColumn, $table, $schemaColumn, $schema);
112
    }
113
}
114