@@ -19,8 +19,13 @@ class MsSqlDriver implements Nette\Database\ISupplementalDriver
1919{
2020 use Nette \SmartObject;
2121
22+ /** @var Nette\Database\Connection */
23+ private $ connection ;
24+
25+
2226 public function initialize (Nette \Database \Connection $ connection , array $ options ): void
2327 {
28+ $ this ->connection = $ connection ;
2429 }
2530
2631
@@ -81,25 +86,123 @@ public function applyLimit(string &$sql, ?int $limit, ?int $offset): void
8186
8287 public function getTables (): array
8388 {
84- throw new Nette \NotImplementedException ;
89+ $ tables = [];
90+ foreach ($ this ->connection ->query ('SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE FROM INFORMATION_SCHEMA.TABLES ' ) as $ row ) {
91+ $ tables [] = [
92+ 'name ' => $ row ['TABLE_SCHEMA ' ] . '. ' . $ row ['TABLE_NAME ' ],
93+ 'view ' => ($ row ['TABLE_TYPE ' ] ?? null ) === 'VIEW ' ,
94+ ];
95+ }
96+ return $ tables ;
8597 }
8698
8799
88100 public function getColumns (string $ table ): array
89101 {
90- throw new Nette \NotImplementedException ;
102+ [$ table_schema , $ table_name ] = explode ('. ' , $ table );
103+ $ columns = [];
104+
105+ $ query = "
106+ SELECT
107+ COLUMN_NAME,
108+ DATA_TYPE,
109+ CHARACTER_MAXIMUM_LENGTH,
110+ NUMERIC_PRECISION,
111+ IS_NULLABLE,
112+ COLUMN_DEFAULT,
113+ DOMAIN_NAME
114+ FROM
115+ INFORMATION_SCHEMA.COLUMNS
116+ WHERE
117+ TABLE_SCHEMA = {$ this ->connection ->quote ($ table_schema )}
118+ AND TABLE_NAME = {$ this ->connection ->quote ($ table_name )}" ;
119+
120+ foreach ($ this ->connection ->query ($ query ) as $ row ) {
121+ $ columns [] = [
122+ 'name ' => $ row ['COLUMN_NAME ' ],
123+ 'table ' => $ table ,
124+ 'nativetype ' => strtoupper ($ row ['DATA_TYPE ' ]),
125+ 'size ' => $ row ['CHARACTER_MAXIMUM_LENGTH ' ] ?? ($ row ['NUMERIC_PRECISION ' ] ?? null ),
126+ 'unsigned ' => false ,
127+ 'nullable ' => $ row ['IS_NULLABLE ' ] === 'YES ' ,
128+ 'default ' => $ row ['COLUMN_DEFAULT ' ],
129+ 'autoincrement ' => $ row ['DOMAIN_NAME ' ] === 'COUNTER ' ,
130+ 'primary ' => $ row ['COLUMN_NAME ' ] === 'ID ' ,
131+ 'vendor ' => (array ) $ row ,
132+ ];
133+ }
134+ return $ columns ;
91135 }
92136
93137
94138 public function getIndexes (string $ table ): array
95139 {
96- throw new Nette \NotImplementedException ;
140+ [, $ table_name ] = explode ('. ' , $ table );
141+ $ indexes = [];
142+
143+ $ query = "
144+ SELECT
145+ name_index = ind.name,
146+ id_column = ic.index_column_id,
147+ name_column = col.name,
148+ ind.is_unique,
149+ ind.is_primary_key
150+ FROM
151+ sys.indexes ind
152+ INNER JOIN sys.index_columns ic ON ind.object_id = ic.object_id and ind.index_id = ic.index_id
153+ INNER JOIN sys.columns col ON ic.object_id = col.object_id and ic.column_id = col.column_id
154+ INNER JOIN sys.tables t ON ind.object_id = t.object_id
155+ WHERE
156+ t.name = {$ this ->connection ->quote ($ table_name )}
157+ ORDER BY
158+ t.name, ind.name, ind.index_id, ic.index_column_id " ;
159+
160+ foreach ($ this ->connection ->query ($ query ) as $ row ) {
161+ $ indexes [$ row ['name_index ' ]]['name ' ] = $ row ['name_index ' ];
162+ $ indexes [$ row ['name_index ' ]]['unique ' ] = $ row ['is_unique ' ] !== 'False ' ;
163+ $ indexes [$ row ['name_index ' ]]['primary ' ] = $ row ['is_primary_key ' ] !== 'False ' ;
164+ $ indexes [$ row ['name_index ' ]]['columns ' ][$ row ['id_column ' ] - 1 ] = $ row ['name_column ' ];
165+ }
166+ return array_values ($ indexes );
97167 }
98168
99169
100170 public function getForeignKeys (string $ table ): array
101171 {
102- throw new Nette \NotImplementedException ;
172+ [$ table_schema , $ table_name ] = explode ('. ' , $ table );
173+ $ keys = [];
174+
175+ $ query = "
176+ SELECT
177+ obj.name AS [fk_name],
178+ col1.name AS [column],
179+ tab2.name AS [referenced_table],
180+ col2.name AS [referenced_column]
181+ FROM
182+ sys.foreign_key_columns fkc
183+ INNER JOIN sys.objects obj
184+ ON obj.object_id = fkc.constraint_object_id
185+ INNER JOIN sys.tables tab1
186+ ON tab1.object_id = fkc.parent_object_id
187+ INNER JOIN sys.schemas sch
188+ ON tab1.schema_id = sch.schema_id
189+ INNER JOIN sys.columns col1
190+ ON col1.column_id = parent_column_id AND col1.object_id = tab1.object_id
191+ INNER JOIN sys.tables tab2
192+ ON tab2.object_id = fkc.referenced_object_id
193+ INNER JOIN sys.columns col2
194+ ON col2.column_id = referenced_column_id AND col2.object_id = tab2.object_id
195+ WHERE
196+ tab1.name = {$ this ->connection ->quote ($ table_name )}" ;
197+
198+ foreach ($ this ->connection ->query ($ query ) as $ id => $ row ) {
199+ $ keys [$ id ]['name ' ] = $ row ['fk_name ' ];
200+ $ keys [$ id ]['local ' ] = $ row ['column ' ];
201+ $ keys [$ id ]['table ' ] = $ table_schema . '. ' . $ row ['referenced_table ' ];
202+ $ keys [$ id ]['foreign ' ] = $ row ['referenced_column ' ];
203+ }
204+
205+ return array_values ($ keys );
103206 }
104207
105208
0 commit comments