reydb 1.1.59__py3-none-any.whl → 1.1.61__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/rconfig.py CHANGED
@@ -9,8 +9,7 @@
9
9
  """
10
10
 
11
11
 
12
- from typing import TypedDict, TypeVar
13
- import datetime
12
+ from typing import TypedDict, TypeVar, Generic
14
13
  from datetime import (
15
14
  datetime as Datetime,
16
15
  date as Date,
@@ -24,7 +23,9 @@ from .rbase import DatabaseBase
24
23
 
25
24
 
26
25
  __all__ = (
26
+ 'DatabaseConfigSuper',
27
27
  'DatabaseConfig',
28
+ 'DatabaseConfigAsync'
28
29
  )
29
30
 
30
31
 
@@ -32,11 +33,12 @@ type ConfigValue = bool | str | int | float | list | tuple | dict | set | Dateti
32
33
  ConfigRow = TypedDict('ConfigRow', {'key': str, 'value': ConfigValue, 'type': str, 'note': str | None})
33
34
  type ConfigTable = list[ConfigRow]
34
35
  ConfigValueT = TypeVar('T', bound=ConfigValue) # Any.
36
+ DatabaseT = TypeVar('DatabaseT', 'rdb.Database', 'rdb.DatabaseAsync')
35
37
 
36
38
 
37
- class DatabaseConfig(DatabaseBase):
39
+ class DatabaseConfigSuper(DatabaseBase, Generic[DatabaseT]):
38
40
  """
39
- Database config type.
41
+ Database config super type.
40
42
  Can create database used `self.build_db` method.
41
43
 
42
44
  Examples
@@ -49,115 +51,75 @@ class DatabaseConfig(DatabaseBase):
49
51
  """
50
52
 
51
53
 
52
- def __init__(self, db: 'rdb.Database') -> None:
54
+ def __init__(
55
+ self,
56
+ db: DatabaseT,
57
+ db_names: dict[str, str] | None = None
58
+ ) -> None:
53
59
  """
54
60
  Build instance attributes.
55
61
 
56
62
  Parameters
57
63
  ----------
58
64
  db: Database instance.
65
+ db_names: Update build database table names.
59
66
  """
60
67
 
61
68
  # Build.
62
69
  self.db = db
63
-
64
- ## Database path name.
65
70
  self.db_names = {
66
- 'base': 'base',
67
- 'base.config': 'config',
68
- 'base.stats_config': 'stats_config'
71
+ 'config': 'config',
72
+ 'stats_config': 'stats_config'
69
73
  }
74
+ if db_names is not None:
75
+ self.db_names.update(db_names)
76
+
77
+
78
+ class DatabaseConfig(DatabaseConfigSuper['rdb.Database']):
79
+ """
80
+ Database config type.
81
+ Can create database used `self.build_db` method.
82
+
83
+ Examples
84
+ --------
85
+ >>> config = DatabaseConfig()
86
+ >>> config['key1'] = 1
87
+ >>> config['key2', 'note'] = 2
88
+ >>> config['key1'], config['key2']
89
+ (1, 2)
90
+ """
70
91
 
71
92
 
72
93
  def build_db(self) -> None:
73
94
  """
74
- Check and build all standard databases and tables, by `self.db_names`.
95
+ Check and build database tables, by `self.db_names`.
75
96
  """
76
97
 
77
- # Set parameter.
78
-
79
- ## Database.
80
- databases = [
81
- {
82
- 'name': self.db_names['base']
83
- }
84
- ]
98
+ # Handle parameter.
85
99
 
86
100
  ## Table.
87
- tables = [
88
-
89
- ### 'config'.
90
- {
91
- 'path': (self.db_names['base'], self.db_names['base.config']),
92
- 'fields': [
93
- {
94
- 'name': 'create_time',
95
- 'type': 'datetime',
96
- 'constraint': 'NOT NULL DEFAULT CURRENT_TIMESTAMP',
97
- 'comment': 'Config create time.'
98
- },
99
- {
100
- 'name': 'update_time',
101
- 'type': 'datetime',
102
- 'constraint': 'DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP',
103
- 'comment': 'Config update time.'
104
- },
105
- {
106
- 'name': 'key',
107
- 'type': 'varchar(50)',
108
- 'constraint': 'NOT NULL',
109
- 'comment': 'Config key.'
110
- },
111
- {
112
- 'name': 'value',
113
- 'type': 'text',
114
- 'constraint': 'NOT NULL',
115
- 'comment': 'Config value.'
116
- },
117
- {
118
- 'name': 'type',
119
- 'type': 'varchar(50)',
120
- 'constraint': 'NOT NULL',
121
- 'comment': 'Config value type.'
122
- },
123
- {
124
- 'name': 'note',
125
- 'type': 'varchar(500)',
126
- 'comment': 'Config note.'
127
- }
128
- ],
129
- 'primary': 'key',
130
- 'indexes': [
131
- {
132
- 'name': 'n_create_time',
133
- 'fields': 'create_time',
134
- 'type': 'noraml',
135
- 'comment': 'Config create time normal index.'
136
- },
137
- {
138
- 'name': 'n_update_time',
139
- 'fields': 'update_time',
140
- 'type': 'noraml',
141
- 'comment': 'Config update time normal index.'
142
- }
143
- ],
144
- 'comment': 'Config data table.'
145
- }
146
-
147
- ]
101
+ class Config(self.db.orm.Model, table=True):
102
+ __name__ = self.db_names['config']
103
+ __comment__ = 'Config data table.'
104
+ create_time: Datetime = self.db.orm.Field(not_null=True, field_default='CURRENT_TIMESTAMP', index_n=True, comment='Config create time.')
105
+ update_time: Datetime = self.db.orm.Field(field_default='CURRENT_TIMESTAMP', index_n=True, comment='Config update time.')
106
+ key: str = self.db.orm.Field(type=self.db.orm.types.VARCHAR(50), key=True, not_null=True, comment='Config key.')
107
+ value: str = self.db.orm.Field(type=self.db.orm.types.TEXT, not_null=True, comment='Config value.')
108
+ type: str = self.db.orm.Field(type=self.db.orm.types.VARCHAR(50), not_null=True, comment='Config value type.')
109
+ note: str = self.db.orm.Field(type=self.db.orm.types.VARCHAR(500), comment='Config note.')
110
+
111
+ tables = [Config]
148
112
 
149
113
  ## View stats.
150
114
  views_stats = [
151
-
152
- ### 'stats_config'.
153
115
  {
154
- 'path': (self.db_names['base'], self.db_names['base.stats_config']),
116
+ 'path': (self.db.database, self.db_names['stats_config']),
155
117
  'items': [
156
118
  {
157
119
  'name': 'count',
158
120
  'select': (
159
121
  'SELECT COUNT(1)\n'
160
- f'FROM `{self.db_names['base']}`.`{self.db_names['base.config']}`'
122
+ f'FROM `{self.db_names['config']}`'
161
123
  ),
162
124
  'comment': 'Config count.'
163
125
  },
@@ -165,7 +127,7 @@ class DatabaseConfig(DatabaseBase):
165
127
  'name': 'last_create_time',
166
128
  'select': (
167
129
  'SELECT MAX(`create_time`)\n'
168
- f'FROM `{self.db_names['base']}`.`{self.db_names['base.config']}`'
130
+ f'FROM `{self.db_names['config']}`'
169
131
  ),
170
132
  'comment': 'Config last record create time.'
171
133
  },
@@ -173,21 +135,19 @@ class DatabaseConfig(DatabaseBase):
173
135
  'name': 'last_update_time',
174
136
  'select': (
175
137
  'SELECT MAX(`update_time`)\n'
176
- f'FROM `{self.db_names['base']}`.`{self.db_names['base.config']}`'
138
+ f'FROM `{self.db_names['config']}`'
177
139
  ),
178
140
  'comment': 'Config last record update time.'
179
141
  }
180
142
  ]
181
-
182
143
  }
183
144
 
184
145
  ]
185
146
 
186
147
  # Build.
187
- self.db.build.build(databases, tables, views_stats=views_stats)
148
+ self.db.build.build(tables=tables, views_stats=views_stats, skip=True)
188
149
 
189
150
 
190
- @property
191
151
  def data(self) -> ConfigTable:
192
152
  """
193
153
  Get config data table.
@@ -199,13 +159,13 @@ class DatabaseConfig(DatabaseBase):
199
159
 
200
160
  # Get.
201
161
  result = self.db.execute.select(
202
- (self.db_names['base'], self.db_names['base.config']),
162
+ self.db_names['config'],
203
163
  ['key', 'value', 'type', 'note'],
204
164
  order='IFNULL(`update_time`, `create_time`) DESC'
205
165
  )
206
166
 
207
167
  # Convert.
208
- global_dict = {'datetime': datetime}
168
+ global_dict = {'datetime': Datetime}
209
169
  result = [
210
170
  {
211
171
  'key': row['key'],
@@ -235,7 +195,7 @@ class DatabaseConfig(DatabaseBase):
235
195
  # Get.
236
196
  where = '`key` = :key'
237
197
  result = self.db.execute.select(
238
- (self.db_names['base'], self.db_names['base.config']),
198
+ self.db_names['config'],
239
199
  '`value`',
240
200
  where,
241
201
  limit=1,
@@ -247,7 +207,7 @@ class DatabaseConfig(DatabaseBase):
247
207
  if value is None:
248
208
  value = default
249
209
  else:
250
- global_dict = {'datetime': datetime}
210
+ global_dict = {'datetime': Datetime}
251
211
  value = eval(value, global_dict)
252
212
 
253
213
  return value
@@ -260,7 +220,7 @@ class DatabaseConfig(DatabaseBase):
260
220
  default_note: str | None = None
261
221
  ) -> ConfigValue | ConfigValueT:
262
222
  """
263
- Set config value.
223
+ Set config default value.
264
224
 
265
225
  Parameters
266
226
  ----------
@@ -281,7 +241,7 @@ class DatabaseConfig(DatabaseBase):
281
241
  'note': default_note
282
242
  }
283
243
  result = self.db.execute.insert(
284
- (self.db_names['base'], self.db_names['base.config']),
244
+ self.db_names['config'],
285
245
  data,
286
246
  'ignore'
287
247
  )
@@ -322,7 +282,7 @@ class DatabaseConfig(DatabaseBase):
322
282
 
323
283
  # Update.
324
284
  self.db.execute.insert(
325
- (self.db_names['base'], self.db_names['base.config']),
285
+ self.db_names['config'],
326
286
  data,
327
287
  'update'
328
288
  )
@@ -345,7 +305,7 @@ class DatabaseConfig(DatabaseBase):
345
305
  where = '`key` in :key'
346
306
  limit = None
347
307
  result = self.db.execute.delete(
348
- (self.db_names['base'], self.db_names['base.config']),
308
+ self.db_names['base.config'],
349
309
  where,
350
310
  limit=limit,
351
311
  key=key
@@ -367,12 +327,12 @@ class DatabaseConfig(DatabaseBase):
367
327
 
368
328
  # Get.
369
329
  result = self.db.execute.select(
370
- (self.db_names['base'], self.db_names['base.config']),
330
+ self.db_names['config'],
371
331
  ['key', 'value']
372
332
  )
373
333
 
374
334
  # Convert.
375
- global_dict = {'datetime': datetime}
335
+ global_dict = {'datetime': Datetime}
376
336
  result = result.to_dict('key', 'value')
377
337
  result = {
378
338
  key: eval(value, global_dict)
@@ -393,12 +353,12 @@ class DatabaseConfig(DatabaseBase):
393
353
 
394
354
  # Get.
395
355
  result = self.db.execute.select(
396
- (self.db_names['base'], self.db_names['base.config']),
356
+ self.db_names['config'],
397
357
  '`key`'
398
358
  )
399
359
 
400
360
  # Convert.
401
- global_dict = {'datetime': datetime}
361
+ global_dict = {'datetime': Datetime}
402
362
  result = [
403
363
  eval(value, global_dict)
404
364
  for value in result
@@ -418,12 +378,12 @@ class DatabaseConfig(DatabaseBase):
418
378
 
419
379
  # Get.
420
380
  result = self.db.execute.select(
421
- (self.db_names['base'], self.db_names['base.config']),
381
+ self.db_names['config'],
422
382
  '`value`'
423
383
  )
424
384
 
425
385
  # Convert.
426
- global_dict = {'datetime': datetime}
386
+ global_dict = {'datetime': Datetime}
427
387
  result = [
428
388
  eval(value, global_dict)
429
389
  for value in result
@@ -480,7 +440,378 @@ class DatabaseConfig(DatabaseBase):
480
440
  'note': note
481
441
  }
482
442
  self.db.execute.insert(
483
- (self.db_names['base'], self.db_names['base.config']),
443
+ self.db_names['config'],
444
+ data,
445
+ 'update'
446
+ )
447
+
448
+
449
+ class DatabaseConfigAsync(DatabaseConfigSuper['rdb.DatabaseAsync']):
450
+ """
451
+ Asynchronous database config type.
452
+ Can create database used `self.build_db` method.
453
+
454
+ Examples
455
+ --------
456
+ >>> config = DatabaseConfig()
457
+ >>> config['key1'] = 1
458
+ >>> config['key2', 'note'] = 2
459
+ >>> config['key1'], config['key2']
460
+ (1, 2)
461
+ """
462
+
463
+
464
+ async def build_db(self) -> None:
465
+ """
466
+ Asynchronous check and build database tables, by `self.db_names`.
467
+ """
468
+
469
+ # Handle parameter.
470
+
471
+ ## Table.
472
+ class Config(self.db.orm.Model, table=True):
473
+ __name__ = self.db_names['config']
474
+ __comment__ = 'Config data table.'
475
+ create_time: Datetime = self.db.orm.Field(not_null=True, field_default='CURRENT_TIMESTAMP', index_n=True, comment='Config create time.')
476
+ update_time: Datetime = self.db.orm.Field(field_default='CURRENT_TIMESTAMP', index_n=True, comment='Config update time.')
477
+ key: str = self.db.orm.Field(type=self.db.orm.types.VARCHAR(50), key=True, not_null=True, comment='Config key.')
478
+ value: str = self.db.orm.Field(type=self.db.orm.types.TEXT, not_null=True, comment='Config value.')
479
+ type: str = self.db.orm.Field(type=self.db.orm.types.VARCHAR(50), not_null=True, comment='Config value type.')
480
+ note: str = self.db.orm.Field(type=self.db.orm.types.VARCHAR(500), comment='Config note.')
481
+
482
+ tables = [Config]
483
+
484
+ ## View stats.
485
+ views_stats = [
486
+ {
487
+ 'path': (self.db.database, self.db_names['stats_config']),
488
+ 'items': [
489
+ {
490
+ 'name': 'count',
491
+ 'select': (
492
+ 'SELECT COUNT(1)\n'
493
+ f'FROM `{self.db_names['config']}`'
494
+ ),
495
+ 'comment': 'Config count.'
496
+ },
497
+ {
498
+ 'name': 'last_create_time',
499
+ 'select': (
500
+ 'SELECT MAX(`create_time`)\n'
501
+ f'FROM `{self.db_names['config']}`'
502
+ ),
503
+ 'comment': 'Config last record create time.'
504
+ },
505
+ {
506
+ 'name': 'last_update_time',
507
+ 'select': (
508
+ 'SELECT MAX(`update_time`)\n'
509
+ f'FROM `{self.db_names['config']}`'
510
+ ),
511
+ 'comment': 'Config last record update time.'
512
+ }
513
+ ]
514
+ }
515
+
516
+ ]
517
+
518
+ # Build.
519
+ await self.db.build.build(tables=tables, views_stats=views_stats, skip=True)
520
+
521
+
522
+ async def data(self) -> ConfigTable:
523
+ """
524
+ Asynchronous get config data table.
525
+
526
+ Returns
527
+ -------
528
+ Config data table.
529
+ """
530
+
531
+ # Get.
532
+ result = await self.db.execute.select(
533
+ self.db_names['config'],
534
+ ['key', 'value', 'type', 'note'],
535
+ order='IFNULL(`update_time`, `create_time`) DESC'
536
+ )
537
+
538
+ # Convert.
539
+ global_dict = {'datetime': Datetime}
540
+ result = [
541
+ {
542
+ 'key': row['key'],
543
+ 'value': eval(row['value'], global_dict),
544
+ 'note': row['note']
545
+ }
546
+ for row in result
547
+ ]
548
+
549
+ return result
550
+
551
+
552
+ async def get(self, key: str, default: ConfigValueT | None = None) -> ConfigValue | ConfigValueT:
553
+ """
554
+ Asynchronous get config value, when not exist, then return default value.
555
+
556
+ Parameters
557
+ ----------
558
+ key : Config key.
559
+ default : Config default value.
560
+
561
+ Returns
562
+ -------
563
+ Config value.
564
+ """
565
+
566
+ # Get.
567
+ where = '`key` = :key'
568
+ result = await self.db.execute.select(
569
+ self.db_names['config'],
570
+ '`value`',
571
+ where,
572
+ limit=1,
573
+ key=key
574
+ )
575
+ value = result.scalar()
576
+
577
+ # Default.
578
+ if value is None:
579
+ value = default
580
+ else:
581
+ global_dict = {'datetime': Datetime}
582
+ value = eval(value, global_dict)
583
+
584
+ return value
585
+
586
+
587
+ async def setdefault(
588
+ self,
589
+ key: str,
590
+ default: ConfigValueT | None = None,
591
+ default_note: str | None = None
592
+ ) -> ConfigValue | ConfigValueT:
593
+ """
594
+ Asynchronous set config default value.
595
+
596
+ Parameters
597
+ ----------
598
+ key : Config key.
599
+ default : Config default value.
600
+ default_note : Config default note.
601
+
602
+ Returns
603
+ -------
604
+ Config value.
605
+ """
606
+
607
+ # Set.
608
+ data = {
609
+ 'key': key,
610
+ 'value': repr(default),
611
+ 'type': type(default).__name__,
612
+ 'note': default_note
613
+ }
614
+ result = await self.db.execute.insert(
615
+ self.db_names['config'],
616
+ data,
617
+ 'ignore'
618
+ )
619
+
620
+ # Get.
621
+ if result.rowcount == 0:
622
+ default = await self.get(key)
623
+
624
+ return default
625
+
626
+
627
+ async def update(self, data: dict[str, ConfigValue] | ConfigTable) -> None:
628
+ """
629
+ Asynchronous update config values.
630
+
631
+ Parameters
632
+ ----------
633
+ data : Config update data.
634
+ - `dict[str, Any]`: Config key and value.
635
+ - `ConfigTable`: Config key and value and note.
636
+ """
637
+
638
+ # Handle parameter.
639
+ if type(data) == dict:
640
+ data = [
641
+ {
642
+ 'key': key,
643
+ 'value': repr(value),
644
+ 'type': type(value).__name__
645
+ }
646
+ for key, value in data.items()
647
+ ]
648
+ else:
649
+ data = data.copy()
650
+ for row in data:
651
+ row['value'] = repr(row['value'])
652
+ row['type'] = type(row['value']).__name__
653
+
654
+ # Update.
655
+ await self.db.execute.insert(
656
+ self.db_names['config'],
657
+ data,
658
+ 'update'
659
+ )
660
+
661
+
662
+ async def remove(self, key: str | list[str]) -> None:
663
+ """
664
+ Asynchronous remove config.
665
+
666
+ Parameters
667
+ ----------
668
+ key : Config key or key list.
669
+ """
670
+
671
+ # Remove.
672
+ if type(key) == str:
673
+ where = '`key` = :key'
674
+ limit = 1
675
+ else:
676
+ where = '`key` in :key'
677
+ limit = None
678
+ result = await self.db.execute.delete(
679
+ self.db_names['base.config'],
680
+ where,
681
+ limit=limit,
682
+ key=key
683
+ )
684
+
685
+ # Check.
686
+ if result.rowcount == 0:
687
+ throw(KeyError, key)
688
+
689
+
690
+ async def items(self) -> dict[str, ConfigValue]:
691
+ """
692
+ Asynchronous get all config keys and values.
693
+
694
+ Returns
695
+ -------
696
+ All config keys and values.
697
+ """
698
+
699
+ # Get.
700
+ result = await self.db.execute.select(
701
+ self.db_names['config'],
702
+ ['key', 'value']
703
+ )
704
+
705
+ # Convert.
706
+ global_dict = {'datetime': Datetime}
707
+ result = result.to_dict('key', 'value')
708
+ result = {
709
+ key: eval(value, global_dict)
710
+ for key, value in result.items()
711
+ }
712
+
713
+ return result
714
+
715
+
716
+ async def keys(self) -> list[str]:
717
+ """
718
+ Asynchronous get all config keys.
719
+
720
+ Returns
721
+ -------
722
+ All config keys.
723
+ """
724
+
725
+ # Get.
726
+ result = await self.db.execute.select(
727
+ self.db_names['config'],
728
+ '`key`'
729
+ )
730
+
731
+ # Convert.
732
+ global_dict = {'datetime': Datetime}
733
+ result = [
734
+ eval(value, global_dict)
735
+ for value in result
736
+ ]
737
+
738
+ return result
739
+
740
+
741
+ async def values(self) -> list[ConfigValue]:
742
+ """
743
+ Asynchronous get all config value.
744
+
745
+ Returns
746
+ -------
747
+ All config values.
748
+ """
749
+
750
+ # Get.
751
+ result = await self.db.execute.select(
752
+ self.db_names['config'],
753
+ '`value`'
754
+ )
755
+
756
+ # Convert.
757
+ global_dict = {'datetime': Datetime}
758
+ result = [
759
+ eval(value, global_dict)
760
+ for value in result
761
+ ]
762
+
763
+ return result
764
+
765
+
766
+ async def __getitem__(self, key: str) -> ConfigValue:
767
+ """
768
+ Asynchronous get config value.
769
+
770
+ Parameters
771
+ ----------
772
+ key : Config key.
773
+
774
+ Returns
775
+ -------
776
+ Config value.
777
+ """
778
+
779
+ # Get.
780
+ value = await self.get(key, Null)
781
+
782
+ # Check.
783
+ if value == Null:
784
+ throw(KeyError, key)
785
+
786
+ return value
787
+
788
+
789
+ async def __setitem__(self, key_note: str | tuple[str, str], value: ConfigValue) -> None:
790
+ """
791
+ Asynchronous set config value.
792
+
793
+ Parameters
794
+ ----------
795
+ key_note : Config key and note.
796
+ value : Config value.
797
+ """
798
+
799
+ # Handle parameter.
800
+ if type(key_note) != str:
801
+ key, note = key_note
802
+ else:
803
+ key = key_note
804
+ note = None
805
+
806
+ # Set.
807
+ data = {
808
+ 'key': key,
809
+ 'value': repr(value),
810
+ 'type': type(value).__name__,
811
+ 'note': note
812
+ }
813
+ await self.db.execute.insert(
814
+ self.db_names['config'],
484
815
  data,
485
816
  'update'
486
817
  )