reydb 1.1.61__py3-none-any.whl → 1.2.0__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/rfile.py DELETED
@@ -1,482 +0,0 @@
1
- # !/usr/bin/env python
2
- # -*- coding: utf-8 -*-
3
-
4
- """
5
- @Time : 2023-10-29 20:01:25
6
- @Author : Rey
7
- @Contact : reyxbo@163.com
8
- @Explain : Database file methods.
9
- """
10
-
11
-
12
- from typing import TypedDict, overload
13
- from datetime import datetime
14
- from reykit.ros import File, Folder, get_md5
15
-
16
- from . import rdb
17
- from .rbase import DatabaseBase
18
-
19
-
20
- __all__ = (
21
- 'DatabaseFile',
22
- )
23
-
24
-
25
- FileInfo = TypedDict('FileInfo', {'create_time': datetime, 'md5': str, 'name': str | None, 'size': int, 'note': str | None})
26
-
27
-
28
- class DatabaseFile(DatabaseBase):
29
- """
30
- Database file type.
31
- Can create database used `self.build_db` method.
32
- """
33
-
34
-
35
- def __init__(self, db: 'rdb.Database') -> None:
36
- """
37
- Build instance attributes.
38
-
39
- Parameters
40
- ----------
41
- db: Database instance.
42
- """
43
-
44
- # Build.
45
- self.db = db
46
-
47
- ## Database path name.
48
- self.db_names = {
49
- 'file': 'file',
50
- 'file.information': 'information',
51
- 'file.data': 'data',
52
- 'file.stats': 'stats',
53
- 'file.data_information': 'data_information'
54
- }
55
-
56
-
57
- def build_db(self) -> None:
58
- """
59
- Check and build database tables, by `self.db_names`.
60
- """
61
-
62
- # Set parameter.
63
-
64
- ## Database.
65
- databases = [
66
- {
67
- 'name': self.db_names['file']
68
- }
69
- ]
70
-
71
- ## Table.
72
- tables = [
73
-
74
- ### 'information'.
75
- {
76
- 'path': (self.db_names['file'], self.db_names['file.information']),
77
- 'fields': [
78
- {
79
- 'name': 'create_time',
80
- 'type': 'datetime',
81
- 'constraint': 'NOT NULL DEFAULT CURRENT_TIMESTAMP',
82
- 'comment': 'Record create time.'
83
- },
84
- {
85
- 'name': 'file_id',
86
- 'type': 'mediumint unsigned',
87
- 'constraint': 'NOT NULL AUTO_INCREMENT',
88
- 'comment': 'File ID.'
89
- },
90
- {
91
- 'name': 'md5',
92
- 'type': 'char(32)',
93
- 'constraint': 'NOT NULL',
94
- 'comment': 'File MD5.'
95
- },
96
- {
97
- 'name': 'name',
98
- 'type': 'varchar(260)',
99
- 'comment': 'File name.'
100
- },
101
- {
102
- 'name': 'note',
103
- 'type': 'varchar(500)',
104
- 'comment': 'File note.'
105
- }
106
- ],
107
- 'primary': 'file_id',
108
- 'indexes': [
109
- {
110
- 'name': 'n_create_time',
111
- 'fields': 'create_time',
112
- 'type': 'noraml',
113
- 'comment': 'Record create time normal index.'
114
- },
115
- {
116
- 'name': 'n_md5',
117
- 'fields': 'md5',
118
- 'type': 'noraml',
119
- 'comment': 'File MD5 normal index.'
120
- },
121
- {
122
- 'name': 'n_name',
123
- 'fields': 'name',
124
- 'type': 'noraml',
125
- 'comment': 'File name normal index.'
126
- }
127
- ],
128
- 'comment': 'File information table.'
129
- },
130
-
131
- ### 'data'.
132
- {
133
- 'path': (self.db_names['file'], self.db_names['file.data']),
134
- 'fields': [
135
- {
136
- 'name': 'md5',
137
- 'type': 'char(32)',
138
- 'constraint': 'NOT NULL',
139
- 'comment': 'File MD5.'
140
- },
141
- {
142
- 'name': 'size',
143
- 'type': 'int unsigned',
144
- 'constraint': 'NOT NULL',
145
- 'comment': 'File byte size.'
146
- },
147
- {
148
- 'name': 'bytes',
149
- 'type': 'longblob',
150
- 'constraint': 'NOT NULL',
151
- 'comment': 'File bytes.'
152
- }
153
- ],
154
- 'primary': 'md5',
155
- 'comment': 'File data table.'
156
- }
157
-
158
- ]
159
-
160
- ## View.
161
- views = [
162
-
163
- ### Data information.
164
- {
165
- 'path': (self.db_names['file'], self.db_names['file.data_information']),
166
- 'select': (
167
- 'SELECT `b`.`last_time`, `a`.`md5`, `a`.`size`, `b`.`names`, `b`.`notes`\n'
168
- f'FROM `{self.db_names['file']}`.`{self.db_names['file.data']}` AS `a`\n'
169
- 'LEFT JOIN (\n'
170
- ' SELECT\n'
171
- ' `md5`,\n'
172
- " GROUP_CONCAT(DISTINCT(`name`) ORDER BY `create_time` DESC SEPARATOR ' | ') AS `names`,\n"
173
- " GROUP_CONCAT(DISTINCT(`note`) ORDER BY `create_time` DESC SEPARATOR ' | ') AS `notes`,\n"
174
- ' MAX(`create_time`) as `last_time`\n'
175
- f' FROM `{self.db_names['file']}`.`{self.db_names['file.information']}`\n'
176
- ' GROUP BY `md5`\n'
177
- ' ORDER BY `last_time` DESC\n'
178
- ') AS `b`\n'
179
- 'ON `a`.`md5` = `b`.`md5`\n'
180
- 'ORDER BY `last_time` DESC'
181
- )
182
- }
183
-
184
- ]
185
-
186
- ## View stats.
187
- views_stats = [
188
-
189
- ### 'stats'.
190
- {
191
- 'path': (self.db_names['file'], self.db_names['file.stats']),
192
- 'items': [
193
- {
194
- 'name': 'count',
195
- 'select': (
196
- 'SELECT COUNT(1)\n'
197
- f'FROM `{self.db_names['file']}`.`{self.db_names['file.information']}`'
198
- ),
199
- 'comment': 'File information count.'
200
- },
201
- {
202
- 'name': 'past_day_count',
203
- 'select': (
204
- 'SELECT COUNT(1)\n'
205
- f'FROM `{self.db_names['file']}`.`{self.db_names['file.information']}`\n'
206
- 'WHERE TIMESTAMPDIFF(DAY, `create_time`, NOW()) = 0'
207
- ),
208
- 'comment': 'File information count in the past day.'
209
- },
210
- {
211
- 'name': 'past_week_count',
212
- 'select': (
213
- 'SELECT COUNT(1)\n'
214
- f'FROM `{self.db_names['file']}`.`{self.db_names['file.information']}`\n'
215
- 'WHERE TIMESTAMPDIFF(DAY, `create_time`, NOW()) <= 6'
216
- ),
217
- 'comment': 'File information count in the past week.'
218
- },
219
- {
220
- 'name': 'past_month_count',
221
- 'select': (
222
- 'SELECT COUNT(1)\n'
223
- f'FROM `{self.db_names['file']}`.`{self.db_names['file.information']}`\n'
224
- 'WHERE TIMESTAMPDIFF(DAY, `create_time`, NOW()) <= 29'
225
- ),
226
- 'comment': 'File information count in the past month.'
227
- },
228
- {
229
- 'name': 'data_count',
230
- 'select': (
231
- 'SELECT COUNT(1)\n'
232
- f'FROM `{self.db_names['file']}`.`{self.db_names['file.data']}`'
233
- ),
234
- 'comment': 'File data unique count.'
235
- },
236
- {
237
- 'name': 'total_size',
238
- 'select': (
239
- 'SELECT FORMAT(SUM(`size`), 0)\n'
240
- f'FROM `{self.db_names['file']}`.`{self.db_names['file.data']}`'
241
- ),
242
- 'comment': 'File total byte size.'
243
- },
244
- {
245
- 'name': 'avg_size',
246
- 'select': (
247
- 'SELECT FORMAT(AVG(`size`), 0)\n'
248
- f'FROM `{self.db_names['file']}`.`{self.db_names['file.data']}`'
249
- ),
250
- 'comment': 'File average byte size.'
251
- },
252
- {
253
- 'name': 'max_size',
254
- 'select': (
255
- 'SELECT FORMAT(MAX(`size`), 0)\n'
256
- f'FROM `{self.db_names['file']}`.`{self.db_names['file.data']}`'
257
- ),
258
- 'comment': 'File maximum byte size.'
259
- },
260
- {
261
- 'name': 'last_time',
262
- 'select': (
263
- 'SELECT MAX(`create_time`)\n'
264
- f'FROM `{self.db_names['file']}`.`{self.db_names['file.information']}`'
265
- ),
266
- 'comment': 'File last record create time.'
267
- }
268
- ]
269
-
270
- }
271
-
272
- ]
273
-
274
- # Build.
275
- self.db.build.build(databases, tables, views, views_stats)
276
-
277
-
278
- def upload(
279
- self,
280
- source: str | bytes,
281
- name: str | None = None,
282
- note: str | None = None
283
- ) -> int:
284
- """
285
- Upload file.
286
-
287
- Parameters
288
- ----------
289
- source : File path or file bytes.
290
- name : File name.
291
- - `None`: Automatic set.
292
- `parameter 'file' is 'str'`: Use path file name.
293
- `parameter 'file' is 'bytes'`: No name.
294
- - `str`: Use this name.
295
- note : File note.
296
-
297
- Returns
298
- -------
299
- File ID.
300
- """
301
-
302
- # Handle parameter.
303
- conn = self.db.connect()
304
- match source:
305
-
306
- ## File path.
307
- case str():
308
- file = File(source)
309
- file_bytes = file.bytes
310
- file_md5 = get_md5(file_bytes)
311
- file_name = file.name_suffix
312
-
313
- ## File bytes.
314
- case bytes() | bytearray():
315
- if type(source) == bytearray:
316
- source = bytes(source)
317
- file_bytes = source
318
- file_md5 = get_md5(file_bytes)
319
- file_name = None
320
-
321
- ## File name.
322
- if name is not None:
323
- file_name = name
324
-
325
- ## File size.
326
- file_size = len(file_bytes)
327
-
328
- # Exist.
329
- exist = conn.execute.exist(
330
- self.db_names['file.data'],
331
- '`md5` = :file_md5',
332
- file_md5=file_md5
333
- )
334
-
335
- # Upload.
336
-
337
- ## Data.
338
- if not exist:
339
- data = {
340
- 'md5': file_md5,
341
- 'size': file_size,
342
- 'bytes': file_bytes
343
- }
344
- conn.execute.insert(
345
- self.db_names['file.data'],
346
- data,
347
- 'ignore'
348
- )
349
-
350
- ## Information.
351
- data = {
352
- 'md5': file_md5,
353
- 'name': file_name,
354
- 'note': note
355
- }
356
- conn.execute.insert(
357
- self.db_names['file.information'],
358
- data
359
- )
360
-
361
- # Get ID.
362
- file_id = conn.insert_id()
363
-
364
- # Commit.
365
- conn.commit()
366
-
367
- return file_id
368
-
369
-
370
- @overload
371
- def download(
372
- self,
373
- file_id: int,
374
- path: None = None
375
- ) -> bytes: ...
376
-
377
- @overload
378
- def download(
379
- self,
380
- file_id: int,
381
- path: str
382
- ) -> str: ...
383
-
384
- def download(
385
- self,
386
- file_id: int,
387
- path: str | None = None
388
- ) -> bytes | str:
389
- """
390
- Download file.
391
-
392
- Parameters
393
- ----------
394
- file_id : File ID.
395
- path : File save path.
396
- - `None`: Not save and return file bytes.
397
- - `str`: Save and return file path.
398
- `File path`: Use this file path.
399
- `Folder path`: Use this folder path and original name.
400
-
401
- Returns
402
- -------
403
- File bytes or file path.
404
- """
405
-
406
- # Generate SQL.
407
- sql = (
408
- 'SELECT `name`, (\n'
409
- ' SELECT `bytes`\n'
410
- f' FROM `{self.db_names['file']}`.`{self.db_names['file.data']}`\n'
411
- f' WHERE `md5` = `{self.db_names['file.information']}`.`md5`\n'
412
- ' LIMIT 1\n'
413
- ') AS `bytes`\n'
414
- f'FROM `{self.db_names['file']}`.`{self.db_names['file.information']}`\n'
415
- 'WHERE `file_id` = :file_id\n'
416
- 'LIMIT 1'
417
- )
418
-
419
- # Execute SQL.
420
- result = self.db.execute(sql, file_id=file_id)
421
-
422
- # Check.
423
- if result.empty:
424
- text = "file ID '%s' not exist or no data" % file_id
425
- raise ValueError(text)
426
- file_name, file_bytes = result.first()
427
-
428
- # Not save.
429
- if path is None:
430
- return file_bytes
431
-
432
- # Save.
433
- else:
434
- folder = Folder(path)
435
- if folder:
436
- path = folder + file_name
437
- file = File(path)
438
- file(file_bytes)
439
- return file.path
440
-
441
-
442
- def query(
443
- self,
444
- file_id: int
445
- ) -> FileInfo:
446
- """
447
- Query file information.
448
-
449
- Parameters
450
- ----------
451
- file_id : File ID.
452
-
453
- Returns
454
- -------
455
- File information.
456
- """
457
-
458
- # Generate SQL.
459
- sql = (
460
- 'SELECT `create_time`, `md5`, `name`, `note`, (\n'
461
- ' SELECT `size`\n'
462
- f' FROM `{self.db_names['file']}`.`{self.db_names['file.data']}`\n'
463
- ' WHERE `md5` = `a`.`md5`\n'
464
- ' LIMIT 1\n'
465
- ') AS `size`\n'
466
- f'FROM `{self.db_names['file']}`.`{self.db_names['file.information']}` AS `a`\n'
467
- 'WHERE `file_id` = :file_id\n'
468
- 'LIMIT 1'
469
- )
470
-
471
- # Execute SQL.
472
- result = self.db.execute(sql, file_id=file_id)
473
-
474
- # Check.
475
- if result.empty:
476
- raise AssertionError('file ID does not exist')
477
-
478
- # Convert.
479
- table = result.to_table()
480
- info = table[0]
481
-
482
- return info
@@ -1,16 +0,0 @@
1
- reydb/__init__.py,sha256=zuQ14sl7rZ6lQ1P566ALjiRi-PcIXj9Ff0U_yYNQHFE,581
2
- reydb/rall.py,sha256=8tWDeGRLKujqPHFy4898WCIgZEA4OxOfeQ8xG6Fw69c,387
3
- reydb/rbase.py,sha256=16fG_YWnvJFu0ElXvc3BS9PtSJFZ9M631Te0b2ewWDE,9457
4
- reydb/rbuild.py,sha256=-C8ORqJSa6tDBMm7Y-ZcN80sgWs5rX6I0aO0DioXNm4,46599
5
- reydb/rconfig.py,sha256=mA40xrC5O9Y3lHnuJYDRUqRsLk3s2BFxgXou2tnFAXM,21196
6
- reydb/rconn.py,sha256=guRaR8N6RuzZzujwaeq7HhKWTizF9SrUBqEAFjfjpoo,6909
7
- reydb/rdb.py,sha256=Dh0J26fIfRrX8EK25cH1MfFzPLmWC-VnvXjLgiS_wFM,13824
8
- reydb/rerror.py,sha256=309PJVQG7jsL2A2R5IW4zuS4IojBgoGx3qxwIotBh_k,9896
9
- reydb/rexec.py,sha256=sOiapQnnbMhnItgYhUZ4iz8xRolsUJz6inCH1-7hb54,52074
10
- reydb/rfile.py,sha256=usK1W39O3Fi7FoAljhDIFgqj15c1GrQv3ASYUt1IxdA,15087
11
- reydb/rorm.py,sha256=heJf_vVJgjlNNQHbkpS_Q2rk8CBmRdOOSO7RZBfHulE,40355
12
- reydb/rparam.py,sha256=hXpnT4YnTgZFjyuc6bf2TCc-p1HQ7ycJjamq7I1xook,12851
13
- reydb-1.1.61.dist-info/METADATA,sha256=U2Xa2A4pdO1OKHmYgzphmIWh0cma7fCBi31grlX8iwQ,1622
14
- reydb-1.1.61.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
15
- reydb-1.1.61.dist-info/licenses/LICENSE,sha256=UYLPqp7BvPiH8yEZduJqmmyEl6hlM3lKrFIefiD4rvk,1059
16
- reydb-1.1.61.dist-info/RECORD,,
File without changes