@@ -201,23 +201,24 @@ class TableName(StrEnum):
201
201
component_releases = "component_releases"
202
202
components = "components"
203
203
204
- def __init__ (self , db : os .PathLike | None = None ) -> None :
204
+ def __init__ (self , db : os .PathLike [ str ] | str | None = None ) -> None :
205
205
"""Initialize the Store class.
206
206
207
207
This will create the database and its tables (if needed).
208
208
209
209
:param db: A path to the database. If None, a new database is created with the
210
210
name `.store.db`.
211
211
"""
212
- self .connection = sqlite3 .connect (db or ".store.db" )
212
+ self .db_path = os .fspath (db or ".store.db" )
213
+ self .connection = sqlite3 .connect (self .db_path )
213
214
self .cursor = self .connection .cursor ()
214
215
self .cursor .execute (
215
216
f"CREATE TABLE IF NOT EXISTS { _Store .TableName .buildinfos } ("
216
217
" id TEXT NOT NULL PRIMARY KEY,"
217
218
" build_date TEXT NOT NULL,"
218
219
" setup TEXT NOT NULL,"
219
220
" creation_date TEXT NOT NULL DEFAULT("
220
- " STRFTIME('%Y-%m-%d %H:%M:%f+00:00', 'now')"
221
+ " STRFTIME('%Y-%m-%dT %H:%M:%f+00:00', 'now')"
221
222
" ),"
222
223
" build_version TEXT NOT NULL,"
223
224
" isready INTEGER NOT NULL DEFAULT 0 CHECK(isready in (0, 1))"
@@ -230,7 +231,7 @@ def __init__(self, db: os.PathLike | None = None) -> None:
230
231
" path TEXT NOT NULL,"
231
232
" size INTEGER NOT NULL,"
232
233
" creation_date TEXT NOT NULL DEFAULT("
233
- " STRFTIME('%Y-%m-%d %H:%M:%f+00:00', 'now')"
234
+ " STRFTIME('%Y-%m-%dT %H:%M:%f+00:00', 'now')"
234
235
" )"
235
236
")"
236
237
)
@@ -246,7 +247,7 @@ def __init__(self, db: os.PathLike | None = None) -> None:
246
247
" revision TEXT NOT NULL,"
247
248
" metadata TEXT NOT NULL,"
248
249
" creation_date TEXT NOT NULL DEFAULT("
249
- " STRFTIME('%Y-%m-%d %H:%M:%f+00:00', 'now')"
250
+ " STRFTIME('%Y-%m-%dT %H:%M:%f+00:00', 'now')"
250
251
" )"
251
252
")"
252
253
)
@@ -259,7 +260,7 @@ def __init__(self, db: os.PathLike | None = None) -> None:
259
260
" internal INTEGER NOT NULL DEFAULT 1 CHECK(internal IN (0, 1)),"
260
261
" attachment_name TEXT,"
261
262
" CHECK("
262
- " (attachment_name IS NOT NULL AND kind='attachment')"
263
+ " (attachment_name IS NOT NULL AND kind='attachment') "
263
264
" OR kind IN ('file', 'source')"
264
265
" )"
265
266
")"
@@ -280,7 +281,7 @@ def __init__(self, db: os.PathLike | None = None) -> None:
280
281
" specname TEXT," # Can be Null
281
282
" build_id TEXT NOT NULL,"
282
283
" creation_date TEXT NOT NULL DEFAULT("
283
- " STRFTIME('%Y-%m-%d %H:%M:%f+00:00', 'now')"
284
+ " STRFTIME('%Y-%m-%dT %H:%M:%f+00:00', 'now')"
284
285
" ),"
285
286
" is_valid INTEGER NOT NULL DEFAULT 1 CHECK(is_valid in (0, 1)),"
286
287
" is_published INTEGER NOT NULL DEFAULT 0 CHECK(is_published in (0, 1)),"
@@ -341,6 +342,7 @@ def _select(
341
342
if where_clause :
342
343
sql = f"{ sql } WHERE { where_clause } "
343
344
sql = f"{ sql } ORDER BY { order_by } "
345
+
344
346
return self .cursor .execute (sql , dynamic_where_values ).fetchall ()
345
347
346
348
def _select_one (
@@ -397,7 +399,7 @@ def _tuple_to_resource(cls, req_tuple: _Store.ResourceTuple) -> ResourceDict:
397
399
"""
398
400
_ , resource_id , path , size , creation_date = req_tuple
399
401
return {
400
- "_id " : resource_id ,
402
+ "id " : resource_id ,
401
403
"path" : path ,
402
404
"size" : size ,
403
405
"creation_date" : creation_date ,
@@ -447,7 +449,7 @@ def _tuple_to_file(
447
449
self ._select_one (_Store .TableName .buildinfos , build_id ) # type: ignore[arg-type]
448
450
)
449
451
450
- if not resource or resource ["_id " ] != resource_id :
452
+ if not resource or resource ["id " ] != resource_id :
451
453
resource = self ._tuple_to_resource (
452
454
self ._select_one (
453
455
_Store .TableName .resources , resource_id , field_name = "resource_id" # type: ignore[arg-type]
@@ -461,7 +463,7 @@ def _tuple_to_file(
461
463
"alias" : alias ,
462
464
"filename" : filename ,
463
465
"revision" : revision ,
464
- "metadata" : json .loads (metadata ) if metadata else None ,
466
+ "metadata" : json .loads (metadata ) if metadata else {} ,
465
467
"build_id" : str (build_id ),
466
468
"resource_id" : resource_id ,
467
469
"build" : buildinfo ,
@@ -729,7 +731,8 @@ def _tuple_to_comp(
729
731
else self ._list_component_files (
730
732
"attachment" , comp_id , component_buildinfo = buildinfo
731
733
)
732
- ),
734
+ )
735
+ or None ,
733
736
"build" : buildinfo ,
734
737
}
735
738
@@ -822,29 +825,29 @@ def create_thirdparty(self, file_info: FileDict) -> FileDict:
822
825
file_info ["revision" ] = ""
823
826
return self .submit_file (file_info )
824
827
825
- def submit_component (self , component_info : ComponentDict ) -> ComponentDict :
826
- """See e3.anod.store.interface.StoreWriteInterface."""
828
+ def _insert_to_component_files (
829
+ self ,
830
+ kind : Literal ["file" ] | Literal ["source" ] | Literal ["attachment" ],
831
+ file_list : Sequence [tuple [str | None , FileDict ]],
832
+ component_id : str | int ,
833
+ ) -> None :
834
+ """Insert a list of files to the component_files database table.
827
835
828
- def insert_to_component_files (
829
- kind : Literal ["file" ] | Literal ["source" ] | Literal ["attachment" ],
830
- file_list : Sequence [tuple [str | None , FileDict ]],
831
- component_id : str | int ,
832
- ) -> None :
833
- """Insert a list of files to the component_files database table.
834
-
835
- :param kind: The kind of file to insert.
836
- :param file_list: A sequence of tuples. The first element of this tuple must
837
- be None if the kind != attachment. Otherwise, this represents the
838
- attachment name. The second element should always be a FileDict.
839
- :param component_id: The component id linked to these files.
840
- """
841
- for att_name , f in file_list :
842
- self ._insert (
843
- _Store .TableName .component_files ,
844
- ["kind" , "file_id" , "component_id" , "attachment_name" ], # type: ignore[arg-type]
845
- [kind , f ["_id" ], component_id , att_name ],
846
- )
836
+ :param kind: The kind of file to insert.
837
+ :param file_list: A sequence of tuples. The first element of this tuple must
838
+ be None if the kind != attachment. Otherwise, this represents the
839
+ attachment name. The second element should always be a FileDict.
840
+ :param component_id: The component id linked to these files.
841
+ """
842
+ for att_name , f in file_list :
843
+ self ._insert (
844
+ _Store .TableName .component_files ,
845
+ ["kind" , "file_id" , "component_id" , "attachment_name" ], # type: ignore[arg-type]
846
+ [kind , f ["_id" ], component_id , att_name ],
847
+ )
847
848
849
+ def submit_component (self , component_info : ComponentDict ) -> ComponentDict :
850
+ """See e3.anod.store.interface.StoreWriteInterface."""
848
851
# Upload only readmes, binaries and attachments, as sources are supposed to be
849
852
# already there.
850
853
@@ -859,7 +862,7 @@ def insert_to_component_files(
859
862
# Retrieve binaries an upload them.
860
863
files = [self ._submit_file (file_info ) for file_info in component_info ["files" ]]
861
864
862
- # Retrieve attachment an upload them.
865
+ # Retrieve attachments and upload them.
863
866
attachments_with_name : dict [str , FileDict ] = {}
864
867
attachments = component_info .get ("attachments" )
865
868
if attachments :
@@ -914,10 +917,12 @@ def insert_to_component_files(
914
917
)
915
918
# Create relation between files/sources/attachment and the new component.
916
919
comp_id = req_tuple [0 ]
917
- insert_to_component_files ("file" , [(None , f ) for f in files ], comp_id )
920
+ self . _insert_to_component_files ("file" , [(None , f ) for f in files ], comp_id )
918
921
sources = component_info ["sources" ]
919
- insert_to_component_files ("source" , [(None , src ) for src in sources ], comp_id )
920
- insert_to_component_files (
922
+ self ._insert_to_component_files (
923
+ "source" , [(None , src ) for src in sources ], comp_id
924
+ )
925
+ self ._insert_to_component_files (
921
926
"attachment" , list (attachments_with_name .items ()), comp_id
922
927
)
923
928
# Add the list of releases linked to this component.
@@ -1002,12 +1007,12 @@ def update_file_metadata(self, file_info: FileDict) -> FileDict:
1002
1007
_Store .TableName .files ,
1003
1008
fid ,
1004
1009
["metadata" ], # type: ignore[arg-type]
1005
- [json .dumps (file_info ["metadata" ]) if file_info ["metadata" ] else "" ],
1010
+ [json .dumps (file_info ["metadata" ]) if file_info ["metadata" ] else "{} " ],
1006
1011
)
1007
1012
self .connection .commit ()
1008
1013
return self ._tuple_to_file (req_tuple , buildinfo = buildinfo ) # type: ignore[arg-type]
1009
1014
1010
- def add_component_attachment (
1015
+ def _add_component_attachment (
1011
1016
self , component_id : str , file_id : str , name : str
1012
1017
) -> None :
1013
1018
"""See e3.anod.store.interface.StoreWriteInterface."""
@@ -1016,6 +1021,12 @@ def add_component_attachment(
1016
1021
["kind" , "file_id" , "component_id" , "attachment_name" ], # type: ignore[arg-type]
1017
1022
["attachment" , file_id , component_id , name ],
1018
1023
)
1024
+
1025
+ def add_component_attachment (
1026
+ self , component_id : str , file_id : str , name : str
1027
+ ) -> None :
1028
+ """See e3.anod.store.interface.StoreWriteInterface."""
1029
+ self ._add_component_attachment (component_id , file_id , name )
1019
1030
self .connection .commit ()
1020
1031
1021
1032
### PRIVATE ###
@@ -1087,7 +1098,7 @@ def _submit_file(self, file_info: FileDict) -> FileDict:
1087
1098
file_info ["kind" ],
1088
1099
resource_id ,
1089
1100
file_info ["revision" ],
1090
- json .dumps (file_info ["metadata" ]) if file_info ["metadata" ] else "" ,
1101
+ json .dumps (file_info ["metadata" ]) if file_info ["metadata" ] else "{} " ,
1091
1102
],
1092
1103
)
1093
1104
res = self ._tuple_to_file (req_tuple , resource = resource ) # type: ignore[arg-type]
@@ -1258,7 +1269,7 @@ def get_build_info_list(
1258
1269
date = date or "all"
1259
1270
1260
1271
static_where_rules : tuple [str , ...]
1261
- if date == "all" :
1272
+ if not date or date == "all" :
1262
1273
static_where_rules = ()
1263
1274
else :
1264
1275
assert len (date ) == 8
0 commit comments