1
1
from __future__ import annotations
2
2
3
3
import abc
4
+ import os
5
+ from typing import TYPE_CHECKING
6
+
4
7
from e3 .error import E3Error
5
8
from e3 .hash import sha1
6
- from typing import TYPE_CHECKING
7
9
8
10
if TYPE_CHECKING :
9
- from typing import Any , TypeVar , TypedDict
11
+ from typing import Any , TypeVar , TypedDict , Literal
10
12
11
13
from e3 .anod .store .buildinfo import BuildInfoDict
12
14
from e3 .anod .store .component import ComponentDict
13
15
from e3 .anod .store .file import FileDict
14
16
15
- _StoreContextManagerSelf = TypeVar (
16
- "_StoreContextManagerSelf " , bound = "_StoreContextManager"
17
+ StoreContextManagerType = TypeVar (
18
+ "StoreContextManagerType " , bound = "_StoreContextManager"
17
19
)
18
20
19
21
class BuildDataDict (TypedDict ):
@@ -25,7 +27,7 @@ class StoreError(E3Error):
25
27
pass
26
28
27
29
28
- def resource_id (path : str ) -> str :
30
+ def resource_id (path : os . PathLike [ str ] | str ) -> str :
29
31
"""Given a path to a file return the resource id.
30
32
31
33
:param path: a path to an existing path
@@ -38,15 +40,41 @@ class _StoreContextManager(metaclass=abc.ABCMeta):
38
40
"""A class to define the context manager interface needed by a Store class."""
39
41
40
42
@abc .abstractmethod
41
- def __enter__ (self : _StoreContextManagerSelf ) -> _StoreContextManagerSelf :
43
+ def __enter__ (self : StoreContextManagerType ) -> StoreContextManagerType :
44
+ """Enter in a new context.
45
+
46
+ This method is called when used with the "with" keyword. For example:
47
+
48
+ .. code-block:: python
49
+
50
+ with _StoreContextManager() as x:
51
+ pass
52
+
53
+ :return: Self
54
+ """
42
55
pass # all: no cover
43
56
44
57
@abc .abstractmethod
45
58
def __exit__ (self , * args : Any ) -> None :
59
+ """Exit a context.
60
+
61
+ This method is called when exiting a "with" context. For example:
62
+
63
+ .. code-block:: python
64
+
65
+ with _StoreContextManager() as x:
66
+ pass
67
+ # __exit__ is call here
68
+ """
46
69
pass # all: no cover
47
70
48
71
@abc .abstractmethod
49
72
def close (self ) -> None :
73
+ """Close the current context.
74
+
75
+ This method is used to close a context, generally not initiated using the
76
+ `with` keyword. See `builtin.open` for more example.
77
+ """
50
78
pass # all: no cover
51
79
52
80
@@ -327,11 +355,8 @@ def copy_build_id(self, bid: str, dest_setup: str) -> BuildInfoDict:
327
355
"""Copy a build id.
328
356
329
357
:param bid: a build id
330
- :type bid: str
331
358
:param dest_setup: setup destination different from source setup
332
- :type bid: str
333
359
:return: a dict representing a build id
334
- :rtype: dict
335
360
"""
336
361
337
362
@abc .abstractmethod
@@ -351,10 +376,128 @@ def add_component_attachment(
351
376
This function attach an ALREADY SUBMITTED file to a component.
352
377
353
378
:param component_id: the component id.
354
- :param name: the attachment name.
355
379
:param file_id: the id of the attachment file.
380
+ :param name: the attachment name.
356
381
"""
357
382
358
383
359
384
class StoreRWInterface (StoreReadInterface , StoreWriteInterface ):
360
385
pass
386
+
387
+
388
+ class LocalStoreInterface (object , metaclass = abc .ABCMeta ):
389
+ @abc .abstractmethod
390
+ def raw_add_build_info (self , build_info_data : BuildInfoDict ) -> None :
391
+ """Add a build info to the local store.
392
+
393
+ :param build_info_data: build info data (i.e: result of BuildInfo.to_dict())
394
+ """
395
+ raise NotImplementedError # all: no cover
396
+
397
+ @abc .abstractmethod
398
+ def add_build_info_from_store (
399
+ self , from_store : StoreReadInterface , bid : str
400
+ ) -> None :
401
+ """Add a build info to the local store from another store instance.
402
+
403
+ :param from_store: The other store instance where the buildinfo is retrieve.
404
+ :param bid: The buildinfo ID to retrieve.
405
+ """
406
+ raise NotImplementedError # all: no cover
407
+
408
+ @abc .abstractmethod
409
+ def raw_add_file (self , file_info : FileDict ) -> None :
410
+ """Add a file to the local store.
411
+
412
+ :param file_info: a file dict (i.e: result of File.as_dict()).
413
+ """
414
+ raise NotImplementedError # all: no cover
415
+
416
+ @abc .abstractmethod
417
+ def add_source_from_store (
418
+ self ,
419
+ from_store : StoreReadInterface ,
420
+ name : str ,
421
+ bid : str | None = None ,
422
+ setup : str | None = None ,
423
+ date : str = "all" ,
424
+ kind : Literal ["source" , "thirdparty" ] = "source" ,
425
+ ) -> None :
426
+ """Add a file info and all associated informations to the db.
427
+
428
+ The associated build id is also automatically added.
429
+
430
+ .. note::
431
+ If the file information is already present no call to the online store is
432
+ performed.
433
+
434
+ This method doesn't retrieve the resource pointed by the added file. Trying
435
+ to download the file without calling `add_resource` will raise an error.
436
+
437
+ :param from_store: instance of an online store to query.
438
+ :param name: the source name to retrieve.
439
+ :param bid: a build id.
440
+ :param setup: a setup name.
441
+ :param date: a build date.
442
+ :param kind: kind can be either source or thirdparty.
443
+ """
444
+ raise NotImplementedError # all: no cover
445
+
446
+ @abc .abstractmethod
447
+ def raw_add_component (self , component_info : ComponentDict ) -> None :
448
+ """Add a component to the local store.
449
+
450
+ :param component_info: a Component dict (i.e: result of Component.to_dict()).
451
+ """
452
+ raise NotImplementedError # all: no cover
453
+
454
+ @abc .abstractmethod
455
+ def add_component_from_store (
456
+ self ,
457
+ from_store : StoreReadInterface ,
458
+ setup : str ,
459
+ name : str = "all" ,
460
+ platform : str = "all" ,
461
+ date : str | None = None ,
462
+ specname : str | None = None ,
463
+ ) -> None :
464
+ """Add a component and all associated informatios to the db.
465
+
466
+ The associated build id is also automatically added
467
+
468
+ :param from_store: instance of an online store to query.
469
+ :param setup: a setup name.
470
+ :param name: a component name.
471
+ :param platform: a platform name.
472
+ :param date: a build date.
473
+ :param specname: the spec name related to the component.
474
+ """
475
+ raise NotImplementedError # all: no cover
476
+
477
+ @abc .abstractmethod
478
+ def save (self , filename : os .PathLike | None = None ) -> None :
479
+ """Save the local store database.
480
+
481
+ This function can does nothing and is hightly related to the LocalStore
482
+ implementation.
483
+
484
+ :param filename: the file path to save the database.
485
+ """
486
+ raise NotImplementedError # all: no cover
487
+
488
+ @abc .abstractmethod
489
+ def bulk_update_from_store (
490
+ self , from_store : StoreReadInterface , queries : list [dict [str , Any ]]
491
+ ) -> list [dict [str , Any ]]:
492
+ """Perform a list of update queries (source and components) to Store.
493
+
494
+ Each element of the queries list should conform to the specifications define by
495
+ self.bulk_query.
496
+
497
+ This function will populate the LocalStore depending of the queries.
498
+
499
+ :param from_store: instance of an online store to query.
500
+ :param queries: a list of queries
501
+ :return: a list of answers
502
+ """
503
+ raise NotImplementedError # all: no cover
0 commit comments