reydb 1.1.56__py3-none-any.whl → 1.1.58__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/rdb.py CHANGED
@@ -9,29 +9,36 @@
9
9
  """
10
10
 
11
11
 
12
- from typing import Literal, overload
12
+ from typing import Generic
13
13
  from urllib.parse import quote as urllib_quote
14
14
  from pymysql.constants.CLIENT import MULTI_STATEMENTS
15
- from sqlalchemy import create_engine as sqlalchemy_create_engine
16
- from sqlalchemy.engine.base import Engine
15
+ from sqlalchemy import Engine, create_engine as sqlalchemy_create_engine
17
16
  from sqlalchemy.ext.asyncio import AsyncEngine, create_async_engine as sqlalchemy_create_async_engine
18
17
  from reykit.rtext import join_data_text
19
18
 
20
- from .rbase import DatabaseBase, extract_url
19
+ from . import rbase, rbuild, rconfig, rconn, rerror, rexec, rfile, rinfo, rorm, rparam
21
20
 
22
21
 
23
22
  __all__ = (
23
+ 'DatabaseSuper',
24
24
  'Database',
25
+ 'DatabaseAsync'
25
26
  )
26
27
 
27
28
 
28
- class Database(DatabaseBase):
29
+ class DatabaseSuper(
30
+ rbase.DatabaseBase,
31
+ Generic[
32
+ rbase.EngineT,
33
+ rbase.DatabaseConnectionT,
34
+ rbase.DatabaseExecuteT,
35
+ rbase.DatabaseSchemaT
36
+ ]
37
+ ):
29
38
  """
30
- Database type, based `MySQL`.
39
+ Database super type, based `MySQL`.
31
40
  """
32
41
 
33
- default_report: bool = False
34
-
35
42
 
36
43
  def __init__(
37
44
  self,
@@ -44,6 +51,7 @@ class Database(DatabaseBase):
44
51
  max_overflow: int = 10,
45
52
  pool_timeout: float = 30.0,
46
53
  pool_recycle: int | None = 3600,
54
+ report: bool = False,
47
55
  **query: str
48
56
  ) -> None:
49
57
  """
@@ -62,6 +70,7 @@ class Database(DatabaseBase):
62
70
  pool_recycle : Number of seconds `recycle` connection.
63
71
  - `None | Literal[-1]`: No recycle.
64
72
  - `int`: Use this value.
73
+ report : Whether report SQL execute information.
65
74
  query : Remote server database parameters.
66
75
  """
67
76
 
@@ -82,53 +91,40 @@ class Database(DatabaseBase):
82
91
  self.pool_recycle = -1
83
92
  else:
84
93
  self.pool_recycle = pool_recycle
94
+ self.report = report
85
95
  self.query = query
86
96
 
87
- # Create engine.
88
- self.engine = self.__create_engine(False)
89
- self.aengine = self.__create_engine(True)
90
-
91
-
92
- @property
93
- def backend(self) -> str:
94
- """
95
- Database backend name.
97
+ ## Create engine.
98
+ self.engine = self.__create_engine()
96
99
 
97
- Returns
98
- -------
99
- Name.
100
- """
101
-
102
- # Get.
103
- url = self.url(False)
104
- url_params = extract_url(url)
105
- backend = url_params['backend']
106
100
 
107
- return backend
108
-
109
-
110
- @property
111
- def driver(self) -> str:
101
+ def __str__(self) -> str:
112
102
  """
113
- Database driver name.
114
-
115
- Returns
116
- -------
117
- Name.
103
+ Return connection information text.
118
104
  """
119
105
 
120
- # Get.
121
- url = self.url(False)
122
- url_params = extract_url(url)
123
- driver = url_params['driver']
106
+ # Generate.
107
+ filter_key = (
108
+ 'engine',
109
+ 'connection',
110
+ 'rdatabase',
111
+ 'begin'
112
+ )
113
+ info = {
114
+ key: value
115
+ for key, value in self.__dict__.items()
116
+ if key not in filter_key
117
+ }
118
+ info['conn_count'] = self.conn_count
119
+ text = join_data_text(info)
124
120
 
125
- return driver
121
+ return text
126
122
 
127
123
 
128
124
  @property
129
- def abackend(self) -> str:
125
+ def backend(self) -> str:
130
126
  """
131
- Asynchronous database backend name.
127
+ Database backend name.
132
128
 
133
129
  Returns
134
130
  -------
@@ -136,17 +132,16 @@ class Database(DatabaseBase):
136
132
  """
137
133
 
138
134
  # Get.
139
- url = self.url(True)
140
- url_params = extract_url(url)
135
+ url_params = rbase.extract_url(self.url)
141
136
  backend = url_params['backend']
142
137
 
143
138
  return backend
144
139
 
145
140
 
146
141
  @property
147
- def adriver(self) -> str:
142
+ def driver(self) -> str:
148
143
  """
149
- Asynchronous database driver name.
144
+ Database driver name.
150
145
 
151
146
  Returns
152
147
  -------
@@ -154,21 +149,17 @@ class Database(DatabaseBase):
154
149
  """
155
150
 
156
151
  # Get.
157
- url = self.url(True)
158
- url_params = extract_url(url)
152
+ url_params = rbase.extract_url(self.url)
159
153
  driver = url_params['driver']
160
154
 
161
155
  return driver
162
156
 
163
157
 
164
- def url(self, is_async: bool) -> str:
158
+ @property
159
+ def url(self) -> str:
165
160
  """
166
161
  Generate server URL.
167
162
 
168
- Parameters
169
- ----------
170
- is_async : Whether to use asynchronous engine.
171
-
172
163
  Returns
173
164
  -------
174
165
  Server URL.
@@ -176,10 +167,11 @@ class Database(DatabaseBase):
176
167
 
177
168
  # Generate URL.
178
169
  password = urllib_quote(self.password)
179
- if is_async:
180
- url_ = f'mysql+aiomysql://{self.username}:{password}@{self.host}:{self.port}/{self.database}'
181
- else:
182
- url_ = f'mysql+pymysql://{self.username}:{password}@{self.host}:{self.port}/{self.database}'
170
+ match self:
171
+ case Database():
172
+ url_ = f'mysql+pymysql://{self.username}:{password}@{self.host}:{self.port}/{self.database}'
173
+ case DatabaseAsync():
174
+ url_ = f'mysql+aiomysql://{self.username}:{password}@{self.host}:{self.port}/{self.database}'
183
175
 
184
176
  # Add Server parameter.
185
177
  if self.query != {}:
@@ -194,29 +186,18 @@ class Database(DatabaseBase):
194
186
  return url_
195
187
 
196
188
 
197
- @overload
198
- def __create_engine(self, is_async: Literal[False]) -> Engine: ...
199
-
200
- @overload
201
- def __create_engine(self, is_async: Literal[True]) -> AsyncEngine: ...
202
-
203
- def __create_engine(self, is_async: bool) -> Engine | AsyncEngine:
189
+ def __create_engine(self) -> rbase.EngineT:
204
190
  """
205
191
  Create database `Engine` object.
206
192
 
207
- Parameters
208
- ----------
209
- is_async : Whether to use asynchronous engine.
210
-
211
193
  Returns
212
194
  -------
213
195
  Engine object.
214
196
  """
215
197
 
216
198
  # Handle parameter.
217
- url = self.url(is_async)
218
199
  engine_params = {
219
- 'url': url,
200
+ 'url': self.url,
220
201
  'pool_size': self.pool_size,
221
202
  'max_overflow': self.max_overflow,
222
203
  'pool_timeout': self.pool_timeout,
@@ -225,44 +206,27 @@ class Database(DatabaseBase):
225
206
  }
226
207
 
227
208
  # Create Engine.
228
- if is_async:
229
- engine = sqlalchemy_create_async_engine(**engine_params)
230
- else:
231
- engine = sqlalchemy_create_engine(**engine_params)
209
+ match self:
210
+ case Database():
211
+ engine = sqlalchemy_create_engine(**engine_params)
212
+ case DatabaseAsync():
213
+ engine = sqlalchemy_create_async_engine(**engine_params)
232
214
 
233
215
  return engine
234
216
 
235
217
 
236
- async def dispose(self) -> None:
237
- """
238
- Dispose asynchronous connections.
239
- """
240
-
241
- # Dispose.
242
- await self.aengine.dispose()
243
-
244
-
245
- def __conn_count(self, is_async: bool) -> tuple[int, int]:
218
+ @property
219
+ def conn_count(self) -> tuple[int, int]:
246
220
  """
247
221
  Count number of keep open and allowed overflow connection.
248
222
 
249
- Parameters
250
- ----------
251
- is_async : Whether to use asynchronous engine.
252
-
253
223
  Returns
254
224
  -------
255
225
  Number of keep open and allowed overflow connection.
256
226
  """
257
227
 
258
- # Handle parameter.
259
- if is_async:
260
- engine = self.aengine
261
- else:
262
- engine = self.engine
263
-
264
228
  # Count.
265
- _overflow: int = engine.pool._overflow
229
+ _overflow: int = self.engine.pool._overflow
266
230
  if _overflow < 0:
267
231
  keep_n = self.pool_size + _overflow
268
232
  overflow_n = 0
@@ -273,134 +237,66 @@ class Database(DatabaseBase):
273
237
  return keep_n, overflow_n
274
238
 
275
239
 
276
- @property
277
- def conn_count(self) -> tuple[int, int]:
278
- """
279
- Count number of keep open and allowed overflow connection.
280
-
281
- Returns
282
- -------
283
- Number of keep open and allowed overflow connection.
240
+ def connect(self, autocommit: bool = False) -> rbase.DatabaseConnectionT:
284
241
  """
242
+ Build database connection instance.
285
243
 
286
- # Count.
287
- keep_n, overflow_n = self.__conn_count(False)
288
-
289
- return keep_n, overflow_n
290
-
291
-
292
- @property
293
- def aconn_count(self) -> tuple[int, int]:
294
- """
295
- Count number of keep open and allowed overflow asynchronous connection.
244
+ Parameters
245
+ ----------
246
+ autocommit: Whether automatic commit execute.
296
247
 
297
248
  Returns
298
249
  -------
299
- Number of keep open and allowed overflow asynchronous connection.
250
+ Database connection instance.
300
251
  """
301
252
 
302
- # Count.
303
- keep_n, overflow_n = self.__conn_count(True)
253
+ # Build.
254
+ match self:
255
+ case Database():
256
+ conn = rconn.DatabaseConnection(self, autocommit)
257
+ case DatabaseAsync():
258
+ conn = rconn.DatabaseConnectionAsync(self, autocommit)
304
259
 
305
- return keep_n, overflow_n
260
+ return conn
306
261
 
307
262
 
308
- def schema(self, filter_default: bool = True) -> dict[str, dict[str, list[str]]]:
263
+ @property
264
+ def execute(self) -> rbase.DatabaseExecuteT:
309
265
  """
310
- Get schemata of databases and tables and columns.
311
-
312
- Parameters
313
- ----------
314
- filter_default : Whether filter default database.
266
+ Build database execute instance.
315
267
 
316
268
  Returns
317
269
  -------
318
- Schemata of databases and tables and columns.
270
+ Instance.
319
271
  """
320
272
 
321
- # Handle parameter.
322
- filter_db = (
323
- 'information_schema',
324
- 'performance_schema',
325
- 'mysql',
326
- 'sys'
327
- )
328
- if filter_default:
329
- where_database = 'WHERE `SCHEMA_NAME` NOT IN :filter_db\n'
330
- where_column = ' WHERE `TABLE_SCHEMA` NOT IN :filter_db\n'
331
- else:
332
- where_database = where_column = ''
333
-
334
- # Select.
335
- sql = (
336
- 'SELECT GROUP_CONCAT(`SCHEMA_NAME`) AS `TABLE_SCHEMA`, NULL AS `TABLE_NAME`, NULL AS `COLUMN_NAME`\n'
337
- 'FROM `information_schema`.`SCHEMATA`\n'
338
- f'{where_database}'
339
- 'UNION ALL (\n'
340
- ' SELECT `TABLE_SCHEMA`, `TABLE_NAME`, `COLUMN_NAME`\n'
341
- ' FROM `information_schema`.`COLUMNS`\n'
342
- f'{where_column}'
343
- ' ORDER BY `TABLE_SCHEMA`, `TABLE_NAME`, `ORDINAL_POSITION`\n'
344
- ')'
345
- )
346
- result = self.execute(sql, filter_db=filter_db)
347
-
348
- # Convert.
349
- database_names, *_ = result.fetchone()
350
- database_names: list[str] = database_names.split(',')
351
- schema_dict = {}
352
- for database, table, column in result:
353
- if database in database_names:
354
- database_names.remove(database)
355
-
356
- ## Index database.
357
- if database not in schema_dict:
358
- schema_dict[database] = {table: [column]}
359
- continue
360
- table_dict: dict = schema_dict[database]
361
-
362
- ## Index table.
363
- if table not in table_dict:
364
- table_dict[table] = [column]
365
- continue
366
- column_list: list = table_dict[table]
367
-
368
- ## Add column.
369
- column_list.append(column)
370
-
371
- ## Add empty database.
372
- for name in database_names:
373
- schema_dict[name] = None
273
+ # Build.
274
+ conn = self.connect(True)
275
+ exec = conn.execute
374
276
 
375
- return schema_dict
277
+ return exec
376
278
 
377
279
 
378
- def connect(self, autocommit: bool = False):
280
+ @property
281
+ def orm(self):
379
282
  """
380
- Build `DatabaseConnection` instance.
381
-
382
- Parameters
383
- ----------
384
- autocommit: Whether automatic commit execute.
283
+ Build database ORM instance.
385
284
 
386
285
  Returns
387
286
  -------
388
- Database connection instance.
287
+ Instance.
389
288
  """
390
289
 
391
- # Import.
392
- from .rconn import DatabaseConnection
393
-
394
290
  # Build.
395
- conn = DatabaseConnection(self, autocommit)
291
+ orm = rorm.DatabaseORM(self)
396
292
 
397
- return conn
293
+ return orm
398
294
 
399
295
 
400
296
  @property
401
- def execute(self):
297
+ def build(self):
402
298
  """
403
- Build `DatabaseExecute` instance.
299
+ Build database build instance.
404
300
 
405
301
  Returns
406
302
  -------
@@ -408,38 +304,31 @@ class Database(DatabaseBase):
408
304
  """
409
305
 
410
306
  # Build.
411
- dbconn = self.connect(True)
412
- exec = dbconn.execute
307
+ dbbuild = rbuild.DatabaseBuild(self)
413
308
 
414
- return exec
309
+ return dbbuild
415
310
 
416
311
 
417
- def aconnect(self, autocommit: bool = False):
312
+ @property
313
+ def file(self):
418
314
  """
419
- Build `DatabaseConnectionAsync` instance.
420
-
421
- Parameters
422
- ----------
423
- autocommit: Whether automatic commit execute.
315
+ Build database file instance.
424
316
 
425
317
  Returns
426
318
  -------
427
- Database connection instance.
319
+ Instance.
428
320
  """
429
321
 
430
- # Import.
431
- from .rconn import DatabaseConnectionAsync
432
-
433
322
  # Build.
434
- conn = DatabaseConnectionAsync(self, autocommit)
323
+ dbfile = rfile.DatabaseFile(self)
435
324
 
436
- return conn
325
+ return dbfile
437
326
 
438
327
 
439
328
  @property
440
- def aexecute(self):
329
+ def error(self):
441
330
  """
442
- Build `DatabaseConnectionAsync` instance.
331
+ Build database error instance.
443
332
 
444
333
  Returns
445
334
  -------
@@ -447,35 +336,31 @@ class Database(DatabaseBase):
447
336
  """
448
337
 
449
338
  # Build.
450
- dbconn = self.aconnect(True)
451
- exec = dbconn.aexecute
339
+ dbfile = rerror.DatabaseError(self)
452
340
 
453
- return exec
341
+ return dbfile
454
342
 
455
343
 
456
344
  @property
457
- def orm(self):
345
+ def config(self):
458
346
  """
459
- Build `DatabaseORM` instance.
347
+ Build database config instance.
460
348
 
461
349
  Returns
462
350
  -------
463
351
  Instance.
464
352
  """
465
353
 
466
- # Import.
467
- from .rorm import DatabaseORM
468
-
469
354
  # Build.
470
- orm = DatabaseORM(self)
355
+ dbconfig = rconfig.DatabaseConfig(self)
471
356
 
472
- return orm
357
+ return dbconfig
473
358
 
474
359
 
475
360
  @property
476
361
  def info(self):
477
362
  """
478
- Build `DatabaseInformationSchema` instance.
363
+ Build database information schema instance.
479
364
 
480
365
  Returns
481
366
  -------
@@ -502,125 +387,60 @@ class Database(DatabaseBase):
502
387
  >>> database_attr = DatabaseInformationSchema.database.table.column['attribute']
503
388
  """
504
389
 
505
- # Import.
506
- from .rinfo import DatabaseInformationSchema
507
-
508
390
  # Build.
509
- dbischema = DatabaseInformationSchema(self)
391
+ dbischema = rinfo.DatabaseInformationSchema(self)
510
392
 
511
393
  return dbischema
512
394
 
513
395
 
514
396
  @property
515
- def build(self):
397
+ def schema(self) -> rbase.DatabaseSchemaT:
516
398
  """
517
- Build `DatabaseBuild` instance.
399
+ Build database schema instance.
518
400
 
519
401
  Returns
520
402
  -------
521
403
  Instance.
522
404
  """
523
405
 
524
- # Import.
525
- from .rbuild import DatabaseBuild
526
-
527
406
  # Build.
528
- dbbuild = DatabaseBuild(self)
407
+ match self:
408
+ case Database():
409
+ schema = rparam.DatabaseSchema(self)
410
+ case DatabaseAsync():
411
+ schema = rparam.DatabaseSchemaAsync(self)
529
412
 
530
- return dbbuild
531
-
532
-
533
- @property
534
- def file(self):
535
- """
536
- Build `DatabaseFile` instance.
537
-
538
- Returns
539
- -------
540
- Instance.
541
- """
542
-
543
- # Import.
544
- from .rfile import DatabaseFile
545
-
546
- # Build.
547
- dbfile = DatabaseFile(self)
548
-
549
- return dbfile
550
-
551
-
552
- @property
553
- def error(self):
554
- """
555
- Build `DatabaseError` instance.
556
-
557
- Returns
558
- -------
559
- Instance.
560
- """
561
-
562
- # Import.
563
- from .rerror import DatabaseError
564
-
565
- # Build.
566
- dbfile = DatabaseError(self)
567
-
568
- return dbfile
569
-
570
-
571
- @property
572
- def config(self):
573
- """
574
- Build `DatabaseConfig` instance.
575
-
576
- Returns
577
- -------
578
- Instance.
579
- """
580
-
581
- # Import.
582
- from .rconfig import DatabaseConfig
583
-
584
- # Build.
585
- dbconfig = DatabaseConfig(self)
586
-
587
- return dbconfig
413
+ return schema
588
414
 
589
415
 
590
416
  @property
591
417
  def status(self):
592
418
  """
593
- Build `DatabaseParametersStatus` instance.
419
+ Build database parameters status instance.
594
420
 
595
421
  Returns
596
422
  -------
597
423
  Instance.
598
424
  """
599
425
 
600
- # Import.
601
- from .rparam import DatabaseParametersStatus
602
-
603
426
  # Build.
604
- dbps = DatabaseParametersStatus(self, False)
427
+ dbps = rparam.DatabaseParametersStatus(self, False)
605
428
 
606
429
  return dbps
607
430
 
608
431
 
609
432
  @property
610
- def global_status(self):
433
+ def status_global(self):
611
434
  """
612
- Build global `DatabaseParametersStatus` instance.
435
+ Build global database parameters status instance.
613
436
 
614
437
  Returns
615
438
  -------
616
439
  Instance.
617
440
  """
618
441
 
619
- # Import.
620
- from .rparam import DatabaseParametersStatus
621
-
622
442
  # Build.
623
- dbps = DatabaseParametersStatus(self, True)
443
+ dbps = rparam.DatabaseParametersStatus(self, True)
624
444
 
625
445
  return dbps
626
446
 
@@ -628,62 +448,67 @@ class Database(DatabaseBase):
628
448
  @property
629
449
  def variables(self):
630
450
  """
631
- Build `DatabaseParametersVariable` instance.
451
+ Build database parameters variable instance.
632
452
 
633
453
  Returns
634
454
  -------
635
455
  Instance.
636
456
  """
637
457
 
638
- # Import.
639
- from .rparam import DatabaseParametersVariable
640
-
641
458
  # Build.
642
- dbpv = DatabaseParametersVariable(self, False)
459
+ dbpv = rparam.DatabaseParametersVariable(self, False)
643
460
 
644
461
  return dbpv
645
462
 
646
463
 
647
464
  @property
648
- def global_variables(self):
465
+ def variables_global(self):
649
466
  """
650
- Build global `DatabaseParametersVariable` instance.
467
+ Build global database parameters variable instance.
651
468
 
652
469
  Returns
653
470
  -------
654
471
  Instance.
655
472
  """
656
473
 
657
- # Import.
658
- from .rparam import DatabaseParametersVariable
659
-
660
474
  # Build.
661
475
 
662
476
  ## SQLite.
663
- dbpv = DatabaseParametersVariable(self, True)
477
+ dbpv = rparam.DatabaseParametersVariable(self, True)
664
478
 
665
479
  return dbpv
666
480
 
667
481
 
668
- def __str__(self) -> str:
482
+ class Database(
483
+ DatabaseSuper[
484
+ Engine,
485
+ 'rconn.DatabaseConnection',
486
+ 'rexec.DatabaseExecute',
487
+ 'rparam.DatabaseSchema'
488
+ ]
489
+ ):
490
+ """
491
+ Database type, based `MySQL`.
492
+ """
493
+
494
+
495
+ class DatabaseAsync(
496
+ DatabaseSuper[
497
+ AsyncEngine,
498
+ 'rconn.DatabaseConnectionAsync',
499
+ 'rexec.DatabaseExecuteAsync',
500
+ 'rparam.DatabaseSchemaAsync'
501
+ ]
502
+ ):
503
+ """
504
+ Asynchronous database type, based `MySQL`.
505
+ """
506
+
507
+
508
+ async def dispose(self) -> None:
669
509
  """
670
- Return connection information text.
510
+ Dispose asynchronous connections.
671
511
  """
672
512
 
673
- # Generate.
674
- filter_key = (
675
- 'engine',
676
- 'connection',
677
- 'rdatabase',
678
- 'begin'
679
- )
680
- info = {
681
- key: value
682
- for key, value in self.__dict__.items()
683
- if key not in filter_key
684
- }
685
- info['conn_count'] = self.conn_count
686
- info['aconn_count'] = self.aconn_count
687
- text = join_data_text(info)
688
-
689
- return text
513
+ # Dispose.
514
+ await self.engine.dispose()