reykit 1.0.0__py3-none-any.whl → 1.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
reydb/rinformation.py ADDED
@@ -0,0 +1,515 @@
1
+ # !/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ """
5
+ @Time : 2022-12-05 14:10:02
6
+ @Author : Rey
7
+ @Contact : reyxbo@163.com
8
+ @Explain : Database information methods.
9
+ """
10
+
11
+
12
+ from __future__ import annotations
13
+ from typing import Any, Union, Literal, Optional, overload
14
+
15
+ from .rconnection import RDatabase, RDBConnection
16
+
17
+
18
+ __all__ = (
19
+ 'RDBInformation',
20
+ 'RDBISchema',
21
+ 'RDBIDatabase',
22
+ 'RDBITable',
23
+ 'RDBIColumn'
24
+ )
25
+
26
+
27
+ class RDBInformation(object):
28
+ """
29
+ Rey's `database base information` type.
30
+ """
31
+
32
+
33
+ @overload
34
+ def __call__(self: RDBISchema, name: Optional[str] = None) -> Union[RDBIDatabase, list[dict]]: ...
35
+
36
+ @overload
37
+ def __call__(self: RDBIDatabase, name: Optional[str] = None) -> Union[RDBITable, list[dict]]: ...
38
+
39
+ @overload
40
+ def __call__(self: RDBITable, name: Optional[str] = None) -> Union[RDBIColumn, list[dict]]: ...
41
+
42
+ @overload
43
+ def __call__(self: RDBIColumn, name: Optional[str] = None) -> dict: ...
44
+
45
+ def __call__(self, name: Optional[str] = None) -> Union[
46
+ RDBIDatabase,
47
+ RDBITable,
48
+ RDBIColumn,
49
+ list[dict],
50
+ dict
51
+ ]:
52
+ """
53
+ Get information table or subclass instance.
54
+
55
+ Parameters
56
+ ----------
57
+ name : Subclass index name.
58
+
59
+ Returns
60
+ -------
61
+ Information table or subclass instance.
62
+ """
63
+
64
+ # Information table.
65
+ if name is None:
66
+
67
+ ## Break.
68
+ if not hasattr(self, '_get_info_table'):
69
+ raise AssertionError("class '%s' does not have this method" % self.__class__.__name__)
70
+
71
+ ## Get.
72
+ result: list[dict] = self._get_info_table()
73
+
74
+ # Subobject.
75
+ else:
76
+
77
+ ## Break.
78
+ if not hasattr(self, '__getattr__'):
79
+ raise AssertionError("class '%s' does not have this method" % self.__class__.__name__)
80
+
81
+ ## Get.
82
+ result = self.__getattr__(name)
83
+
84
+ return result
85
+
86
+
87
+ @overload
88
+ def __getitem__(self, key: Literal['*', 'all', 'ALL']) -> dict: ...
89
+
90
+ @overload
91
+ def __getitem__(self, key: str) -> Any: ...
92
+
93
+ def __getitem__(self, key: str) -> Any:
94
+ """
95
+ Get information attribute value or dictionary.
96
+
97
+ Parameters
98
+ ----------
99
+ key : Attribute key. When key not exist, then try all caps key.
100
+ - `Literal['*', 'all', 'ALL']`: Get attribute dictionary.
101
+ - `str`: Get attribute value.
102
+
103
+ Returns
104
+ -------
105
+ Information attribute value or dictionary.
106
+ """
107
+
108
+ # Break.
109
+ if not hasattr(self, '_get_info_attrs'):
110
+ raise AssertionError("class '%s' does not have this method" % self.__class__.__name__)
111
+
112
+ # Get.
113
+ info_attrs: dict = self._get_info_attrs()
114
+
115
+ # Return.
116
+
117
+ ## Dictionary.
118
+ if key in ('*', 'all', 'ALL'):
119
+ return info_attrs
120
+
121
+ ## Value.
122
+ info_attr = info_attrs.get(key)
123
+ if info_attr is None:
124
+ key_upper = key.upper()
125
+ info_attr = info_attrs[key_upper]
126
+ return info_attr
127
+
128
+
129
+ @overload
130
+ def __getattr__(self, key: Literal['_rdatabase']) -> Union[RDatabase, RDBConnection]: ...
131
+
132
+ @overload
133
+ def __getattr__(self, key: Literal['_database_name', '_table_name']) -> str: ...
134
+
135
+ @overload
136
+ def __getattr__(self: RDBISchema, key: str) -> RDBIDatabase: ...
137
+
138
+ @overload
139
+ def __getattr__(self: RDBIDatabase, key: str) -> RDBITable: ...
140
+
141
+ @overload
142
+ def __getattr__(self: RDBITable, key: str) -> RDBIColumn: ...
143
+
144
+ def __getattr__(self, key: str) -> Union[
145
+ Union[RDatabase, RDBConnection],
146
+ str,
147
+ RDBIDatabase,
148
+ RDBITable,
149
+ RDBIColumn
150
+ ]:
151
+ """
152
+ Get attribute or build subclass instance.
153
+
154
+ Parameters
155
+ ----------
156
+ key : Attribute key or table name.
157
+
158
+ Returns
159
+ -------
160
+ Attribute or subclass instance.
161
+ """
162
+
163
+ # Filter private
164
+ if key in ('_rdatabase', '_database_name', '_table_name'):
165
+ return self.__dict__[key]
166
+
167
+ # Build.
168
+ match self:
169
+ case RDBISchema():
170
+ rtable = RDBIDatabase(self._rdatabase, key)
171
+ case RDBIDatabase():
172
+ rtable = RDBITable(self._rdatabase, self._database_name, key)
173
+ case RDBITable():
174
+ rtable = RDBIColumn(self._rdatabase, self._database_name, self._table_name, key)
175
+ case _:
176
+ raise AssertionError("class '%s' does not have this method" % self.__class__.__name__)
177
+
178
+ return rtable
179
+
180
+
181
+ class RDBISchema(RDBInformation):
182
+ """
183
+ Rey's `database information schema` type.
184
+
185
+ Examples
186
+ --------
187
+ Get databases information of server.
188
+ >>> databases_info = RDBISchema()
189
+
190
+ Get tables information of database.
191
+ >>> tables_info = RDBISchema.database()
192
+
193
+ Get columns information of table.
194
+ >>> columns_info = RDBISchema.database.table()
195
+
196
+ Get column information.
197
+ >>> column_info = RDBISchema.database.table.column()
198
+
199
+ Get database attribute.
200
+ >>> database_attr = RDBISchema.database['attribute']
201
+
202
+ Get table attribute.
203
+ >>> database_attr = RDBISchema.database.table['attribute']
204
+
205
+ Get column attribute.
206
+ >>> database_attr = RDBISchema.database.table.column['attribute']
207
+ """
208
+
209
+
210
+ def __init__(
211
+ self,
212
+ rdatabase: Union[RDatabase, RDBConnection]
213
+ ) -> None:
214
+ """
215
+ Build `database information schema` attributes.
216
+
217
+ Parameters
218
+ ----------
219
+ rdatabase : RDatabase or RDBConnection instance.
220
+ """
221
+
222
+ # Set parameter.
223
+ self._rdatabase = rdatabase
224
+
225
+
226
+ def _get_info_table(self) -> list[dict]:
227
+ """
228
+ Get information table.
229
+
230
+ Returns
231
+ -------
232
+ Information table.
233
+ """
234
+
235
+ # Select.
236
+ result = self._rdatabase.execute_select(
237
+ 'information_schema.SCHEMATA',
238
+ order='`schema_name`'
239
+ )
240
+
241
+ # Convert.
242
+ info_table = result.fetch_table()
243
+
244
+ return info_table
245
+
246
+
247
+ class RDBIDatabase(RDBInformation):
248
+ """
249
+ Rey's `database information database` type.
250
+
251
+ Examples
252
+ --------
253
+ Get tables information of database.
254
+ >>> tables_info = RDBIDatabase()
255
+
256
+ Get columns information of table.
257
+ >>> columns_info = RDBIDatabase.table()
258
+
259
+ Get column information.
260
+ >>> column_info = RDBIDatabase.table.column()
261
+
262
+ Get database attribute.
263
+ >>> database_attr = RDBIDatabase['attribute']
264
+
265
+ Get table attribute.
266
+ >>> database_attr = RDBIDatabase.table['attribute']
267
+
268
+ Get column attribute.
269
+ >>> database_attr = RDBIDatabase.table.column['attribute']
270
+ """
271
+
272
+
273
+ def __init__(
274
+ self,
275
+ rdatabase: Union[RDatabase, RDBConnection],
276
+ database_name: str
277
+ ) -> None:
278
+ """
279
+ Build `database information database` attributes.
280
+
281
+ Parameters
282
+ ----------
283
+ rdatabase : RDatabase or RDBConnection instance.
284
+ database_name : Database name.
285
+ """
286
+
287
+ # Set parameter.
288
+ self._rdatabase = rdatabase
289
+ self._database_name = database_name
290
+
291
+
292
+ def _get_info_attrs(self) -> dict:
293
+ """
294
+ Get information attribute dictionary.
295
+
296
+ Returns
297
+ -------
298
+ Information attribute dictionary.
299
+ """
300
+
301
+ # Select.
302
+ where = '`SCHEMA_NAME` = :database_name'
303
+ result = self._rdatabase.execute_select(
304
+ 'information_schema.SCHEMATA',
305
+ where=where,
306
+ limit=1,
307
+ database_name=self._database_name
308
+ )
309
+
310
+ # Check.
311
+ assert result.exist, "database '%s' not exist" % self._database_name
312
+
313
+ # Convert.
314
+ info_table = result.fetch_table()
315
+ info_attrs = info_table[0]
316
+
317
+ return info_attrs
318
+
319
+
320
+ def _get_info_table(self) -> list[dict]:
321
+ """
322
+ Get information table.
323
+
324
+ Returns
325
+ -------
326
+ Information table.
327
+ """
328
+
329
+ # Select.
330
+ where = '`TABLE_SCHEMA` = :database_name'
331
+ result = self._rdatabase.execute_select(
332
+ 'information_schema.TABLES',
333
+ where=where,
334
+ order='`TABLE_NAME`',
335
+ database_name=self._database_name
336
+ )
337
+
338
+ # Check.
339
+ assert result.exist, "database '%s' not exist" % self._database_name
340
+
341
+ # Convert.
342
+ info_table = result.fetch_table()
343
+
344
+ return info_table
345
+
346
+
347
+ class RDBITable(RDBInformation):
348
+ """
349
+ Rey's `database information table` type.
350
+
351
+ Examples
352
+ --------
353
+ Get columns information of table.
354
+ >>> columns_info = RDBITable()
355
+
356
+ Get column information.
357
+ >>> column_info = RDBITable.column()
358
+
359
+ Get table attribute.
360
+ >>> database_attr = RDBITable['attribute']
361
+
362
+ Get column attribute.
363
+ >>> database_attr = RDBITable.column['attribute']
364
+ """
365
+
366
+
367
+ def __init__(
368
+ self,
369
+ rdatabase: Union[RDatabase, RDBConnection],
370
+ database_name: str,
371
+ table_name: str
372
+ ) -> None:
373
+ """
374
+ Build `database information table` attributes.
375
+
376
+ Parameters
377
+ ----------
378
+ rdatabase : RDatabase or RDBConnection instance.
379
+ database_name : Database name.
380
+ table_name : Table name.
381
+ """
382
+
383
+ # Set parameter.
384
+ self._rdatabase = rdatabase
385
+ self._database_name = database_name
386
+ self._table_name = table_name
387
+
388
+
389
+ def _get_info_attrs(self) -> dict:
390
+ """
391
+ Get information attribute dictionary.
392
+
393
+ Returns
394
+ -------
395
+ Information attribute dictionary.
396
+ """
397
+
398
+ # Select.
399
+ where = '`TABLE_SCHEMA` = :database_name AND `TABLE_NAME` = :table_name'
400
+ result = self._rdatabase.execute_select(
401
+ 'information_schema.TABLES',
402
+ where=where,
403
+ limit=1,
404
+ database_name=self._database_name,
405
+ table_name=self._table_name
406
+ )
407
+
408
+ # Check.
409
+ assert result.exist, "database '%s' or table '%s' not exist" % (self._database_name, self._table_name)
410
+
411
+ # Convert.
412
+ info_table = result.fetch_table()
413
+ info_attrs = info_table[0]
414
+
415
+ return info_attrs
416
+
417
+
418
+ def _get_info_table(self) -> list[dict]:
419
+ """
420
+ Get information table.
421
+
422
+ Returns
423
+ -------
424
+ Information table.
425
+ """
426
+
427
+ # Select.
428
+ where = '`TABLE_SCHEMA` = :database_name AND `TABLE_NAME` = :table_name'
429
+ result = self._rdatabase.execute_select(
430
+ 'information_schema.COLUMNS',
431
+ where=where,
432
+ order='`ORDINAL_POSITION`',
433
+ database_name=self._database_name,
434
+ table_name=self._table_name
435
+ )
436
+
437
+ # Check.
438
+ assert result.exist, "database '%s' or table '%s' not exist" % (self._database_name, self._table_name)
439
+
440
+ # Convert.
441
+ info_table = result.fetch_table()
442
+
443
+ return info_table
444
+
445
+
446
+ class RDBIColumn(RDBInformation):
447
+ """
448
+ Rey's `database information column` type.
449
+
450
+ Examples
451
+ --------
452
+ Get column information.
453
+ >>> column_info = RDBIColumn()
454
+
455
+ Get column attribute.
456
+ >>> database_attr = RDBIColumn['attribute']
457
+ """
458
+
459
+
460
+ def __init__(
461
+ self,
462
+ rdatabase: Union[RDatabase, RDBConnection],
463
+ database_name: str,
464
+ table_name: str,
465
+ column_name: str
466
+ ) -> None:
467
+ """
468
+ Build `database information column` attributes.
469
+
470
+ Parameters
471
+ ----------
472
+ rdatabase : RDatabase or RDBConnection instance.
473
+ database_name : Database name.
474
+ table_name : Table name.
475
+ column_name : Column name.
476
+ """
477
+
478
+ # Set parameter.
479
+ self._rdatabase = rdatabase
480
+ self._database_name = database_name
481
+ self._table_name = table_name
482
+ self._column_name = column_name
483
+
484
+
485
+ def _get_info_attrs(self) -> dict:
486
+ """
487
+ Get information attribute dictionary.
488
+
489
+ Returns
490
+ -------
491
+ Information attribute dictionary.
492
+ """
493
+
494
+ # Select.
495
+ where = '`TABLE_SCHEMA` = :database_name AND `TABLE_NAME` = :table_name AND `COLUMN_NAME` = :column_name'
496
+ result = self._rdatabase.execute_select(
497
+ 'information_schema.COLUMNS',
498
+ where=where,
499
+ limit=1,
500
+ database_name=self._database_name,
501
+ table_name=self._table_name,
502
+ column_name=self._column_name
503
+ )
504
+
505
+ # Check.
506
+ assert result.exist, "database '%s' or table '%s' or column '%s' not exist" % (self._database_name, self._table_name, self._column_name)
507
+
508
+ # Convert.
509
+ info_table = result.fetch_table()
510
+ info_attrs = info_table[0]
511
+
512
+ return info_attrs
513
+
514
+
515
+ _get_info_table = _get_info_attrs