├── .gitignore ├── .pyrustic └── buildver │ └── build_report ├── LICENSE ├── MANIFEST.in ├── README.md ├── VERSION ├── docs └── api │ ├── MIKEDOC │ ├── README.md │ └── modules │ └── jinbase │ ├── __init__ │ ├── README.md │ ├── class-Jinbase.md │ ├── class-Model.md │ ├── class-RecordInfo.md │ ├── class-TimestampPrecision.md │ ├── class-TypeRef.md │ └── fields.md │ ├── blob │ └── __init__ │ │ ├── README.md │ │ └── class-Blob.md │ ├── const │ └── __init__ │ │ ├── README.md │ │ ├── class-Model.md │ │ ├── class-StorageUnit.md │ │ ├── class-TimeUnit.md │ │ ├── class-TimestampPrecision.md │ │ └── fields.md │ └── store │ ├── __init__ │ ├── README.md │ ├── class-RecordInfo.md │ └── class-Store.md │ ├── depot │ ├── README.md │ └── class-Depot.md │ ├── kv │ ├── README.md │ └── class-Kv.md │ ├── queue │ ├── README.md │ └── class-Queue.md │ └── stack │ ├── README.md │ └── class-Stack.md ├── mikedoc.kvf ├── pyproject.toml ├── setup.cfg ├── setup.py ├── src └── jinbase │ ├── __init__.py │ ├── __main__.py │ ├── blob │ └── __init__.py │ ├── const │ └── __init__.py │ ├── errors │ └── __init__.py │ ├── misc │ └── __init__.py │ ├── queries │ └── __init__.py │ ├── store │ ├── __init__.py │ ├── depot.py │ ├── kv.py │ ├── queue.py │ └── stack.py │ └── transaction_policy.txt └── tests ├── __init__.py ├── __main__.py ├── test_blob.py ├── test_depot.py ├── test_imports.py ├── test_jinbase.py ├── test_kv.py ├── test_misc.py ├── test_queue.py └── test_stack.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Python 2 | __pycache__/ 3 | *.py[cod] 4 | build/ 5 | dist/ 6 | *.egg-info/ 7 | 8 | # Environments 9 | venv/ 10 | env/ 11 | 12 | # PyCharm 13 | .idea/ 14 | 15 | -------------------------------------------------------------------------------- /.pyrustic/buildver/build_report: -------------------------------------------------------------------------------- 1 | 0.0.5 1733864063 2 | 0.0.4 1733863804 3 | 0.0.3 1732907360 4 | 0.0.2 1732573634 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023, 2024 Pyrustic Architect 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include VERSION 2 | recursive-include src * 3 | global-exclude *.py[cod] 4 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 0.0.6 -------------------------------------------------------------------------------- /docs/api/MIKEDOC: -------------------------------------------------------------------------------- 1 | API Reference generated with [MikeDoc](https://github.com/pyrustic/mikedoc). 2 | -------------------------------------------------------------------------------- /docs/api/README.md: -------------------------------------------------------------------------------- 1 | # Jinbase API Reference 2 | Here are modules that make up [Jinbase](/README.md): 3 | 4 | [jinbase.\_\_init\_\_](/docs/api/modules/jinbase/__init__/README.md) 5 |
6 | The main module of Jinbase. 7 | 8 | [jinbase.blob.\_\_init\_\_](/docs/api/modules/jinbase/blob/__init__/README.md) 9 |
10 | The Blob class is defined here. 11 | 12 | [jinbase.const.\_\_init\_\_](/docs/api/modules/jinbase/const/__init__/README.md) 13 |
14 | Project-wide constants are defined in this module. 15 | 16 | [jinbase.store.\_\_init\_\_](/docs/api/modules/jinbase/store/__init__/README.md) 17 |
18 | The abstract Store class is defined in this module. 19 | 20 | [jinbase.store.depot](/docs/api/modules/jinbase/store/depot/README.md) 21 |
22 | The Depot store is defined in this module. 23 | 24 | [jinbase.store.kv](/docs/api/modules/jinbase/store/kv/README.md) 25 |
26 | The Kv store is defined in this module. 27 | 28 | [jinbase.store.queue](/docs/api/modules/jinbase/store/queue/README.md) 29 |
30 | The Queue store is defined in this module. 31 | 32 | [jinbase.store.stack](/docs/api/modules/jinbase/store/stack/README.md) 33 |
34 | The Stack store is defined in this module. 35 | 36 |

Back to top

37 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/__init__/README.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | Module | [Source](/src/jinbase/__init__.py) 3 | 4 | # Module Overview 5 | > Module: **jinbase.\_\_init\_\_** 6 | 7 | The main module of Jinbase. 8 | 9 | ## Fields 10 | - [**All fields**](/docs/api/modules/jinbase/__init__/fields.md) 11 | - CHUNK\_SIZE = `1048576` 12 | - DATETIME\_FORMAT = `'%Y-%m-%d %H:%M:%S.%fZ'` 13 | - JINBASE\_HOME = `'/home/alex/JinbaseHome'` 14 | - JINBASE\_VERSION = `1` 15 | - TIMEOUT = `5.0` 16 | - TIMESTAMP\_PRECISION = `` 17 | - USER\_HOME = `'/home/alex'` 18 | 19 |

Back to top

20 | 21 | ## Classes 22 | - [**Jinbase**](/docs/api/modules/jinbase/__init__/class-Jinbase.md): The Jinbase class. A Jinbase object is intended to be directly instantiated by the user. 23 | - [chunk\_size](/docs/api/modules/jinbase/__init__/class-Jinbase.md#properties-table); _getter_ 24 | - [created\_at](/docs/api/modules/jinbase/__init__/class-Jinbase.md#properties-table); _getter_ 25 | - [creation\_dt](/docs/api/modules/jinbase/__init__/class-Jinbase.md#properties-table); _getter_ 26 | - [dbc](/docs/api/modules/jinbase/__init__/class-Jinbase.md#properties-table); _getter_ 27 | - [depot](/docs/api/modules/jinbase/__init__/class-Jinbase.md#properties-table); _getter_ 28 | - [filename](/docs/api/modules/jinbase/__init__/class-Jinbase.md#properties-table); _getter_ 29 | - [in\_memory](/docs/api/modules/jinbase/__init__/class-Jinbase.md#properties-table); _getter_ 30 | - [is\_closed](/docs/api/modules/jinbase/__init__/class-Jinbase.md#properties-table); _getter_ 31 | - [is\_destroyed](/docs/api/modules/jinbase/__init__/class-Jinbase.md#properties-table); _getter_ 32 | - [is\_new](/docs/api/modules/jinbase/__init__/class-Jinbase.md#properties-table); _getter_ 33 | - [is\_readonly](/docs/api/modules/jinbase/__init__/class-Jinbase.md#properties-table); _getter_ 34 | - [kv](/docs/api/modules/jinbase/__init__/class-Jinbase.md#properties-table); _getter_ 35 | - [queue](/docs/api/modules/jinbase/__init__/class-Jinbase.md#properties-table); _getter_ 36 | - [stack](/docs/api/modules/jinbase/__init__/class-Jinbase.md#properties-table); _getter_ 37 | - [timeout](/docs/api/modules/jinbase/__init__/class-Jinbase.md#properties-table); _getter_ 38 | - [timestamp\_precision](/docs/api/modules/jinbase/__init__/class-Jinbase.md#properties-table); _getter_ 39 | - [type\_ref](/docs/api/modules/jinbase/__init__/class-Jinbase.md#properties-table); _getter_ 40 | - [version](/docs/api/modules/jinbase/__init__/class-Jinbase.md#properties-table); _getter_ 41 | - [backup](/docs/api/modules/jinbase/__init__/class-Jinbase.md#backup): No docstring. 42 | - [close](/docs/api/modules/jinbase/__init__/class-Jinbase.md#close): Close the connection 43 | - [copy](/docs/api/modules/jinbase/__init__/class-Jinbase.md#copy): Create a new Jinbase instance that points to the same database file 44 | - [count\_bytes](/docs/api/modules/jinbase/__init__/class-Jinbase.md#count_bytes): No docstring. 45 | - [count\_chunks](/docs/api/modules/jinbase/__init__/class-Jinbase.md#count_chunks): No docstring. 46 | - [count\_records](/docs/api/modules/jinbase/__init__/class-Jinbase.md#count_records): No docstring. 47 | - [destroy](/docs/api/modules/jinbase/__init__/class-Jinbase.md#destroy): Destroy the database file 48 | - [get\_journal\_mode](/docs/api/modules/jinbase/__init__/class-Jinbase.md#get_journal_mode): No docstring. 49 | - [get\_locking\_mode](/docs/api/modules/jinbase/__init__/class-Jinbase.md#get_locking_mode): No docstring. 50 | - [get\_sync\_mode](/docs/api/modules/jinbase/__init__/class-Jinbase.md#get_sync_mode): No docstring. 51 | - [interrupt](/docs/api/modules/jinbase/__init__/class-Jinbase.md#interrupt): No docstring. 52 | - [iterdump](/docs/api/modules/jinbase/__init__/class-Jinbase.md#iterdump): Returns an iterator to the dump of the database in an SQL text format 53 | - [latest](/docs/api/modules/jinbase/__init__/class-Jinbase.md#latest): Get the utc datetime of the latest operation. 54 | - [now](/docs/api/modules/jinbase/__init__/class-Jinbase.md#now): Get the current utc datetime. 55 | - [now\_dt](/docs/api/modules/jinbase/__init__/class-Jinbase.md#now_dt): Get the current utc datetime. 56 | - [read\_transaction](/docs/api/modules/jinbase/__init__/class-Jinbase.md#read_transaction): No docstring. 57 | - [scan](/docs/api/modules/jinbase/__init__/class-Jinbase.md#scan): Scan the Jinbase database 58 | - [set\_journal\_mode](/docs/api/modules/jinbase/__init__/class-Jinbase.md#set_journal_mode): No docstring. 59 | - [set\_locking\_mode](/docs/api/modules/jinbase/__init__/class-Jinbase.md#set_locking_mode): No docstring. 60 | - [set\_progress\_handler](/docs/api/modules/jinbase/__init__/class-Jinbase.md#set_progress_handler): No docstring. 61 | - [set\_sync\_mode](/docs/api/modules/jinbase/__init__/class-Jinbase.md#set_sync_mode): No docstring. 62 | - [set\_trace\_callback](/docs/api/modules/jinbase/__init__/class-Jinbase.md#set_trace_callback): No docstring. 63 | - [transaction](/docs/api/modules/jinbase/__init__/class-Jinbase.md#transaction): No docstring. 64 | - [vacuum](/docs/api/modules/jinbase/__init__/class-Jinbase.md#vacuum): Vacuum the database 65 | - [vacuum\_into](/docs/api/modules/jinbase/__init__/class-Jinbase.md#vacuum_into): Vacuum into a file whose name is provided via `dst`. 66 | - [write\_transaction](/docs/api/modules/jinbase/__init__/class-Jinbase.md#write_transaction): No docstring. 67 | - [**Model**](/docs/api/modules/jinbase/__init__/class-Model.md): Create a collection of name/value pairs. 68 | - KV = `1` 69 | - DEPOT = `2` 70 | - QUEUE = `3` 71 | - STACK = `4` 72 | - [**RecordInfo**](/docs/api/modules/jinbase/__init__/class-RecordInfo.md): Named tuple returned by store.info() 73 | - uid: Alias for field number 0 74 | - datatype: Alias for field number 1 75 | - created\_at: Alias for field number 2 76 | - [**TimestampPrecision**](/docs/api/modules/jinbase/__init__/class-TimestampPrecision.md): Create a collection of name/value pairs. 77 | - SECONDS = `0` 78 | - MILLISECONDS = `3` 79 | - MICROSECONDS = `6` 80 | - NANOSECONDS = `9` 81 | - [**TypeRef**](/docs/api/modules/jinbase/__init__/class-TypeRef.md): This class represents a mechanism for customizing Python types allowed for (de)serializing data with Paradict classes and functi... 82 | - [adapters](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 83 | - [bin\_type](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 84 | - [bin\_types](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 85 | - [bool\_type](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 86 | - [bool\_types](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 87 | - [complex\_type](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 88 | - [complex\_types](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 89 | - [date\_type](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 90 | - [date\_types](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 91 | - [datetime\_type](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 92 | - [datetime\_types](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 93 | - [dict\_type](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 94 | - [dict\_types](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 95 | - [float\_type](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 96 | - [float\_types](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 97 | - [grid\_type](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 98 | - [grid\_types](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 99 | - [int\_type](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 100 | - [int\_types](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 101 | - [list\_type](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 102 | - [list\_types](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 103 | - [obj\_type](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 104 | - [obj\_types](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 105 | - [set\_type](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 106 | - [set\_types](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 107 | - [str\_type](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 108 | - [str\_types](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 109 | - [time\_type](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 110 | - [time\_types](/docs/api/modules/jinbase/__init__/class-TypeRef.md#properties-table); _getter, setter_ 111 | - [adapt](/docs/api/modules/jinbase/__init__/class-TypeRef.md#adapt): Checks the 'adapters' attribute to find out if there is an adapter function registered for the type of the data argument. Then, ... 112 | - [check](/docs/api/modules/jinbase/__init__/class-TypeRef.md#check): This function accepts as argument a Python type, and return a Datatype instance if the type is supported/registered, else return... 113 | - [\_create\_map](/docs/api/modules/jinbase/__init__/class-TypeRef.md#_create_map): No docstring. 114 | - [\_update\_types](/docs/api/modules/jinbase/__init__/class-TypeRef.md#_update_types): No docstring. 115 | 116 |

Back to top

117 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/__init__/class-Jinbase.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | [Module](/docs/api/modules/jinbase/__init__/README.md) | [Source](/src/jinbase/__init__.py) 3 | 4 | # Class Jinbase 5 | > Module: [jinbase.\_\_init\_\_](/docs/api/modules/jinbase/__init__/README.md) 6 | > 7 | > Class: **Jinbase** 8 | > 9 | > Inheritance: `object` 10 | 11 | The Jinbase class. A Jinbase object is intended to 12 | be directly instantiated by the user. 13 | 14 | ## Properties table 15 | Here are properties exposed in the class: 16 | 17 | | Property | Methods | Description | 18 | | --- | --- | --- | 19 | | chunk\_size | _getter_ | No docstring. | 20 | | created\_at | _getter_ | No docstring. | 21 | | creation\_dt | _getter_ | No docstring. | 22 | | dbc | _getter_ | The instance of litedbc.LiteDBC | 23 | | depot | _getter_ | No docstring. | 24 | | filename | _getter_ | No docstring. | 25 | | in\_memory | _getter_ | No docstring. | 26 | | is\_closed | _getter_ | No docstring. | 27 | | is\_destroyed | _getter_ | No docstring. | 28 | | is\_new | _getter_ | No docstring. | 29 | | is\_readonly | _getter_ | No docstring. | 30 | | kv | _getter_ | No docstring. | 31 | | queue | _getter_ | No docstring. | 32 | | stack | _getter_ | No docstring. | 33 | | timeout | _getter_ | No docstring. | 34 | | timestamp\_precision | _getter_ | No docstring. | 35 | | type\_ref | _getter_ | No docstring. | 36 | | version | _getter_ | No docstring. | 37 | 38 |

Back to top

39 | 40 | # Methods within class 41 | Here are methods exposed in the class: 42 | - [\_\_init\_\_](#__init__) 43 | - [backup](#backup) 44 | - [close](#close) 45 | - [copy](#copy) 46 | - [count\_bytes](#count_bytes) 47 | - [count\_chunks](#count_chunks) 48 | - [count\_records](#count_records) 49 | - [destroy](#destroy) 50 | - [get\_journal\_mode](#get_journal_mode) 51 | - [get\_locking\_mode](#get_locking_mode) 52 | - [get\_sync\_mode](#get_sync_mode) 53 | - [interrupt](#interrupt) 54 | - [iterdump](#iterdump) 55 | - [latest](#latest) 56 | - [now](#now) 57 | - [now\_dt](#now_dt) 58 | - [read\_transaction](#read_transaction) 59 | - [scan](#scan) 60 | - [set\_journal\_mode](#set_journal_mode) 61 | - [set\_locking\_mode](#set_locking_mode) 62 | - [set\_progress\_handler](#set_progress_handler) 63 | - [set\_sync\_mode](#set_sync_mode) 64 | - [set\_trace\_callback](#set_trace_callback) 65 | - [transaction](#transaction) 66 | - [vacuum](#vacuum) 67 | - [vacuum\_into](#vacuum_into) 68 | - [write\_transaction](#write_transaction) 69 | 70 | ## \_\_init\_\_ 71 | Init. 72 | 73 | ```python 74 | def __init__(self, filename=None, *, auto_create=True, is_readonly=False, timeout=5.0, type_ref=None, chunk_size=1048576, timestamp_precision=): 75 | ... 76 | ``` 77 | 78 | | Parameter | Description | 79 | | --- | --- | 80 | | filename | The filename of the Jinbase database. If the pointed file doesn't exist, it will be created if `auto_create` is set to True. | 81 | | auto\_create | Boolean to tell whether a nonexistent database file should automatically be created or not. Defaults to True. | 82 | | is\_readonly | Boolean to tell whether the database connection should be in readonly or not. | 83 | | timeout | Timeout in seconds for all database operations. Defaults to the value of `jinbase.TIMEOUT` | 84 | | type\_ref | A paradict.TypeRef instance | 85 | | chunk\_size | Chunk size in bytes. Defaults to `jinbase.CHUNK_SIZE`. Note that this value is only relevant when the Jinbase tables are created. | 86 | | timestamp\_precision | An instance of the `jinbase.TimestampPrecision` namedtuple. Defaults to `jinbase.TIMESTAMP_PRECISION`. Note that this value is only relevant when the Jinbase tables are created. | 87 | 88 |

Back to top

89 | 90 | ## backup 91 | No docstring 92 | 93 | ```python 94 | def backup(self, dst, *, pages=-1, progress=None, sleep=0.25): 95 | ... 96 | ``` 97 | 98 |

Back to top

99 | 100 | ## close 101 | Close the connection 102 | 103 | ```python 104 | def close(self): 105 | ... 106 | ``` 107 | 108 |

Back to top

109 | 110 | ## copy 111 | Create a new Jinbase instance that 112 | points to the same database file 113 | 114 | ```python 115 | def copy(self): 116 | ... 117 | ``` 118 | 119 |

Back to top

120 | 121 | ## count\_bytes 122 | No docstring 123 | 124 | ```python 125 | def count_bytes(self): 126 | ... 127 | ``` 128 | 129 |

Back to top

130 | 131 | ## count\_chunks 132 | No docstring 133 | 134 | ```python 135 | def count_chunks(self): 136 | ... 137 | ``` 138 | 139 |

Back to top

140 | 141 | ## count\_records 142 | No docstring 143 | 144 | ```python 145 | def count_records(self): 146 | ... 147 | ``` 148 | 149 |

Back to top

150 | 151 | ## destroy 152 | Destroy the database file 153 | 154 | ```python 155 | def destroy(self): 156 | ... 157 | ``` 158 | 159 |

Back to top

160 | 161 | ## get\_journal\_mode 162 | No docstring 163 | 164 | ```python 165 | def get_journal_mode(self): 166 | ... 167 | ``` 168 | 169 |

Back to top

170 | 171 | ## get\_locking\_mode 172 | No docstring 173 | 174 | ```python 175 | def get_locking_mode(self): 176 | ... 177 | ``` 178 | 179 |

Back to top

180 | 181 | ## get\_sync\_mode 182 | No docstring 183 | 184 | ```python 185 | def get_sync_mode(self): 186 | ... 187 | ``` 188 | 189 |

Back to top

190 | 191 | ## interrupt 192 | No docstring 193 | 194 | ```python 195 | def interrupt(self): 196 | ... 197 | ``` 198 | 199 |

Back to top

200 | 201 | ## iterdump 202 | Returns an iterator to the dump of the database 203 | in an SQL text format 204 | 205 | ```python 206 | def iterdump(self): 207 | ... 208 | ``` 209 | 210 |

Back to top

211 | 212 | ## latest 213 | Get the utc datetime of the latest operation. 214 | 215 | ```python 216 | def latest(self): 217 | ... 218 | ``` 219 | 220 | ### Value to return 221 | A utc instance of `datetime.datetime` 222 | 223 |

Back to top

224 | 225 | ## now 226 | Get the current utc datetime. 227 | 228 | ```python 229 | @staticmethod 230 | def now(): 231 | ... 232 | ``` 233 | 234 | ### Value to return 235 | A utc instance of `datetime.datetime` 236 | 237 |

Back to top

238 | 239 | ## now\_dt 240 | Get the current utc datetime. 241 | 242 | ```python 243 | @staticmethod 244 | def now_dt(): 245 | ... 246 | ``` 247 | 248 | ### Value to return 249 | A utc string 250 | 251 |

Back to top

252 | 253 | ## read\_transaction 254 | No docstring 255 | 256 | ```python 257 | def read_transaction(self): 258 | ... 259 | ``` 260 | 261 |

Back to top

262 | 263 | ## scan 264 | Scan the Jinbase database 265 | 266 | ```python 267 | def scan(self): 268 | ... 269 | ``` 270 | 271 | ### Value to return 272 | A dictionary object whose keys are jinbase.Model namedtuples 273 | and values are tuples of the total record count and total byte count. 274 | 275 |

Back to top

276 | 277 | ## set\_journal\_mode 278 | No docstring 279 | 280 | ```python 281 | def set_journal_mode(self, journal_mode): 282 | ... 283 | ``` 284 | 285 |

Back to top

286 | 287 | ## set\_locking\_mode 288 | No docstring 289 | 290 | ```python 291 | def set_locking_mode(self, locking_mode): 292 | ... 293 | ``` 294 | 295 |

Back to top

296 | 297 | ## set\_progress\_handler 298 | No docstring 299 | 300 | ```python 301 | def set_progress_handler(self, callback, n): 302 | ... 303 | ``` 304 | 305 |

Back to top

306 | 307 | ## set\_sync\_mode 308 | No docstring 309 | 310 | ```python 311 | def set_sync_mode(self, sync_mode): 312 | ... 313 | ``` 314 | 315 |

Back to top

316 | 317 | ## set\_trace\_callback 318 | No docstring 319 | 320 | ```python 321 | def set_trace_callback(self, callback): 322 | ... 323 | ``` 324 | 325 |

Back to top

326 | 327 | ## transaction 328 | No docstring 329 | 330 | ```python 331 | def transaction(self, transaction_mode=): 332 | ... 333 | ``` 334 | 335 |

Back to top

336 | 337 | ## vacuum 338 | Vacuum the database 339 | 340 | ```python 341 | def vacuum(self): 342 | ... 343 | ``` 344 | 345 |

Back to top

346 | 347 | ## vacuum\_into 348 | Vacuum into a file whose name is provided via `dst`. 349 | 350 | ```python 351 | def vacuum_into(self, dst): 352 | ... 353 | ``` 354 | 355 |

Back to top

356 | 357 | ## write\_transaction 358 | No docstring 359 | 360 | ```python 361 | def write_transaction(self): 362 | ... 363 | ``` 364 | 365 |

Back to top

366 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/__init__/class-Model.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | [Module](/docs/api/modules/jinbase/__init__/README.md) | [Source](/src/jinbase/__init__.py) 3 | 4 | # Class Model 5 | > Module: [jinbase.\_\_init\_\_](/docs/api/modules/jinbase/__init__/README.md) 6 | > 7 | > Class: **Model** 8 | > 9 | > Inheritance: `enum.Enum` 10 | 11 | Create a collection of name/value pairs. 12 | 13 | Example enumeration: 14 | 15 | >>> class Color(Enum): 16 | ... RED = 1 17 | ... BLUE = 2 18 | ... GREEN = 3 19 | 20 | Access them by: 21 | 22 | - attribute access: 23 | 24 | >>> Color.RED 25 | 26 | 27 | - value lookup: 28 | 29 | >>> Color(1) 30 | 31 | 32 | - name lookup: 33 | 34 | >>> Color['RED'] 35 | 36 | 37 | Enumerations can be iterated over, and know how many members they have: 38 | 39 | >>> len(Color) 40 | 3 41 | 42 | >>> list(Color) 43 | 44 | ## Fields table 45 | Here are fields exposed in the class: 46 | 47 | | Field | Value | 48 | | --- | --- | 49 | | KV | `1` | 50 | | DEPOT | `2` | 51 | | QUEUE | `3` | 52 | | STACK | `4` | 53 | 54 |

Back to top

55 | 56 | # Methods within class 57 | Here are methods exposed in the class: 58 | - [\_\_init\_\_](#__init__) 59 | - [\_generate\_next\_value\_](#_generate_next_value_) 60 | - [\_missing\_](#_missing_) 61 | 62 | ## \_\_init\_\_ 63 | Initialize self. See help(type(self)) for accurate signature. 64 | 65 | ```python 66 | def __init__(self, *args, **kwds): 67 | ... 68 | ``` 69 | 70 |

Back to top

71 | 72 | ## \_generate\_next\_value\_ 73 | Generate the next value when not given. 74 | 75 | name: the name of the member 76 | start: the initial start value or None 77 | count: the number of existing members 78 | last_values: the list of values assigned 79 | 80 | ```python 81 | @staticmethod 82 | def _generate_next_value_(name, start, count, last_values): 83 | ... 84 | ``` 85 | 86 |

Back to top

87 | 88 | ## \_missing\_ 89 | No docstring 90 | 91 | ```python 92 | @classmethod 93 | def _missing_(value): 94 | ... 95 | ``` 96 | 97 |

Back to top

98 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/__init__/class-RecordInfo.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | [Module](/docs/api/modules/jinbase/__init__/README.md) | [Source](/src/jinbase/__init__.py) 3 | 4 | # Class RecordInfo 5 | > Module: [jinbase.\_\_init\_\_](/docs/api/modules/jinbase/__init__/README.md) 6 | > 7 | > Class: **RecordInfo** 8 | > 9 | > Inheritance: `tuple` 10 | 11 | Named tuple returned by store.info() 12 | 13 | ## Fields table 14 | Here are fields exposed in the class: 15 | 16 | | Field | Description | 17 | | --- | --- | 18 | | uid | Alias for field number 0 | 19 | | datatype | Alias for field number 1 | 20 | | created\_at | Alias for field number 2 | 21 | 22 |

Back to top

23 | 24 | # Methods within class 25 | Here are methods exposed in the class: 26 | - [\_asdict](#_asdict) 27 | - [\_make](#_make) 28 | - [\_replace](#_replace) 29 | 30 | ## \_asdict 31 | Return a new dict which maps field names to their values. 32 | 33 | ```python 34 | def _asdict(self): 35 | ... 36 | ``` 37 | 38 |

Back to top

39 | 40 | ## \_make 41 | Make a new RecordInfo object from a sequence or iterable 42 | 43 | ```python 44 | @classmethod 45 | def _make(iterable): 46 | ... 47 | ``` 48 | 49 |

Back to top

50 | 51 | ## \_replace 52 | Return a new RecordInfo object replacing specified fields with new values 53 | 54 | ```python 55 | def _replace(self, /, **kwds): 56 | ... 57 | ``` 58 | 59 |

Back to top

60 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/__init__/class-TimestampPrecision.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | [Module](/docs/api/modules/jinbase/__init__/README.md) | [Source](/src/jinbase/__init__.py) 3 | 4 | # Class TimestampPrecision 5 | > Module: [jinbase.\_\_init\_\_](/docs/api/modules/jinbase/__init__/README.md) 6 | > 7 | > Class: **TimestampPrecision** 8 | > 9 | > Inheritance: `enum.Enum` 10 | 11 | Create a collection of name/value pairs. 12 | 13 | Example enumeration: 14 | 15 | >>> class Color(Enum): 16 | ... RED = 1 17 | ... BLUE = 2 18 | ... GREEN = 3 19 | 20 | Access them by: 21 | 22 | - attribute access: 23 | 24 | >>> Color.RED 25 | 26 | 27 | - value lookup: 28 | 29 | >>> Color(1) 30 | 31 | 32 | - name lookup: 33 | 34 | >>> Color['RED'] 35 | 36 | 37 | Enumerations can be iterated over, and know how many members they have: 38 | 39 | >>> len(Color) 40 | 3 41 | 42 | >>> list(Color) 43 | 44 | ## Fields table 45 | Here are fields exposed in the class: 46 | 47 | | Field | Value | 48 | | --- | --- | 49 | | SECONDS | `0` | 50 | | MILLISECONDS | `3` | 51 | | MICROSECONDS | `6` | 52 | | NANOSECONDS | `9` | 53 | 54 |

Back to top

55 | 56 | # Methods within class 57 | Here are methods exposed in the class: 58 | - [\_\_init\_\_](#__init__) 59 | - [\_generate\_next\_value\_](#_generate_next_value_) 60 | - [\_missing\_](#_missing_) 61 | 62 | ## \_\_init\_\_ 63 | Initialize self. See help(type(self)) for accurate signature. 64 | 65 | ```python 66 | def __init__(self, *args, **kwds): 67 | ... 68 | ``` 69 | 70 |

Back to top

71 | 72 | ## \_generate\_next\_value\_ 73 | Generate the next value when not given. 74 | 75 | name: the name of the member 76 | start: the initial start value or None 77 | count: the number of existing members 78 | last_values: the list of values assigned 79 | 80 | ```python 81 | @staticmethod 82 | def _generate_next_value_(name, start, count, last_values): 83 | ... 84 | ``` 85 | 86 |

Back to top

87 | 88 | ## \_missing\_ 89 | No docstring 90 | 91 | ```python 92 | @classmethod 93 | def _missing_(value): 94 | ... 95 | ``` 96 | 97 |

Back to top

98 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/__init__/class-TypeRef.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | [Module](/docs/api/modules/jinbase/__init__/README.md) | [Source](/src/jinbase/__init__.py) 3 | 4 | # Class TypeRef 5 | > Module: [jinbase.\_\_init\_\_](/docs/api/modules/jinbase/__init__/README.md) 6 | > 7 | > Class: **TypeRef** 8 | > 9 | > Inheritance: `object` 10 | 11 | This class represents a mechanism for customizing 12 | Python types allowed for (de)serializing data with Paradict classes and functions. 13 | For example, one might want to only use Python OrderedDict instead of the regular 14 | dict. In this case, just create a TypeRef instance, and make sure that you 15 | set the dict_type attribute via the construction or a property. 16 | 17 | ```python 18 | type_ref = TypeRef(dict_type=OrderedDict) 19 | ``` 20 | 21 | Still with this class, one could 'adapt' some exotic datatype so it will 22 | conform with Python datatypes allowed in Paradict (de)serialization. 23 | To do so, set the adapters attribute like this: 24 | 25 | ```python 26 | adapters = {MyExoticType1: adapterFunction1, MyExoticType2: adapterFunction2} 27 | type_ref = TypeRef(adapters=adapters) 28 | ``` 29 | 30 | ## Properties table 31 | Here are properties exposed in the class: 32 | 33 | | Property | Methods | Description | 34 | | --- | --- | --- | 35 | | adapters | _getter, setter_ | No docstring. | 36 | | bin\_type | _getter, setter_ | No docstring. | 37 | | bin\_types | _getter, setter_ | No docstring. | 38 | | bool\_type | _getter, setter_ | No docstring. | 39 | | bool\_types | _getter, setter_ | No docstring. | 40 | | complex\_type | _getter, setter_ | No docstring. | 41 | | complex\_types | _getter, setter_ | No docstring. | 42 | | date\_type | _getter, setter_ | No docstring. | 43 | | date\_types | _getter, setter_ | No docstring. | 44 | | datetime\_type | _getter, setter_ | No docstring. | 45 | | datetime\_types | _getter, setter_ | No docstring. | 46 | | dict\_type | _getter, setter_ | No docstring. | 47 | | dict\_types | _getter, setter_ | No docstring. | 48 | | float\_type | _getter, setter_ | No docstring. | 49 | | float\_types | _getter, setter_ | No docstring. | 50 | | grid\_type | _getter, setter_ | No docstring. | 51 | | grid\_types | _getter, setter_ | No docstring. | 52 | | int\_type | _getter, setter_ | No docstring. | 53 | | int\_types | _getter, setter_ | No docstring. | 54 | | list\_type | _getter, setter_ | No docstring. | 55 | | list\_types | _getter, setter_ | No docstring. | 56 | | obj\_type | _getter, setter_ | No docstring. | 57 | | obj\_types | _getter, setter_ | No docstring. | 58 | | set\_type | _getter, setter_ | No docstring. | 59 | | set\_types | _getter, setter_ | No docstring. | 60 | | str\_type | _getter, setter_ | No docstring. | 61 | | str\_types | _getter, setter_ | No docstring. | 62 | | time\_type | _getter, setter_ | No docstring. | 63 | | time\_types | _getter, setter_ | No docstring. | 64 | 65 |

Back to top

66 | 67 | # Methods within class 68 | Here are methods exposed in the class: 69 | - [\_\_init\_\_](#__init__) 70 | - [adapt](#adapt) 71 | - [check](#check) 72 | - [\_create\_map](#_create_map) 73 | - [\_update\_types](#_update_types) 74 | 75 | ## \_\_init\_\_ 76 | Initialize self. See help(type(self)) for accurate signature. 77 | 78 | ```python 79 | def __init__(self, adapters=None, dict_type=None, list_type=None, set_type=None, obj_type=None, dict_types=None, list_types=None, set_types=None, obj_types=None, bin_type=None, bool_type=None, complex_type=None, date_type=None, datetime_type=None, float_type=None, grid_type=None, int_type=None, str_type=None, time_type=None, bin_types=None, bool_types=None, complex_types=None, date_types=None, datetime_types=None, float_types=None, grid_types=None, int_types=None, str_types=None, time_types=None): 80 | ... 81 | ``` 82 | 83 |

Back to top

84 | 85 | ## adapt 86 | Checks the 'adapters' attribute to find out if there is 87 | an adapter function registered for the type of the data argument. 88 | Then, calls the adapter on the value. 89 | 90 | ```python 91 | def adapt(self, value): 92 | ... 93 | ``` 94 | 95 | | Parameter | Description | 96 | | --- | --- | 97 | | value | the data value to adapt is an arbitrary Python object | 98 | 99 | ### Value to return 100 | Returns the adapted value or the same value if no adapter is registered for its type 101 | 102 |

Back to top

103 | 104 | ## check 105 | This function accepts as argument a Python type, and return 106 | a Datatype instance if the type is supported/registered, else returns None 107 | 108 | ```python 109 | def check(self, dtype): 110 | ... 111 | ``` 112 | 113 |

Back to top

114 | 115 | ## \_create\_map 116 | No docstring 117 | 118 | ```python 119 | def _create_map(self): 120 | ... 121 | ``` 122 | 123 |

Back to top

124 | 125 | ## \_update\_types 126 | No docstring 127 | 128 | ```python 129 | def _update_types(self, name, datatype): 130 | ... 131 | ``` 132 | 133 |

Back to top

134 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/__init__/fields.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | [Module](/docs/api/modules/jinbase/__init__/README.md) | [Source](/src/jinbase/__init__.py) 3 | 4 | # Fields within module 5 | > Module: [jinbase.\_\_init\_\_](/docs/api/modules/jinbase/__init__/README.md) 6 | 7 | Here are fields exposed in the module: 8 | 9 | | Field | Value | 10 | | --- | --- | 11 | | CHUNK\_SIZE | `1048576` | 12 | | DATETIME\_FORMAT | `'%Y-%m-%d %H:%M:%S.%fZ'` | 13 | | JINBASE\_HOME | `'/home/alex/JinbaseHome'` | 14 | | JINBASE\_VERSION | `1` | 15 | | TIMEOUT | `5.0` | 16 | | TIMESTAMP\_PRECISION | `` | 17 | | USER\_HOME | `'/home/alex'` | 18 | 19 |

Back to top

20 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/blob/__init__/README.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | Module | [Source](/src/jinbase/blob/__init__.py) 3 | 4 | # Module Overview 5 | > Module: **jinbase.blob.\_\_init\_\_** 6 | 7 | The Blob class is defined here. 8 | 9 | ## Classes 10 | - [**Blob**](/docs/api/modules/jinbase/blob/__init__/class-Blob.md): The Blob class allows a Read access to the blobs of Jinbase records. This class isn't intended to be directly instantiated by th... 11 | - [close](/docs/api/modules/jinbase/blob/__init__/class-Blob.md#close): Close this Blob instance. Note that this method is automatically called by the Store's open_blob method. 12 | - [read](/docs/api/modules/jinbase/blob/__init__/class-Blob.md#read): Read the blob. 13 | - [seek](/docs/api/modules/jinbase/blob/__init__/class-Blob.md#seek): Move the cursor to another position 14 | - [tell](/docs/api/modules/jinbase/blob/__init__/class-Blob.md#tell): Returns the current position of the cursor 15 | - [write](/docs/api/modules/jinbase/blob/__init__/class-Blob.md#write): Jinbase doesn't allow Writes on blobs 16 | - [\_get\_blob\_io\_file](/docs/api/modules/jinbase/blob/__init__/class-Blob.md#_get_blob_io_file): No docstring. 17 | - [\_get\_chunk](/docs/api/modules/jinbase/blob/__init__/class-Blob.md#_get_chunk): No docstring. 18 | - [\_read](/docs/api/modules/jinbase/blob/__init__/class-Blob.md#_read): No docstring. 19 | 20 |

Back to top

21 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/blob/__init__/class-Blob.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | [Module](/docs/api/modules/jinbase/blob/__init__/README.md) | [Source](/src/jinbase/blob/__init__.py) 3 | 4 | # Class Blob 5 | > Module: [jinbase.blob.\_\_init\_\_](/docs/api/modules/jinbase/blob/__init__/README.md) 6 | > 7 | > Class: **Blob** 8 | > 9 | > Inheritance: `object` 10 | 11 | The Blob class allows a Read access to the blobs of Jinbase records. 12 | This class isn't intended to be directly instantiated by the user. 13 | 14 | # Methods within class 15 | Here are methods exposed in the class: 16 | - [\_\_init\_\_](#__init__) 17 | - [close](#close) 18 | - [read](#read) 19 | - [seek](#seek) 20 | - [tell](#tell) 21 | - [write](#write) 22 | - [\_get\_blob\_io\_file](#_get_blob_io_file) 23 | - [\_get\_chunk](#_get_chunk) 24 | - [\_read](#_read) 25 | 26 | ## \_\_init\_\_ 27 | Initialization. 28 | 29 | ```python 30 | def __init__(self, store, record_id, n_bytes, n_chunks): 31 | ... 32 | ``` 33 | 34 | | Parameter | Description | 35 | | --- | --- | 36 | | store | Store instance. | 37 | | record\_id | The record's uid. | 38 | | n\_bytes | The size of the blob in bytes. | 39 | | n\_chunks | The number of chunks. | 40 | 41 |

Back to top

42 | 43 | ## close 44 | Close this Blob instance. Note that this method 45 | is automatically called by the Store's open_blob method. 46 | 47 | ```python 48 | def close(self): 49 | ... 50 | ``` 51 | 52 |

Back to top

53 | 54 | ## read 55 | Read the blob. 56 | 57 | ```python 58 | def read(self, length=-1, /): 59 | ... 60 | ``` 61 | 62 | | Parameter | Description | 63 | | --- | --- | 64 | | length | The number of bytes to read. Defaults to -1 to mean the entire blob. Note that the cursor moves as reads are done. | 65 | 66 | ### Value to return 67 | Returns bytes or an empty byte. 68 | 69 |

Back to top

70 | 71 | ## seek 72 | Move the cursor to another position 73 | 74 | ```python 75 | def seek(self, offset, origin=0, /): 76 | ... 77 | ``` 78 | 79 | | Parameter | Description | 80 | | --- | --- | 81 | | offset | Offset value | 82 | | origin | os.SEEK_SET, os.SEEK_CUR, or os.SEEK_END. Note that os.SEEK_END referes to position beyond the last character of the file, not the last character itself. | 83 | 84 |

Back to top

85 | 86 | ## tell 87 | Returns the current position of the cursor 88 | 89 | ```python 90 | def tell(self): 91 | ... 92 | ``` 93 | 94 |

Back to top

95 | 96 | ## write 97 | Jinbase doesn't allow Writes on blobs 98 | 99 | ```python 100 | def write(self, data, /): 101 | ... 102 | ``` 103 | 104 |

Back to top

105 | 106 | ## \_get\_blob\_io\_file 107 | No docstring 108 | 109 | ```python 110 | def _get_blob_io_file(self, chunk_index): 111 | ... 112 | ``` 113 | 114 |

Back to top

115 | 116 | ## \_get\_chunk 117 | No docstring 118 | 119 | ```python 120 | def _get_chunk(self, blob_slice): 121 | ... 122 | ``` 123 | 124 |

Back to top

125 | 126 | ## \_read 127 | No docstring 128 | 129 | ```python 130 | def _read(self, position, length): 131 | ... 132 | ``` 133 | 134 |

Back to top

135 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/const/__init__/README.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | Module | [Source](/src/jinbase/const/__init__.py) 3 | 4 | # Module Overview 5 | > Module: **jinbase.const.\_\_init\_\_** 6 | 7 | Project-wide constants are defined in this module. 8 | 9 | ## Fields 10 | - [**All fields**](/docs/api/modules/jinbase/const/__init__/fields.md) 11 | - CHUNK\_SIZE = `1048576` 12 | - DATETIME\_FORMAT = `'%Y-%m-%d %H:%M:%S.%fZ'` 13 | - JINBASE\_HOME = `'/home/alex/JinbaseHome'` 14 | - JINBASE\_VERSION = `1` 15 | - TIMEOUT = `5.0` 16 | - TIMESTAMP\_PRECISION = `` 17 | - USER\_HOME = `'/home/alex'` 18 | 19 |

Back to top

20 | 21 | ## Classes 22 | - [**Model**](/docs/api/modules/jinbase/const/__init__/class-Model.md): Create a collection of name/value pairs. 23 | - KV = `1` 24 | - DEPOT = `2` 25 | - QUEUE = `3` 26 | - STACK = `4` 27 | - [**StorageUnit**](/docs/api/modules/jinbase/const/__init__/class-StorageUnit.md): Create a collection of name/value pairs. 28 | - BYTE = `'B'` 29 | - KIBIBYTE = `'KiB'` 30 | - MEBIBYTE = `'MiB'` 31 | - GIBIBYTE = `'GiB'` 32 | - TEBIBYTE = `'TiB'` 33 | - [**TimeUnit**](/docs/api/modules/jinbase/const/__init__/class-TimeUnit.md): Create a collection of name/value pairs. 34 | - SECOND = `'sec'` 35 | - MINUTE = `'min'` 36 | - HOUR = `'hour'` 37 | - DAY = `'day'` 38 | - WEEK = `'week'` 39 | - [**TimestampPrecision**](/docs/api/modules/jinbase/const/__init__/class-TimestampPrecision.md): Create a collection of name/value pairs. 40 | - SECONDS = `0` 41 | - MILLISECONDS = `3` 42 | - MICROSECONDS = `6` 43 | - NANOSECONDS = `9` 44 | 45 |

Back to top

46 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/const/__init__/class-Model.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | [Module](/docs/api/modules/jinbase/const/__init__/README.md) | [Source](/src/jinbase/const/__init__.py) 3 | 4 | # Class Model 5 | > Module: [jinbase.const.\_\_init\_\_](/docs/api/modules/jinbase/const/__init__/README.md) 6 | > 7 | > Class: **Model** 8 | > 9 | > Inheritance: `enum.Enum` 10 | 11 | Create a collection of name/value pairs. 12 | 13 | Example enumeration: 14 | 15 | >>> class Color(Enum): 16 | ... RED = 1 17 | ... BLUE = 2 18 | ... GREEN = 3 19 | 20 | Access them by: 21 | 22 | - attribute access: 23 | 24 | >>> Color.RED 25 | 26 | 27 | - value lookup: 28 | 29 | >>> Color(1) 30 | 31 | 32 | - name lookup: 33 | 34 | >>> Color['RED'] 35 | 36 | 37 | Enumerations can be iterated over, and know how many members they have: 38 | 39 | >>> len(Color) 40 | 3 41 | 42 | >>> list(Color) 43 | 44 | ## Fields table 45 | Here are fields exposed in the class: 46 | 47 | | Field | Value | 48 | | --- | --- | 49 | | KV | `1` | 50 | | DEPOT | `2` | 51 | | QUEUE | `3` | 52 | | STACK | `4` | 53 | 54 |

Back to top

55 | 56 | # Methods within class 57 | Here are methods exposed in the class: 58 | - [\_\_init\_\_](#__init__) 59 | - [\_generate\_next\_value\_](#_generate_next_value_) 60 | - [\_missing\_](#_missing_) 61 | 62 | ## \_\_init\_\_ 63 | Initialize self. See help(type(self)) for accurate signature. 64 | 65 | ```python 66 | def __init__(self, *args, **kwds): 67 | ... 68 | ``` 69 | 70 |

Back to top

71 | 72 | ## \_generate\_next\_value\_ 73 | Generate the next value when not given. 74 | 75 | name: the name of the member 76 | start: the initial start value or None 77 | count: the number of existing members 78 | last_values: the list of values assigned 79 | 80 | ```python 81 | @staticmethod 82 | def _generate_next_value_(name, start, count, last_values): 83 | ... 84 | ``` 85 | 86 |

Back to top

87 | 88 | ## \_missing\_ 89 | No docstring 90 | 91 | ```python 92 | @classmethod 93 | def _missing_(value): 94 | ... 95 | ``` 96 | 97 |

Back to top

98 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/const/__init__/class-StorageUnit.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | [Module](/docs/api/modules/jinbase/const/__init__/README.md) | [Source](/src/jinbase/const/__init__.py) 3 | 4 | # Class StorageUnit 5 | > Module: [jinbase.const.\_\_init\_\_](/docs/api/modules/jinbase/const/__init__/README.md) 6 | > 7 | > Class: **StorageUnit** 8 | > 9 | > Inheritance: `enum.Enum` 10 | 11 | Create a collection of name/value pairs. 12 | 13 | Example enumeration: 14 | 15 | >>> class Color(Enum): 16 | ... RED = 1 17 | ... BLUE = 2 18 | ... GREEN = 3 19 | 20 | Access them by: 21 | 22 | - attribute access: 23 | 24 | >>> Color.RED 25 | 26 | 27 | - value lookup: 28 | 29 | >>> Color(1) 30 | 31 | 32 | - name lookup: 33 | 34 | >>> Color['RED'] 35 | 36 | 37 | Enumerations can be iterated over, and know how many members they have: 38 | 39 | >>> len(Color) 40 | 3 41 | 42 | >>> list(Color) 43 | 44 | ## Fields table 45 | Here are fields exposed in the class: 46 | 47 | | Field | Value | 48 | | --- | --- | 49 | | BYTE | `'B'` | 50 | | KIBIBYTE | `'KiB'` | 51 | | MEBIBYTE | `'MiB'` | 52 | | GIBIBYTE | `'GiB'` | 53 | | TEBIBYTE | `'TiB'` | 54 | 55 |

Back to top

56 | 57 | # Methods within class 58 | Here are methods exposed in the class: 59 | - [\_\_init\_\_](#__init__) 60 | - [\_generate\_next\_value\_](#_generate_next_value_) 61 | - [\_missing\_](#_missing_) 62 | 63 | ## \_\_init\_\_ 64 | Initialize self. See help(type(self)) for accurate signature. 65 | 66 | ```python 67 | def __init__(self, *args, **kwds): 68 | ... 69 | ``` 70 | 71 |

Back to top

72 | 73 | ## \_generate\_next\_value\_ 74 | Generate the next value when not given. 75 | 76 | name: the name of the member 77 | start: the initial start value or None 78 | count: the number of existing members 79 | last_values: the list of values assigned 80 | 81 | ```python 82 | @staticmethod 83 | def _generate_next_value_(name, start, count, last_values): 84 | ... 85 | ``` 86 | 87 |

Back to top

88 | 89 | ## \_missing\_ 90 | No docstring 91 | 92 | ```python 93 | @classmethod 94 | def _missing_(value): 95 | ... 96 | ``` 97 | 98 |

Back to top

99 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/const/__init__/class-TimeUnit.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | [Module](/docs/api/modules/jinbase/const/__init__/README.md) | [Source](/src/jinbase/const/__init__.py) 3 | 4 | # Class TimeUnit 5 | > Module: [jinbase.const.\_\_init\_\_](/docs/api/modules/jinbase/const/__init__/README.md) 6 | > 7 | > Class: **TimeUnit** 8 | > 9 | > Inheritance: `enum.Enum` 10 | 11 | Create a collection of name/value pairs. 12 | 13 | Example enumeration: 14 | 15 | >>> class Color(Enum): 16 | ... RED = 1 17 | ... BLUE = 2 18 | ... GREEN = 3 19 | 20 | Access them by: 21 | 22 | - attribute access: 23 | 24 | >>> Color.RED 25 | 26 | 27 | - value lookup: 28 | 29 | >>> Color(1) 30 | 31 | 32 | - name lookup: 33 | 34 | >>> Color['RED'] 35 | 36 | 37 | Enumerations can be iterated over, and know how many members they have: 38 | 39 | >>> len(Color) 40 | 3 41 | 42 | >>> list(Color) 43 | 44 | ## Fields table 45 | Here are fields exposed in the class: 46 | 47 | | Field | Value | 48 | | --- | --- | 49 | | SECOND | `'sec'` | 50 | | MINUTE | `'min'` | 51 | | HOUR | `'hour'` | 52 | | DAY | `'day'` | 53 | | WEEK | `'week'` | 54 | 55 |

Back to top

56 | 57 | # Methods within class 58 | Here are methods exposed in the class: 59 | - [\_\_init\_\_](#__init__) 60 | - [\_generate\_next\_value\_](#_generate_next_value_) 61 | - [\_missing\_](#_missing_) 62 | 63 | ## \_\_init\_\_ 64 | Initialize self. See help(type(self)) for accurate signature. 65 | 66 | ```python 67 | def __init__(self, *args, **kwds): 68 | ... 69 | ``` 70 | 71 |

Back to top

72 | 73 | ## \_generate\_next\_value\_ 74 | Generate the next value when not given. 75 | 76 | name: the name of the member 77 | start: the initial start value or None 78 | count: the number of existing members 79 | last_values: the list of values assigned 80 | 81 | ```python 82 | @staticmethod 83 | def _generate_next_value_(name, start, count, last_values): 84 | ... 85 | ``` 86 | 87 |

Back to top

88 | 89 | ## \_missing\_ 90 | No docstring 91 | 92 | ```python 93 | @classmethod 94 | def _missing_(value): 95 | ... 96 | ``` 97 | 98 |

Back to top

99 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/const/__init__/class-TimestampPrecision.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | [Module](/docs/api/modules/jinbase/const/__init__/README.md) | [Source](/src/jinbase/const/__init__.py) 3 | 4 | # Class TimestampPrecision 5 | > Module: [jinbase.const.\_\_init\_\_](/docs/api/modules/jinbase/const/__init__/README.md) 6 | > 7 | > Class: **TimestampPrecision** 8 | > 9 | > Inheritance: `enum.Enum` 10 | 11 | Create a collection of name/value pairs. 12 | 13 | Example enumeration: 14 | 15 | >>> class Color(Enum): 16 | ... RED = 1 17 | ... BLUE = 2 18 | ... GREEN = 3 19 | 20 | Access them by: 21 | 22 | - attribute access: 23 | 24 | >>> Color.RED 25 | 26 | 27 | - value lookup: 28 | 29 | >>> Color(1) 30 | 31 | 32 | - name lookup: 33 | 34 | >>> Color['RED'] 35 | 36 | 37 | Enumerations can be iterated over, and know how many members they have: 38 | 39 | >>> len(Color) 40 | 3 41 | 42 | >>> list(Color) 43 | 44 | ## Fields table 45 | Here are fields exposed in the class: 46 | 47 | | Field | Value | 48 | | --- | --- | 49 | | SECONDS | `0` | 50 | | MILLISECONDS | `3` | 51 | | MICROSECONDS | `6` | 52 | | NANOSECONDS | `9` | 53 | 54 |

Back to top

55 | 56 | # Methods within class 57 | Here are methods exposed in the class: 58 | - [\_\_init\_\_](#__init__) 59 | - [\_generate\_next\_value\_](#_generate_next_value_) 60 | - [\_missing\_](#_missing_) 61 | 62 | ## \_\_init\_\_ 63 | Initialize self. See help(type(self)) for accurate signature. 64 | 65 | ```python 66 | def __init__(self, *args, **kwds): 67 | ... 68 | ``` 69 | 70 |

Back to top

71 | 72 | ## \_generate\_next\_value\_ 73 | Generate the next value when not given. 74 | 75 | name: the name of the member 76 | start: the initial start value or None 77 | count: the number of existing members 78 | last_values: the list of values assigned 79 | 80 | ```python 81 | @staticmethod 82 | def _generate_next_value_(name, start, count, last_values): 83 | ... 84 | ``` 85 | 86 |

Back to top

87 | 88 | ## \_missing\_ 89 | No docstring 90 | 91 | ```python 92 | @classmethod 93 | def _missing_(value): 94 | ... 95 | ``` 96 | 97 |

Back to top

98 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/const/__init__/fields.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | [Module](/docs/api/modules/jinbase/const/__init__/README.md) | [Source](/src/jinbase/const/__init__.py) 3 | 4 | # Fields within module 5 | > Module: [jinbase.const.\_\_init\_\_](/docs/api/modules/jinbase/const/__init__/README.md) 6 | 7 | Here are fields exposed in the module: 8 | 9 | | Field | Value | 10 | | --- | --- | 11 | | CHUNK\_SIZE | `1048576` | 12 | | DATETIME\_FORMAT | `'%Y-%m-%d %H:%M:%S.%fZ'` | 13 | | JINBASE\_HOME | `'/home/alex/JinbaseHome'` | 14 | | JINBASE\_VERSION | `1` | 15 | | TIMEOUT | `5.0` | 16 | | TIMESTAMP\_PRECISION | `` | 17 | | USER\_HOME | `'/home/alex'` | 18 | 19 |

Back to top

20 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/store/__init__/README.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | Module | [Source](/src/jinbase/store/__init__.py) 3 | 4 | # Module Overview 5 | > Module: **jinbase.store.\_\_init\_\_** 6 | 7 | The abstract Store class is defined in this module. 8 | 9 | ## Classes 10 | - [**RecordInfo**](/docs/api/modules/jinbase/store/__init__/class-RecordInfo.md): Named tuple returned by store.info() 11 | - uid: Alias for field number 0 12 | - datatype: Alias for field number 1 13 | - created\_at: Alias for field number 2 14 | - [**Store**](/docs/api/modules/jinbase/store/__init__/class-Store.md): Abstract Store class intended to be subclassed by the Kv, Depot, Queue, and Stack stores 15 | - [\_abc\_impl](/docs/api/modules/jinbase/store/__init__/class-Store.md#fields-table) = `<_abc._abc_data object at 0x7eb5e3670540>` 16 | - [chunk\_size](/docs/api/modules/jinbase/store/__init__/class-Store.md#properties-table); _getter_ 17 | - [dbc](/docs/api/modules/jinbase/store/__init__/class-Store.md#properties-table); _getter_ 18 | - [filename](/docs/api/modules/jinbase/store/__init__/class-Store.md#properties-table); _getter_ 19 | - [in\_memory](/docs/api/modules/jinbase/store/__init__/class-Store.md#properties-table); _getter_ 20 | - [is\_closed](/docs/api/modules/jinbase/store/__init__/class-Store.md#properties-table); _getter_ 21 | - [is\_new](/docs/api/modules/jinbase/store/__init__/class-Store.md#properties-table); _getter_ 22 | - [is\_readonly](/docs/api/modules/jinbase/store/__init__/class-Store.md#properties-table); _getter_ 23 | - [jinbase](/docs/api/modules/jinbase/store/__init__/class-Store.md#properties-table); _getter_ 24 | - [model](/docs/api/modules/jinbase/store/__init__/class-Store.md#properties-table); _getter_ 25 | - [timeout](/docs/api/modules/jinbase/store/__init__/class-Store.md#properties-table); _getter_ 26 | - [type\_ref](/docs/api/modules/jinbase/store/__init__/class-Store.md#properties-table); _getter_ 27 | - [count\_bytes](/docs/api/modules/jinbase/store/__init__/class-Store.md#count_bytes): Count all data bytes in the store. 28 | - [count\_chunks](/docs/api/modules/jinbase/store/__init__/class-Store.md#count_chunks): Count all data chunks in the store. 29 | - [count\_records](/docs/api/modules/jinbase/store/__init__/class-Store.md#count_records): Count all records in the store. 30 | - [delete\_all](/docs/api/modules/jinbase/store/__init__/class-Store.md#delete_all): Delete all records in the store 31 | - [is\_empty](/docs/api/modules/jinbase/store/__init__/class-Store.md#is_empty): Tells whether the store is empty or not 32 | - [latest](/docs/api/modules/jinbase/store/__init__/class-Store.md#latest): Retrieve the datetime of the latest write operation. 33 | - [now](/docs/api/modules/jinbase/store/__init__/class-Store.md#now): Get the current datetime. 34 | - [now\_dt](/docs/api/modules/jinbase/store/__init__/class-Store.md#now_dt): Get the current datetime. 35 | - [read\_transaction](/docs/api/modules/jinbase/store/__init__/class-Store.md#read_transaction): Context manager for executing a Read transaction. 36 | - [transaction](/docs/api/modules/jinbase/store/__init__/class-Store.md#transaction): Context manager for executing a transaction. 37 | - [write\_transaction](/docs/api/modules/jinbase/store/__init__/class-Store.md#write_transaction): Context manager for executing a Write transaction. 38 | - [\_delete\_record](/docs/api/modules/jinbase/store/__init__/class-Store.md#_delete_record): No docstring. 39 | - [\_retrieve\_data](/docs/api/modules/jinbase/store/__init__/class-Store.md#_retrieve_data): No docstring. 40 | - [\_store\_data](/docs/api/modules/jinbase/store/__init__/class-Store.md#_store_data): No docstring. 41 | 42 |

Back to top

43 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/store/__init__/class-RecordInfo.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | [Module](/docs/api/modules/jinbase/store/__init__/README.md) | [Source](/src/jinbase/store/__init__.py) 3 | 4 | # Class RecordInfo 5 | > Module: [jinbase.store.\_\_init\_\_](/docs/api/modules/jinbase/store/__init__/README.md) 6 | > 7 | > Class: **RecordInfo** 8 | > 9 | > Inheritance: `tuple` 10 | 11 | Named tuple returned by store.info() 12 | 13 | ## Fields table 14 | Here are fields exposed in the class: 15 | 16 | | Field | Description | 17 | | --- | --- | 18 | | uid | Alias for field number 0 | 19 | | datatype | Alias for field number 1 | 20 | | created\_at | Alias for field number 2 | 21 | 22 |

Back to top

23 | 24 | # Methods within class 25 | Here are methods exposed in the class: 26 | - [\_asdict](#_asdict) 27 | - [\_make](#_make) 28 | - [\_replace](#_replace) 29 | 30 | ## \_asdict 31 | Return a new dict which maps field names to their values. 32 | 33 | ```python 34 | def _asdict(self): 35 | ... 36 | ``` 37 | 38 |

Back to top

39 | 40 | ## \_make 41 | Make a new RecordInfo object from a sequence or iterable 42 | 43 | ```python 44 | @classmethod 45 | def _make(iterable): 46 | ... 47 | ``` 48 | 49 |

Back to top

50 | 51 | ## \_replace 52 | Return a new RecordInfo object replacing specified fields with new values 53 | 54 | ```python 55 | def _replace(self, /, **kwds): 56 | ... 57 | ``` 58 | 59 |

Back to top

60 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/store/__init__/class-Store.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | [Module](/docs/api/modules/jinbase/store/__init__/README.md) | [Source](/src/jinbase/store/__init__.py) 3 | 4 | # Class Store 5 | > Module: [jinbase.store.\_\_init\_\_](/docs/api/modules/jinbase/store/__init__/README.md) 6 | > 7 | > Class: **Store** 8 | > 9 | > Inheritance: `abc.ABC` 10 | 11 | Abstract Store class intended to be subclassed by the 12 | Kv, Depot, Queue, and Stack stores 13 | 14 | ## Fields table 15 | Here are fields exposed in the class: 16 | 17 | | Field | Value | 18 | | --- | --- | 19 | | \_abc\_impl | `<_abc._abc_data object at 0x7eb5e3670540>` | 20 | 21 |

Back to top

22 | 23 | ## Properties table 24 | Here are properties exposed in the class: 25 | 26 | | Property | Methods | Description | 27 | | --- | --- | --- | 28 | | chunk\_size | _getter_ | No docstring. | 29 | | dbc | _getter_ | No docstring. | 30 | | filename | _getter_ | No docstring. | 31 | | in\_memory | _getter_ | No docstring. | 32 | | is\_closed | _getter_ | No docstring. | 33 | | is\_new | _getter_ | No docstring. | 34 | | is\_readonly | _getter_ | No docstring. | 35 | | jinbase | _getter_ | No docstring. | 36 | | model | _getter_ | No docstring. | 37 | | timeout | _getter_ | No docstring. | 38 | | type\_ref | _getter_ | No docstring. | 39 | 40 |

Back to top

41 | 42 | # Methods within class 43 | Here are methods exposed in the class: 44 | - [\_\_init\_\_](#__init__) 45 | - [count\_bytes](#count_bytes) 46 | - [count\_chunks](#count_chunks) 47 | - [count\_records](#count_records) 48 | - [delete\_all](#delete_all) 49 | - [is\_empty](#is_empty) 50 | - [latest](#latest) 51 | - [now](#now) 52 | - [now\_dt](#now_dt) 53 | - [read\_transaction](#read_transaction) 54 | - [transaction](#transaction) 55 | - [write\_transaction](#write_transaction) 56 | - [\_delete\_record](#_delete_record) 57 | - [\_retrieve\_data](#_retrieve_data) 58 | - [\_store\_data](#_store_data) 59 | 60 | ## \_\_init\_\_ 61 | Init. 62 | 63 | ```python 64 | def __init__(self, model, jinbase): 65 | ... 66 | ``` 67 | 68 | | Parameter | Description | 69 | | --- | --- | 70 | | model | A Model namedtuple instance | 71 | | jinbase | Jinbase instance | 72 | 73 |

Back to top

74 | 75 | ## count\_bytes 76 | Count all data bytes in the store. 77 | 78 | ```python 79 | def count_bytes(self): 80 | ... 81 | ``` 82 | 83 | ### Value to return 84 | Returns the count of data bytes 85 | 86 |

Back to top

87 | 88 | ## count\_chunks 89 | Count all data chunks in the store. 90 | 91 | ```python 92 | def count_chunks(self): 93 | ... 94 | ``` 95 | 96 | ### Value to return 97 | Returns the number of chunks 98 | 99 |

Back to top

100 | 101 | ## count\_records 102 | Count all records in the store. 103 | 104 | ```python 105 | def count_records(self): 106 | ... 107 | ``` 108 | 109 | ### Value to return 110 | Returns the number of records 111 | 112 |

Back to top

113 | 114 | ## delete\_all 115 | Delete all records in the store 116 | 117 | ```python 118 | def delete_all(self): 119 | ... 120 | ``` 121 | 122 |

Back to top

123 | 124 | ## is\_empty 125 | Tells whether the store is empty or not 126 | 127 | ```python 128 | def is_empty(self): 129 | ... 130 | ``` 131 | 132 | ### Value to return 133 | Return a boolean. 134 | 135 |

Back to top

136 | 137 | ## latest 138 | Retrieve the datetime of the latest write operation. 139 | 140 | ```python 141 | def latest(self): 142 | ... 143 | ``` 144 | 145 | ### Value to return 146 | Return a datetime string 147 | 148 |

Back to top

149 | 150 | ## now 151 | Get the current datetime. 152 | 153 | ```python 154 | @staticmethod 155 | def now(): 156 | ... 157 | ``` 158 | 159 | ### Value to return 160 | Return a datetime string. 161 | 162 |

Back to top

163 | 164 | ## now\_dt 165 | Get the current datetime. 166 | 167 | ```python 168 | @staticmethod 169 | def now_dt(): 170 | ... 171 | ``` 172 | 173 | ### Value to return 174 | Return a datetime object. 175 | 176 |

Back to top

177 | 178 | ## read\_transaction 179 | Context manager for executing a Read transaction. 180 | 181 | ```python 182 | def read_transaction(self): 183 | ... 184 | ``` 185 | 186 | ### Value to yield 187 | Yields a `litedbc.Cursor` object 188 | 189 |

Back to top

190 | 191 | ## transaction 192 | Context manager for executing a transaction. 193 | 194 | ```python 195 | def transaction(self, transaction_mode=): 196 | ... 197 | ``` 198 | 199 | | Parameter | Description | 200 | | --- | --- | 201 | | transaction | Instance of `litedbc.TransactionMode` | 202 | 203 |

Back to top

204 | 205 | ## write\_transaction 206 | Context manager for executing a Write transaction. 207 | 208 | ```python 209 | def write_transaction(self): 210 | ... 211 | ``` 212 | 213 | ### Value to yield 214 | Yields a `litedbc.Cursor` object 215 | 216 |

Back to top

217 | 218 | ## \_delete\_record 219 | No docstring 220 | 221 | ```python 222 | def _delete_record(self, record_id): 223 | ... 224 | ``` 225 | 226 |

Back to top

227 | 228 | ## \_retrieve\_data 229 | No docstring 230 | 231 | ```python 232 | def _retrieve_data(self, record_id, datatype): 233 | ... 234 | ``` 235 | 236 |

Back to top

237 | 238 | ## \_store\_data 239 | No docstring 240 | 241 | ```python 242 | def _store_data(self, record_id, datatype, value): 243 | ... 244 | ``` 245 | 246 |

Back to top

247 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/store/depot/README.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | Module | [Source](/src/jinbase/store/depot.py) 3 | 4 | # Module Overview 5 | > Module: **jinbase.store.depot** 6 | 7 | The Depot store is defined in this module. 8 | 9 | ## Classes 10 | - [**Depot**](/docs/api/modules/jinbase/store/depot/class-Depot.md): This class represents the Depot store. Note that a Depot object isn't intended to be directly instantiated by the user. 11 | - [\_abc\_impl](/docs/api/modules/jinbase/store/depot/class-Depot.md#fields-table) = `<_abc._abc_data object at 0x7eb5e3637440>` 12 | - [chunk\_size](/docs/api/modules/jinbase/store/depot/class-Depot.md#properties-table); _getter_ 13 | - [dbc](/docs/api/modules/jinbase/store/depot/class-Depot.md#properties-table); _getter_ 14 | - [filename](/docs/api/modules/jinbase/store/depot/class-Depot.md#properties-table); _getter_ 15 | - [in\_memory](/docs/api/modules/jinbase/store/depot/class-Depot.md#properties-table); _getter_ 16 | - [is\_closed](/docs/api/modules/jinbase/store/depot/class-Depot.md#properties-table); _getter_ 17 | - [is\_new](/docs/api/modules/jinbase/store/depot/class-Depot.md#properties-table); _getter_ 18 | - [is\_readonly](/docs/api/modules/jinbase/store/depot/class-Depot.md#properties-table); _getter_ 19 | - [jinbase](/docs/api/modules/jinbase/store/depot/class-Depot.md#properties-table); _getter_ 20 | - [model](/docs/api/modules/jinbase/store/depot/class-Depot.md#properties-table); _getter_ 21 | - [timeout](/docs/api/modules/jinbase/store/depot/class-Depot.md#properties-table); _getter_ 22 | - [type\_ref](/docs/api/modules/jinbase/store/depot/class-Depot.md#properties-table); _getter_ 23 | - [append](/docs/api/modules/jinbase/store/depot/class-Depot.md#append): No docstring. 24 | - [count\_bytes](/docs/api/modules/jinbase/store/depot/class-Depot.md#count_bytes): Count all data bytes in the store. 25 | - [count\_chunks](/docs/api/modules/jinbase/store/depot/class-Depot.md#count_chunks): Count all data chunks in the store. 26 | - [count\_records](/docs/api/modules/jinbase/store/depot/class-Depot.md#count_records): Count all records in the store. 27 | - [delete](/docs/api/modules/jinbase/store/depot/class-Depot.md#delete): No docstring. 28 | - [delete\_all](/docs/api/modules/jinbase/store/depot/class-Depot.md#delete_all): Delete all records in the store 29 | - [delete\_many](/docs/api/modules/jinbase/store/depot/class-Depot.md#delete_many): No docstring. 30 | - [exists](/docs/api/modules/jinbase/store/depot/class-Depot.md#exists): No docstring. 31 | - [extend](/docs/api/modules/jinbase/store/depot/class-Depot.md#extend): No docstring. 32 | - [fields](/docs/api/modules/jinbase/store/depot/class-Depot.md#fields): No docstring. 33 | - [get](/docs/api/modules/jinbase/store/depot/class-Depot.md#get): No docstring. 34 | - [get\_first](/docs/api/modules/jinbase/store/depot/class-Depot.md#get_first): No docstring. 35 | - [get\_last](/docs/api/modules/jinbase/store/depot/class-Depot.md#get_last): No docstring. 36 | - [info](/docs/api/modules/jinbase/store/depot/class-Depot.md#info): No docstring. 37 | - [is\_empty](/docs/api/modules/jinbase/store/depot/class-Depot.md#is_empty): Tells whether the store is empty or not 38 | - [iterate](/docs/api/modules/jinbase/store/depot/class-Depot.md#iterate): No docstring. 39 | - [latest](/docs/api/modules/jinbase/store/depot/class-Depot.md#latest): Retrieve the datetime of the latest write operation. 40 | - [load\_field](/docs/api/modules/jinbase/store/depot/class-Depot.md#load_field): No docstring. 41 | - [now](/docs/api/modules/jinbase/store/depot/class-Depot.md#now): Get the current datetime. 42 | - [now\_dt](/docs/api/modules/jinbase/store/depot/class-Depot.md#now_dt): Get the current datetime. 43 | - [open\_blob](/docs/api/modules/jinbase/store/depot/class-Depot.md#open_blob): No docstring. 44 | - [position](/docs/api/modules/jinbase/store/depot/class-Depot.md#position): No docstring. 45 | - [read\_transaction](/docs/api/modules/jinbase/store/depot/class-Depot.md#read_transaction): Context manager for executing a Read transaction. 46 | - [transaction](/docs/api/modules/jinbase/store/depot/class-Depot.md#transaction): Context manager for executing a transaction. 47 | - [uid](/docs/api/modules/jinbase/store/depot/class-Depot.md#uid): No docstring. 48 | - [uids](/docs/api/modules/jinbase/store/depot/class-Depot.md#uids): No docstring. 49 | - [write\_transaction](/docs/api/modules/jinbase/store/depot/class-Depot.md#write_transaction): Context manager for executing a Write transaction. 50 | - [\_delete\_record](/docs/api/modules/jinbase/store/depot/class-Depot.md#_delete_record): No docstring. 51 | - [\_get\_record](/docs/api/modules/jinbase/store/depot/class-Depot.md#_get_record): No docstring. 52 | - [\_get\_record\_by\_position](/docs/api/modules/jinbase/store/depot/class-Depot.md#_get_record_by_position): No docstring. 53 | - [\_retrieve\_data](/docs/api/modules/jinbase/store/depot/class-Depot.md#_retrieve_data): No docstring. 54 | - [\_store\_data](/docs/api/modules/jinbase/store/depot/class-Depot.md#_store_data): No docstring. 55 | 56 |

Back to top

57 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/store/depot/class-Depot.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | [Module](/docs/api/modules/jinbase/store/depot/README.md) | [Source](/src/jinbase/store/depot.py) 3 | 4 | # Class Depot 5 | > Module: [jinbase.store.depot](/docs/api/modules/jinbase/store/depot/README.md) 6 | > 7 | > Class: **Depot** 8 | > 9 | > Inheritance: [jinbase.store.Store](/docs/api/modules/jinbase/store/class-Store.md) 10 | 11 | This class represents the Depot store. 12 | Note that a Depot object isn't intended to be directly 13 | instantiated by the user. 14 | 15 | ## Fields table 16 | Here are fields exposed in the class: 17 | 18 | | Field | Value | 19 | | --- | --- | 20 | | \_abc\_impl | `<_abc._abc_data object at 0x7eb5e3637440>` | 21 | 22 |

Back to top

23 | 24 | ## Properties table 25 | Here are properties exposed in the class: 26 | 27 | | Property | Methods | Description | 28 | | --- | --- | --- | 29 | | chunk\_size | _getter_ | No docstring. | 30 | | dbc | _getter_ | No docstring. | 31 | | filename | _getter_ | No docstring. | 32 | | in\_memory | _getter_ | No docstring. | 33 | | is\_closed | _getter_ | No docstring. | 34 | | is\_new | _getter_ | No docstring. | 35 | | is\_readonly | _getter_ | No docstring. | 36 | | jinbase | _getter_ | No docstring. | 37 | | model | _getter_ | No docstring. | 38 | | timeout | _getter_ | No docstring. | 39 | | type\_ref | _getter_ | No docstring. | 40 | 41 |

Back to top

42 | 43 | # Methods within class 44 | Here are methods exposed in the class: 45 | - [\_\_init\_\_](#__init__) 46 | - [append](#append) 47 | - [count\_bytes](#count_bytes) 48 | - [count\_chunks](#count_chunks) 49 | - [count\_records](#count_records) 50 | - [delete](#delete) 51 | - [delete\_all](#delete_all) 52 | - [delete\_many](#delete_many) 53 | - [exists](#exists) 54 | - [extend](#extend) 55 | - [fields](#fields) 56 | - [get](#get) 57 | - [get\_first](#get_first) 58 | - [get\_last](#get_last) 59 | - [info](#info) 60 | - [is\_empty](#is_empty) 61 | - [iterate](#iterate) 62 | - [latest](#latest) 63 | - [load\_field](#load_field) 64 | - [now](#now) 65 | - [now\_dt](#now_dt) 66 | - [open\_blob](#open_blob) 67 | - [position](#position) 68 | - [read\_transaction](#read_transaction) 69 | - [transaction](#transaction) 70 | - [uid](#uid) 71 | - [uids](#uids) 72 | - [write\_transaction](#write_transaction) 73 | - [\_delete\_record](#_delete_record) 74 | - [\_get\_record](#_get_record) 75 | - [\_get\_record\_by\_position](#_get_record_by_position) 76 | - [\_retrieve\_data](#_retrieve_data) 77 | - [\_store\_data](#_store_data) 78 | 79 | ## \_\_init\_\_ 80 | Init 81 | 82 | ```python 83 | def __init__(self, jinbase): 84 | ... 85 | ``` 86 | 87 | | Parameter | Description | 88 | | --- | --- | 89 | | jinbase | Jinbase object | 90 | 91 |

Back to top

92 | 93 | ## append 94 | No docstring 95 | 96 | ```python 97 | def append(self, value): 98 | ... 99 | ``` 100 | 101 |

Back to top

102 | 103 | ## count\_bytes 104 | Count all data bytes in the store. 105 | 106 | ```python 107 | def count_bytes(self, uid=None): 108 | ... 109 | ``` 110 | 111 | ### Value to return 112 | Returns the count of data bytes 113 | 114 |

Back to top

115 | 116 | ## count\_chunks 117 | Count all data chunks in the store. 118 | 119 | ```python 120 | def count_chunks(self, uid=None): 121 | ... 122 | ``` 123 | 124 | ### Value to return 125 | Returns the number of chunks 126 | 127 |

Back to top

128 | 129 | ## count\_records 130 | Count all records in the store. 131 | 132 | ```python 133 | def count_records(self): 134 | ... 135 | ``` 136 | 137 | ### Value to return 138 | Returns the number of records 139 | 140 |

Back to top

141 | 142 | ## delete 143 | No docstring 144 | 145 | ```python 146 | def delete(self, uid): 147 | ... 148 | ``` 149 | 150 |

Back to top

151 | 152 | ## delete\_all 153 | Delete all records in the store 154 | 155 | ```python 156 | def delete_all(self): 157 | ... 158 | ``` 159 | 160 |

Back to top

161 | 162 | ## delete\_many 163 | No docstring 164 | 165 | ```python 166 | def delete_many(self, uids): 167 | ... 168 | ``` 169 | 170 |

Back to top

171 | 172 | ## exists 173 | No docstring 174 | 175 | ```python 176 | def exists(self, uid): 177 | ... 178 | ``` 179 | 180 |

Back to top

181 | 182 | ## extend 183 | No docstring 184 | 185 | ```python 186 | def extend(self, values): 187 | ... 188 | ``` 189 | 190 |

Back to top

191 | 192 | ## fields 193 | No docstring 194 | 195 | ```python 196 | def fields(self): 197 | ... 198 | ``` 199 | 200 |

Back to top

201 | 202 | ## get 203 | No docstring 204 | 205 | ```python 206 | def get(self, uid, default=None): 207 | ... 208 | ``` 209 | 210 |

Back to top

211 | 212 | ## get\_first 213 | No docstring 214 | 215 | ```python 216 | def get_first(self, default=None): 217 | ... 218 | ``` 219 | 220 |

Back to top

221 | 222 | ## get\_last 223 | No docstring 224 | 225 | ```python 226 | def get_last(self, default=None): 227 | ... 228 | ``` 229 | 230 |

Back to top

231 | 232 | ## info 233 | No docstring 234 | 235 | ```python 236 | def info(self, uid): 237 | ... 238 | ``` 239 | 240 |

Back to top

241 | 242 | ## is\_empty 243 | Tells whether the store is empty or not 244 | 245 | ```python 246 | def is_empty(self): 247 | ... 248 | ``` 249 | 250 | ### Value to return 251 | Return a boolean. 252 | 253 |

Back to top

254 | 255 | ## iterate 256 | No docstring 257 | 258 | ```python 259 | def iterate(self, *, time_range=None, limit=None, asc=True): 260 | ... 261 | ``` 262 | 263 |

Back to top

264 | 265 | ## latest 266 | Retrieve the datetime of the latest write operation. 267 | 268 | ```python 269 | def latest(self): 270 | ... 271 | ``` 272 | 273 | ### Value to return 274 | Return a datetime string 275 | 276 |

Back to top

277 | 278 | ## load\_field 279 | No docstring 280 | 281 | ```python 282 | def load_field(self, uid, field, default=None): 283 | ... 284 | ``` 285 | 286 |

Back to top

287 | 288 | ## now 289 | Get the current datetime. 290 | 291 | ```python 292 | @staticmethod 293 | def now(): 294 | ... 295 | ``` 296 | 297 | ### Value to return 298 | Return a datetime string. 299 | 300 |

Back to top

301 | 302 | ## now\_dt 303 | Get the current datetime. 304 | 305 | ```python 306 | @staticmethod 307 | def now_dt(): 308 | ... 309 | ``` 310 | 311 | ### Value to return 312 | Return a datetime object. 313 | 314 |

Back to top

315 | 316 | ## open\_blob 317 | No docstring 318 | 319 | ```python 320 | def open_blob(self, uid): 321 | ... 322 | ``` 323 | 324 |

Back to top

325 | 326 | ## position 327 | No docstring 328 | 329 | ```python 330 | def position(self, uid): 331 | ... 332 | ``` 333 | 334 |

Back to top

335 | 336 | ## read\_transaction 337 | Context manager for executing a Read transaction. 338 | 339 | ```python 340 | def read_transaction(self): 341 | ... 342 | ``` 343 | 344 | ### Value to yield 345 | Yields a `litedbc.Cursor` object 346 | 347 |

Back to top

348 | 349 | ## transaction 350 | Context manager for executing a transaction. 351 | 352 | ```python 353 | def transaction(self, transaction_mode=): 354 | ... 355 | ``` 356 | 357 | | Parameter | Description | 358 | | --- | --- | 359 | | transaction | Instance of `litedbc.TransactionMode` | 360 | 361 |

Back to top

362 | 363 | ## uid 364 | No docstring 365 | 366 | ```python 367 | def uid(self, position): 368 | ... 369 | ``` 370 | 371 |

Back to top

372 | 373 | ## uids 374 | No docstring 375 | 376 | ```python 377 | def uids(self, *, time_range=None, limit=None, asc=True): 378 | ... 379 | ``` 380 | 381 |

Back to top

382 | 383 | ## write\_transaction 384 | Context manager for executing a Write transaction. 385 | 386 | ```python 387 | def write_transaction(self): 388 | ... 389 | ``` 390 | 391 | ### Value to yield 392 | Yields a `litedbc.Cursor` object 393 | 394 |

Back to top

395 | 396 | ## \_delete\_record 397 | No docstring 398 | 399 | ```python 400 | def _delete_record(self, record_id): 401 | ... 402 | ``` 403 | 404 |

Back to top

405 | 406 | ## \_get\_record 407 | No docstring 408 | 409 | ```python 410 | def _get_record(self, uid): 411 | ... 412 | ``` 413 | 414 |

Back to top

415 | 416 | ## \_get\_record\_by\_position 417 | No docstring 418 | 419 | ```python 420 | def _get_record_by_position(self, position): 421 | ... 422 | ``` 423 | 424 |

Back to top

425 | 426 | ## \_retrieve\_data 427 | No docstring 428 | 429 | ```python 430 | def _retrieve_data(self, record_id, datatype): 431 | ... 432 | ``` 433 | 434 |

Back to top

435 | 436 | ## \_store\_data 437 | No docstring 438 | 439 | ```python 440 | def _store_data(self, record_id, datatype, value): 441 | ... 442 | ``` 443 | 444 |

Back to top

445 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/store/kv/README.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | Module | [Source](/src/jinbase/store/kv.py) 3 | 4 | # Module Overview 5 | > Module: **jinbase.store.kv** 6 | 7 | The Kv store is defined in this module. 8 | 9 | ## Classes 10 | - [**Kv**](/docs/api/modules/jinbase/store/kv/class-Kv.md): This class represents the Kv store. Note that a Kv object isn't intended to be directly instantiated by the user. 11 | - [\_abc\_impl](/docs/api/modules/jinbase/store/kv/class-Kv.md#fields-table) = `<_abc._abc_data object at 0x7eb5e3648b80>` 12 | - [chunk\_size](/docs/api/modules/jinbase/store/kv/class-Kv.md#properties-table); _getter_ 13 | - [dbc](/docs/api/modules/jinbase/store/kv/class-Kv.md#properties-table); _getter_ 14 | - [filename](/docs/api/modules/jinbase/store/kv/class-Kv.md#properties-table); _getter_ 15 | - [in\_memory](/docs/api/modules/jinbase/store/kv/class-Kv.md#properties-table); _getter_ 16 | - [is\_closed](/docs/api/modules/jinbase/store/kv/class-Kv.md#properties-table); _getter_ 17 | - [is\_new](/docs/api/modules/jinbase/store/kv/class-Kv.md#properties-table); _getter_ 18 | - [is\_readonly](/docs/api/modules/jinbase/store/kv/class-Kv.md#properties-table); _getter_ 19 | - [jinbase](/docs/api/modules/jinbase/store/kv/class-Kv.md#properties-table); _getter_ 20 | - [model](/docs/api/modules/jinbase/store/kv/class-Kv.md#properties-table); _getter_ 21 | - [timeout](/docs/api/modules/jinbase/store/kv/class-Kv.md#properties-table); _getter_ 22 | - [type\_ref](/docs/api/modules/jinbase/store/kv/class-Kv.md#properties-table); _getter_ 23 | - [count\_bytes](/docs/api/modules/jinbase/store/kv/class-Kv.md#count_bytes): Count all data bytes in the store. 24 | - [count\_chunks](/docs/api/modules/jinbase/store/kv/class-Kv.md#count_chunks): Count all data chunks in the store. 25 | - [count\_records](/docs/api/modules/jinbase/store/kv/class-Kv.md#count_records): Count all records in the store. 26 | - [delete](/docs/api/modules/jinbase/store/kv/class-Kv.md#delete): No docstring. 27 | - [delete\_all](/docs/api/modules/jinbase/store/kv/class-Kv.md#delete_all): Delete all records in the store 28 | - [delete\_many](/docs/api/modules/jinbase/store/kv/class-Kv.md#delete_many): No docstring. 29 | - [exists](/docs/api/modules/jinbase/store/kv/class-Kv.md#exists): No docstring. 30 | - [fields](/docs/api/modules/jinbase/store/kv/class-Kv.md#fields): No docstring. 31 | - [get](/docs/api/modules/jinbase/store/kv/class-Kv.md#get): No docstring. 32 | - [info](/docs/api/modules/jinbase/store/kv/class-Kv.md#info): No docstring. 33 | - [int\_keys](/docs/api/modules/jinbase/store/kv/class-Kv.md#int_keys): No docstring. 34 | - [is\_empty](/docs/api/modules/jinbase/store/kv/class-Kv.md#is_empty): Tells whether the store is empty or not 35 | - [iterate](/docs/api/modules/jinbase/store/kv/class-Kv.md#iterate): No docstring. 36 | - [key](/docs/api/modules/jinbase/store/kv/class-Kv.md#key): No docstring. 37 | - [keys](/docs/api/modules/jinbase/store/kv/class-Kv.md#keys): No docstring. 38 | - [latest](/docs/api/modules/jinbase/store/kv/class-Kv.md#latest): Retrieve the datetime of the latest write operation. 39 | - [load\_field](/docs/api/modules/jinbase/store/kv/class-Kv.md#load_field): No docstring. 40 | - [now](/docs/api/modules/jinbase/store/kv/class-Kv.md#now): Get the current datetime. 41 | - [now\_dt](/docs/api/modules/jinbase/store/kv/class-Kv.md#now_dt): Get the current datetime. 42 | - [open\_blob](/docs/api/modules/jinbase/store/kv/class-Kv.md#open_blob): No docstring. 43 | - [read\_transaction](/docs/api/modules/jinbase/store/kv/class-Kv.md#read_transaction): Context manager for executing a Read transaction. 44 | - [replace](/docs/api/modules/jinbase/store/kv/class-Kv.md#replace): No docstring. 45 | - [set](/docs/api/modules/jinbase/store/kv/class-Kv.md#set): No docstring. 46 | - [str\_keys](/docs/api/modules/jinbase/store/kv/class-Kv.md#str_keys): No docstring. 47 | - [transaction](/docs/api/modules/jinbase/store/kv/class-Kv.md#transaction): Context manager for executing a transaction. 48 | - [uid](/docs/api/modules/jinbase/store/kv/class-Kv.md#uid): No docstring. 49 | - [update](/docs/api/modules/jinbase/store/kv/class-Kv.md#update): data is a dictionary 50 | - [write\_transaction](/docs/api/modules/jinbase/store/kv/class-Kv.md#write_transaction): Context manager for executing a Write transaction. 51 | - [\_delete\_record](/docs/api/modules/jinbase/store/kv/class-Kv.md#_delete_record): No docstring. 52 | - [\_get\_record\_by\_key](/docs/api/modules/jinbase/store/kv/class-Kv.md#_get_record_by_key): No docstring. 53 | - [\_retrieve\_data](/docs/api/modules/jinbase/store/kv/class-Kv.md#_retrieve_data): No docstring. 54 | - [\_store\_data](/docs/api/modules/jinbase/store/kv/class-Kv.md#_store_data): No docstring. 55 | 56 |

Back to top

57 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/store/kv/class-Kv.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | [Module](/docs/api/modules/jinbase/store/kv/README.md) | [Source](/src/jinbase/store/kv.py) 3 | 4 | # Class Kv 5 | > Module: [jinbase.store.kv](/docs/api/modules/jinbase/store/kv/README.md) 6 | > 7 | > Class: **Kv** 8 | > 9 | > Inheritance: [jinbase.store.Store](/docs/api/modules/jinbase/store/class-Store.md) 10 | 11 | This class represents the Kv store. 12 | Note that a Kv object isn't intended to be directly 13 | instantiated by the user. 14 | 15 | ## Fields table 16 | Here are fields exposed in the class: 17 | 18 | | Field | Value | 19 | | --- | --- | 20 | | \_abc\_impl | `<_abc._abc_data object at 0x7eb5e3648b80>` | 21 | 22 |

Back to top

23 | 24 | ## Properties table 25 | Here are properties exposed in the class: 26 | 27 | | Property | Methods | Description | 28 | | --- | --- | --- | 29 | | chunk\_size | _getter_ | No docstring. | 30 | | dbc | _getter_ | No docstring. | 31 | | filename | _getter_ | No docstring. | 32 | | in\_memory | _getter_ | No docstring. | 33 | | is\_closed | _getter_ | No docstring. | 34 | | is\_new | _getter_ | No docstring. | 35 | | is\_readonly | _getter_ | No docstring. | 36 | | jinbase | _getter_ | No docstring. | 37 | | model | _getter_ | No docstring. | 38 | | timeout | _getter_ | No docstring. | 39 | | type\_ref | _getter_ | No docstring. | 40 | 41 |

Back to top

42 | 43 | # Methods within class 44 | Here are methods exposed in the class: 45 | - [\_\_init\_\_](#__init__) 46 | - [count\_bytes](#count_bytes) 47 | - [count\_chunks](#count_chunks) 48 | - [count\_records](#count_records) 49 | - [delete](#delete) 50 | - [delete\_all](#delete_all) 51 | - [delete\_many](#delete_many) 52 | - [exists](#exists) 53 | - [fields](#fields) 54 | - [get](#get) 55 | - [info](#info) 56 | - [int\_keys](#int_keys) 57 | - [is\_empty](#is_empty) 58 | - [iterate](#iterate) 59 | - [key](#key) 60 | - [keys](#keys) 61 | - [latest](#latest) 62 | - [load\_field](#load_field) 63 | - [now](#now) 64 | - [now\_dt](#now_dt) 65 | - [open\_blob](#open_blob) 66 | - [read\_transaction](#read_transaction) 67 | - [replace](#replace) 68 | - [set](#set) 69 | - [str\_keys](#str_keys) 70 | - [transaction](#transaction) 71 | - [uid](#uid) 72 | - [update](#update) 73 | - [write\_transaction](#write_transaction) 74 | - [\_delete\_record](#_delete_record) 75 | - [\_get\_record\_by\_key](#_get_record_by_key) 76 | - [\_retrieve\_data](#_retrieve_data) 77 | - [\_store\_data](#_store_data) 78 | 79 | ## \_\_init\_\_ 80 | Init 81 | 82 | ```python 83 | def __init__(self, jinbase): 84 | ... 85 | ``` 86 | 87 | | Parameter | Description | 88 | | --- | --- | 89 | | jinbase | Jinbase object | 90 | 91 |

Back to top

92 | 93 | ## count\_bytes 94 | Count all data bytes in the store. 95 | 96 | ```python 97 | def count_bytes(self, key=None): 98 | ... 99 | ``` 100 | 101 | ### Value to return 102 | Returns the count of data bytes 103 | 104 |

Back to top

105 | 106 | ## count\_chunks 107 | Count all data chunks in the store. 108 | 109 | ```python 110 | def count_chunks(self, key=None): 111 | ... 112 | ``` 113 | 114 | ### Value to return 115 | Returns the number of chunks 116 | 117 |

Back to top

118 | 119 | ## count\_records 120 | Count all records in the store. 121 | 122 | ```python 123 | def count_records(self): 124 | ... 125 | ``` 126 | 127 | ### Value to return 128 | Returns the number of records 129 | 130 |

Back to top

131 | 132 | ## delete 133 | No docstring 134 | 135 | ```python 136 | def delete(self, key): 137 | ... 138 | ``` 139 | 140 |

Back to top

141 | 142 | ## delete\_all 143 | Delete all records in the store 144 | 145 | ```python 146 | def delete_all(self): 147 | ... 148 | ``` 149 | 150 |

Back to top

151 | 152 | ## delete\_many 153 | No docstring 154 | 155 | ```python 156 | def delete_many(self, keys): 157 | ... 158 | ``` 159 | 160 |

Back to top

161 | 162 | ## exists 163 | No docstring 164 | 165 | ```python 166 | def exists(self, key): 167 | ... 168 | ``` 169 | 170 |

Back to top

171 | 172 | ## fields 173 | No docstring 174 | 175 | ```python 176 | def fields(self): 177 | ... 178 | ``` 179 | 180 |

Back to top

181 | 182 | ## get 183 | No docstring 184 | 185 | ```python 186 | def get(self, key, default=None): 187 | ... 188 | ``` 189 | 190 |

Back to top

191 | 192 | ## info 193 | No docstring 194 | 195 | ```python 196 | def info(self, key): 197 | ... 198 | ``` 199 | 200 |

Back to top

201 | 202 | ## int\_keys 203 | No docstring 204 | 205 | ```python 206 | def int_keys(self, first=None, last=None, *, time_range=None, limit=None, asc=True): 207 | ... 208 | ``` 209 | 210 |

Back to top

211 | 212 | ## is\_empty 213 | Tells whether the store is empty or not 214 | 215 | ```python 216 | def is_empty(self): 217 | ... 218 | ``` 219 | 220 | ### Value to return 221 | Return a boolean. 222 | 223 |

Back to top

224 | 225 | ## iterate 226 | No docstring 227 | 228 | ```python 229 | def iterate(self, *, time_range=None, limit=None, asc=True): 230 | ... 231 | ``` 232 | 233 |

Back to top

234 | 235 | ## key 236 | No docstring 237 | 238 | ```python 239 | def key(self, uid): 240 | ... 241 | ``` 242 | 243 |

Back to top

244 | 245 | ## keys 246 | No docstring 247 | 248 | ```python 249 | def keys(self, *, time_range=None, limit=None, asc=True): 250 | ... 251 | ``` 252 | 253 |

Back to top

254 | 255 | ## latest 256 | Retrieve the datetime of the latest write operation. 257 | 258 | ```python 259 | def latest(self): 260 | ... 261 | ``` 262 | 263 | ### Value to return 264 | Return a datetime string 265 | 266 |

Back to top

267 | 268 | ## load\_field 269 | No docstring 270 | 271 | ```python 272 | def load_field(self, key, field, default=None): 273 | ... 274 | ``` 275 | 276 |

Back to top

277 | 278 | ## now 279 | Get the current datetime. 280 | 281 | ```python 282 | @staticmethod 283 | def now(): 284 | ... 285 | ``` 286 | 287 | ### Value to return 288 | Return a datetime string. 289 | 290 |

Back to top

291 | 292 | ## now\_dt 293 | Get the current datetime. 294 | 295 | ```python 296 | @staticmethod 297 | def now_dt(): 298 | ... 299 | ``` 300 | 301 | ### Value to return 302 | Return a datetime object. 303 | 304 |

Back to top

305 | 306 | ## open\_blob 307 | No docstring 308 | 309 | ```python 310 | def open_blob(self, key): 311 | ... 312 | ``` 313 | 314 |

Back to top

315 | 316 | ## read\_transaction 317 | Context manager for executing a Read transaction. 318 | 319 | ```python 320 | def read_transaction(self): 321 | ... 322 | ``` 323 | 324 | ### Value to yield 325 | Yields a `litedbc.Cursor` object 326 | 327 |

Back to top

328 | 329 | ## replace 330 | No docstring 331 | 332 | ```python 333 | def replace(self, key, value): 334 | ... 335 | ``` 336 | 337 |

Back to top

338 | 339 | ## set 340 | No docstring 341 | 342 | ```python 343 | def set(self, key, value): 344 | ... 345 | ``` 346 | 347 |

Back to top

348 | 349 | ## str\_keys 350 | No docstring 351 | 352 | ```python 353 | def str_keys(self, glob=None, *, time_range=None, limit=None, asc=True): 354 | ... 355 | ``` 356 | 357 |

Back to top

358 | 359 | ## transaction 360 | Context manager for executing a transaction. 361 | 362 | ```python 363 | def transaction(self, transaction_mode=): 364 | ... 365 | ``` 366 | 367 | | Parameter | Description | 368 | | --- | --- | 369 | | transaction | Instance of `litedbc.TransactionMode` | 370 | 371 |

Back to top

372 | 373 | ## uid 374 | No docstring 375 | 376 | ```python 377 | def uid(self, key): 378 | ... 379 | ``` 380 | 381 |

Back to top

382 | 383 | ## update 384 | data is a dictionary 385 | 386 | ```python 387 | def update(self, dict_data): 388 | ... 389 | ``` 390 | 391 |

Back to top

392 | 393 | ## write\_transaction 394 | Context manager for executing a Write transaction. 395 | 396 | ```python 397 | def write_transaction(self): 398 | ... 399 | ``` 400 | 401 | ### Value to yield 402 | Yields a `litedbc.Cursor` object 403 | 404 |

Back to top

405 | 406 | ## \_delete\_record 407 | No docstring 408 | 409 | ```python 410 | def _delete_record(self, record_id): 411 | ... 412 | ``` 413 | 414 |

Back to top

415 | 416 | ## \_get\_record\_by\_key 417 | No docstring 418 | 419 | ```python 420 | def _get_record_by_key(self, key): 421 | ... 422 | ``` 423 | 424 |

Back to top

425 | 426 | ## \_retrieve\_data 427 | No docstring 428 | 429 | ```python 430 | def _retrieve_data(self, record_id, datatype): 431 | ... 432 | ``` 433 | 434 |

Back to top

435 | 436 | ## \_store\_data 437 | No docstring 438 | 439 | ```python 440 | def _store_data(self, record_id, datatype, value): 441 | ... 442 | ``` 443 | 444 |

Back to top

445 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/store/queue/README.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | Module | [Source](/src/jinbase/store/queue.py) 3 | 4 | # Module Overview 5 | > Module: **jinbase.store.queue** 6 | 7 | The Queue store is defined in this module. 8 | 9 | ## Classes 10 | - [**Queue**](/docs/api/modules/jinbase/store/queue/class-Queue.md): This class represents the Queue store. Note that a Queue object isn't intended to be directly instantiated by the user. 11 | - [\_abc\_impl](/docs/api/modules/jinbase/store/queue/class-Queue.md#fields-table) = `<_abc._abc_data object at 0x7eb5e36495c0>` 12 | - [chunk\_size](/docs/api/modules/jinbase/store/queue/class-Queue.md#properties-table); _getter_ 13 | - [dbc](/docs/api/modules/jinbase/store/queue/class-Queue.md#properties-table); _getter_ 14 | - [filename](/docs/api/modules/jinbase/store/queue/class-Queue.md#properties-table); _getter_ 15 | - [in\_memory](/docs/api/modules/jinbase/store/queue/class-Queue.md#properties-table); _getter_ 16 | - [is\_closed](/docs/api/modules/jinbase/store/queue/class-Queue.md#properties-table); _getter_ 17 | - [is\_new](/docs/api/modules/jinbase/store/queue/class-Queue.md#properties-table); _getter_ 18 | - [is\_readonly](/docs/api/modules/jinbase/store/queue/class-Queue.md#properties-table); _getter_ 19 | - [jinbase](/docs/api/modules/jinbase/store/queue/class-Queue.md#properties-table); _getter_ 20 | - [model](/docs/api/modules/jinbase/store/queue/class-Queue.md#properties-table); _getter_ 21 | - [timeout](/docs/api/modules/jinbase/store/queue/class-Queue.md#properties-table); _getter_ 22 | - [type\_ref](/docs/api/modules/jinbase/store/queue/class-Queue.md#properties-table); _getter_ 23 | - [back\_uid](/docs/api/modules/jinbase/store/queue/class-Queue.md#back_uid): No docstring. 24 | - [count\_back\_bytes](/docs/api/modules/jinbase/store/queue/class-Queue.md#count_back_bytes): No docstring. 25 | - [count\_back\_chunks](/docs/api/modules/jinbase/store/queue/class-Queue.md#count_back_chunks): No docstring. 26 | - [count\_bytes](/docs/api/modules/jinbase/store/queue/class-Queue.md#count_bytes): Count all data bytes in the store. 27 | - [count\_chunks](/docs/api/modules/jinbase/store/queue/class-Queue.md#count_chunks): Count all data chunks in the store. 28 | - [count\_front\_bytes](/docs/api/modules/jinbase/store/queue/class-Queue.md#count_front_bytes): No docstring. 29 | - [count\_front\_chunks](/docs/api/modules/jinbase/store/queue/class-Queue.md#count_front_chunks): No docstring. 30 | - [count\_records](/docs/api/modules/jinbase/store/queue/class-Queue.md#count_records): Count all records in the store. 31 | - [delete\_all](/docs/api/modules/jinbase/store/queue/class-Queue.md#delete_all): Delete all records in the store 32 | - [dequeue](/docs/api/modules/jinbase/store/queue/class-Queue.md#dequeue): No docstring. 33 | - [enqueue](/docs/api/modules/jinbase/store/queue/class-Queue.md#enqueue): No docstring. 34 | - [enqueue\_many](/docs/api/modules/jinbase/store/queue/class-Queue.md#enqueue_many): No docstring. 35 | - [front\_uid](/docs/api/modules/jinbase/store/queue/class-Queue.md#front_uid): No docstring. 36 | - [info\_back](/docs/api/modules/jinbase/store/queue/class-Queue.md#info_back): No docstring. 37 | - [info\_front](/docs/api/modules/jinbase/store/queue/class-Queue.md#info_front): No docstring. 38 | - [is\_empty](/docs/api/modules/jinbase/store/queue/class-Queue.md#is_empty): Tells whether the store is empty or not 39 | - [latest](/docs/api/modules/jinbase/store/queue/class-Queue.md#latest): Retrieve the datetime of the latest write operation. 40 | - [now](/docs/api/modules/jinbase/store/queue/class-Queue.md#now): Get the current datetime. 41 | - [now\_dt](/docs/api/modules/jinbase/store/queue/class-Queue.md#now_dt): Get the current datetime. 42 | - [peek\_back](/docs/api/modules/jinbase/store/queue/class-Queue.md#peek_back): No docstring. 43 | - [peek\_front](/docs/api/modules/jinbase/store/queue/class-Queue.md#peek_front): No docstring. 44 | - [read\_transaction](/docs/api/modules/jinbase/store/queue/class-Queue.md#read_transaction): Context manager for executing a Read transaction. 45 | - [transaction](/docs/api/modules/jinbase/store/queue/class-Queue.md#transaction): Context manager for executing a transaction. 46 | - [write\_transaction](/docs/api/modules/jinbase/store/queue/class-Queue.md#write_transaction): Context manager for executing a Write transaction. 47 | - [\_delete\_record](/docs/api/modules/jinbase/store/queue/class-Queue.md#_delete_record): No docstring. 48 | - [\_get\_back](/docs/api/modules/jinbase/store/queue/class-Queue.md#_get_back): No docstring. 49 | - [\_get\_front](/docs/api/modules/jinbase/store/queue/class-Queue.md#_get_front): No docstring. 50 | - [\_retrieve\_data](/docs/api/modules/jinbase/store/queue/class-Queue.md#_retrieve_data): No docstring. 51 | - [\_store\_data](/docs/api/modules/jinbase/store/queue/class-Queue.md#_store_data): No docstring. 52 | 53 |

Back to top

54 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/store/queue/class-Queue.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | [Module](/docs/api/modules/jinbase/store/queue/README.md) | [Source](/src/jinbase/store/queue.py) 3 | 4 | # Class Queue 5 | > Module: [jinbase.store.queue](/docs/api/modules/jinbase/store/queue/README.md) 6 | > 7 | > Class: **Queue** 8 | > 9 | > Inheritance: [jinbase.store.Store](/docs/api/modules/jinbase/store/class-Store.md) 10 | 11 | This class represents the Queue store. 12 | Note that a Queue object isn't intended to be directly 13 | instantiated by the user. 14 | 15 | ## Fields table 16 | Here are fields exposed in the class: 17 | 18 | | Field | Value | 19 | | --- | --- | 20 | | \_abc\_impl | `<_abc._abc_data object at 0x7eb5e36495c0>` | 21 | 22 |

Back to top

23 | 24 | ## Properties table 25 | Here are properties exposed in the class: 26 | 27 | | Property | Methods | Description | 28 | | --- | --- | --- | 29 | | chunk\_size | _getter_ | No docstring. | 30 | | dbc | _getter_ | No docstring. | 31 | | filename | _getter_ | No docstring. | 32 | | in\_memory | _getter_ | No docstring. | 33 | | is\_closed | _getter_ | No docstring. | 34 | | is\_new | _getter_ | No docstring. | 35 | | is\_readonly | _getter_ | No docstring. | 36 | | jinbase | _getter_ | No docstring. | 37 | | model | _getter_ | No docstring. | 38 | | timeout | _getter_ | No docstring. | 39 | | type\_ref | _getter_ | No docstring. | 40 | 41 |

Back to top

42 | 43 | # Methods within class 44 | Here are methods exposed in the class: 45 | - [\_\_init\_\_](#__init__) 46 | - [back\_uid](#back_uid) 47 | - [count\_back\_bytes](#count_back_bytes) 48 | - [count\_back\_chunks](#count_back_chunks) 49 | - [count\_bytes](#count_bytes) 50 | - [count\_chunks](#count_chunks) 51 | - [count\_front\_bytes](#count_front_bytes) 52 | - [count\_front\_chunks](#count_front_chunks) 53 | - [count\_records](#count_records) 54 | - [delete\_all](#delete_all) 55 | - [dequeue](#dequeue) 56 | - [enqueue](#enqueue) 57 | - [enqueue\_many](#enqueue_many) 58 | - [front\_uid](#front_uid) 59 | - [info\_back](#info_back) 60 | - [info\_front](#info_front) 61 | - [is\_empty](#is_empty) 62 | - [latest](#latest) 63 | - [now](#now) 64 | - [now\_dt](#now_dt) 65 | - [peek\_back](#peek_back) 66 | - [peek\_front](#peek_front) 67 | - [read\_transaction](#read_transaction) 68 | - [transaction](#transaction) 69 | - [write\_transaction](#write_transaction) 70 | - [\_delete\_record](#_delete_record) 71 | - [\_get\_back](#_get_back) 72 | - [\_get\_front](#_get_front) 73 | - [\_retrieve\_data](#_retrieve_data) 74 | - [\_store\_data](#_store_data) 75 | 76 | ## \_\_init\_\_ 77 | Init 78 | 79 | ```python 80 | def __init__(self, jinbase): 81 | ... 82 | ``` 83 | 84 | | Parameter | Description | 85 | | --- | --- | 86 | | jinbase | Jinbase object | 87 | 88 |

Back to top

89 | 90 | ## back\_uid 91 | No docstring 92 | 93 | ```python 94 | def back_uid(self): 95 | ... 96 | ``` 97 | 98 |

Back to top

99 | 100 | ## count\_back\_bytes 101 | No docstring 102 | 103 | ```python 104 | def count_back_bytes(self): 105 | ... 106 | ``` 107 | 108 |

Back to top

109 | 110 | ## count\_back\_chunks 111 | No docstring 112 | 113 | ```python 114 | def count_back_chunks(self): 115 | ... 116 | ``` 117 | 118 |

Back to top

119 | 120 | ## count\_bytes 121 | Count all data bytes in the store. 122 | 123 | ```python 124 | def count_bytes(self): 125 | ... 126 | ``` 127 | 128 | ### Value to return 129 | Returns the count of data bytes 130 | 131 |

Back to top

132 | 133 | ## count\_chunks 134 | Count all data chunks in the store. 135 | 136 | ```python 137 | def count_chunks(self): 138 | ... 139 | ``` 140 | 141 | ### Value to return 142 | Returns the number of chunks 143 | 144 |

Back to top

145 | 146 | ## count\_front\_bytes 147 | No docstring 148 | 149 | ```python 150 | def count_front_bytes(self): 151 | ... 152 | ``` 153 | 154 |

Back to top

155 | 156 | ## count\_front\_chunks 157 | No docstring 158 | 159 | ```python 160 | def count_front_chunks(self): 161 | ... 162 | ``` 163 | 164 |

Back to top

165 | 166 | ## count\_records 167 | Count all records in the store. 168 | 169 | ```python 170 | def count_records(self): 171 | ... 172 | ``` 173 | 174 | ### Value to return 175 | Returns the number of records 176 | 177 |

Back to top

178 | 179 | ## delete\_all 180 | Delete all records in the store 181 | 182 | ```python 183 | def delete_all(self): 184 | ... 185 | ``` 186 | 187 |

Back to top

188 | 189 | ## dequeue 190 | No docstring 191 | 192 | ```python 193 | def dequeue(self, default=None): 194 | ... 195 | ``` 196 | 197 |

Back to top

198 | 199 | ## enqueue 200 | No docstring 201 | 202 | ```python 203 | def enqueue(self, value): 204 | ... 205 | ``` 206 | 207 |

Back to top

208 | 209 | ## enqueue\_many 210 | No docstring 211 | 212 | ```python 213 | def enqueue_many(self, values): 214 | ... 215 | ``` 216 | 217 |

Back to top

218 | 219 | ## front\_uid 220 | No docstring 221 | 222 | ```python 223 | def front_uid(self): 224 | ... 225 | ``` 226 | 227 |

Back to top

228 | 229 | ## info\_back 230 | No docstring 231 | 232 | ```python 233 | def info_back(self): 234 | ... 235 | ``` 236 | 237 |

Back to top

238 | 239 | ## info\_front 240 | No docstring 241 | 242 | ```python 243 | def info_front(self): 244 | ... 245 | ``` 246 | 247 |

Back to top

248 | 249 | ## is\_empty 250 | Tells whether the store is empty or not 251 | 252 | ```python 253 | def is_empty(self): 254 | ... 255 | ``` 256 | 257 | ### Value to return 258 | Return a boolean. 259 | 260 |

Back to top

261 | 262 | ## latest 263 | Retrieve the datetime of the latest write operation. 264 | 265 | ```python 266 | def latest(self): 267 | ... 268 | ``` 269 | 270 | ### Value to return 271 | Return a datetime string 272 | 273 |

Back to top

274 | 275 | ## now 276 | Get the current datetime. 277 | 278 | ```python 279 | @staticmethod 280 | def now(): 281 | ... 282 | ``` 283 | 284 | ### Value to return 285 | Return a datetime string. 286 | 287 |

Back to top

288 | 289 | ## now\_dt 290 | Get the current datetime. 291 | 292 | ```python 293 | @staticmethod 294 | def now_dt(): 295 | ... 296 | ``` 297 | 298 | ### Value to return 299 | Return a datetime object. 300 | 301 |

Back to top

302 | 303 | ## peek\_back 304 | No docstring 305 | 306 | ```python 307 | def peek_back(self, default=None): 308 | ... 309 | ``` 310 | 311 |

Back to top

312 | 313 | ## peek\_front 314 | No docstring 315 | 316 | ```python 317 | def peek_front(self, default=None): 318 | ... 319 | ``` 320 | 321 |

Back to top

322 | 323 | ## read\_transaction 324 | Context manager for executing a Read transaction. 325 | 326 | ```python 327 | def read_transaction(self): 328 | ... 329 | ``` 330 | 331 | ### Value to yield 332 | Yields a `litedbc.Cursor` object 333 | 334 |

Back to top

335 | 336 | ## transaction 337 | Context manager for executing a transaction. 338 | 339 | ```python 340 | def transaction(self, transaction_mode=): 341 | ... 342 | ``` 343 | 344 | | Parameter | Description | 345 | | --- | --- | 346 | | transaction | Instance of `litedbc.TransactionMode` | 347 | 348 |

Back to top

349 | 350 | ## write\_transaction 351 | Context manager for executing a Write transaction. 352 | 353 | ```python 354 | def write_transaction(self): 355 | ... 356 | ``` 357 | 358 | ### Value to yield 359 | Yields a `litedbc.Cursor` object 360 | 361 |

Back to top

362 | 363 | ## \_delete\_record 364 | No docstring 365 | 366 | ```python 367 | def _delete_record(self, record_id): 368 | ... 369 | ``` 370 | 371 |

Back to top

372 | 373 | ## \_get\_back 374 | No docstring 375 | 376 | ```python 377 | def _get_back(self): 378 | ... 379 | ``` 380 | 381 |

Back to top

382 | 383 | ## \_get\_front 384 | No docstring 385 | 386 | ```python 387 | def _get_front(self): 388 | ... 389 | ``` 390 | 391 |

Back to top

392 | 393 | ## \_retrieve\_data 394 | No docstring 395 | 396 | ```python 397 | def _retrieve_data(self, record_id, datatype): 398 | ... 399 | ``` 400 | 401 |

Back to top

402 | 403 | ## \_store\_data 404 | No docstring 405 | 406 | ```python 407 | def _store_data(self, record_id, datatype, value): 408 | ... 409 | ``` 410 | 411 |

Back to top

412 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/store/stack/README.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | Module | [Source](/src/jinbase/store/stack.py) 3 | 4 | # Module Overview 5 | > Module: **jinbase.store.stack** 6 | 7 | The Stack store is defined in this module. 8 | 9 | ## Classes 10 | - [**Stack**](/docs/api/modules/jinbase/store/stack/class-Stack.md): This class represents the Stack store. Note that a Stack object isn't intended to be directly instantiated by the user. 11 | - [\_abc\_impl](/docs/api/modules/jinbase/store/stack/class-Stack.md#fields-table) = `<_abc._abc_data object at 0x7eb5e3649cc0>` 12 | - [chunk\_size](/docs/api/modules/jinbase/store/stack/class-Stack.md#properties-table); _getter_ 13 | - [dbc](/docs/api/modules/jinbase/store/stack/class-Stack.md#properties-table); _getter_ 14 | - [filename](/docs/api/modules/jinbase/store/stack/class-Stack.md#properties-table); _getter_ 15 | - [in\_memory](/docs/api/modules/jinbase/store/stack/class-Stack.md#properties-table); _getter_ 16 | - [is\_closed](/docs/api/modules/jinbase/store/stack/class-Stack.md#properties-table); _getter_ 17 | - [is\_new](/docs/api/modules/jinbase/store/stack/class-Stack.md#properties-table); _getter_ 18 | - [is\_readonly](/docs/api/modules/jinbase/store/stack/class-Stack.md#properties-table); _getter_ 19 | - [jinbase](/docs/api/modules/jinbase/store/stack/class-Stack.md#properties-table); _getter_ 20 | - [model](/docs/api/modules/jinbase/store/stack/class-Stack.md#properties-table); _getter_ 21 | - [timeout](/docs/api/modules/jinbase/store/stack/class-Stack.md#properties-table); _getter_ 22 | - [type\_ref](/docs/api/modules/jinbase/store/stack/class-Stack.md#properties-table); _getter_ 23 | - [count\_bytes](/docs/api/modules/jinbase/store/stack/class-Stack.md#count_bytes): Count all data bytes in the store. 24 | - [count\_chunks](/docs/api/modules/jinbase/store/stack/class-Stack.md#count_chunks): Count all data chunks in the store. 25 | - [count\_records](/docs/api/modules/jinbase/store/stack/class-Stack.md#count_records): Count all records in the store. 26 | - [count\_top\_bytes](/docs/api/modules/jinbase/store/stack/class-Stack.md#count_top_bytes): No docstring. 27 | - [count\_top\_chunks](/docs/api/modules/jinbase/store/stack/class-Stack.md#count_top_chunks): No docstring. 28 | - [delete\_all](/docs/api/modules/jinbase/store/stack/class-Stack.md#delete_all): Delete all records in the store 29 | - [info\_top](/docs/api/modules/jinbase/store/stack/class-Stack.md#info_top): No docstring. 30 | - [is\_empty](/docs/api/modules/jinbase/store/stack/class-Stack.md#is_empty): Tells whether the store is empty or not 31 | - [latest](/docs/api/modules/jinbase/store/stack/class-Stack.md#latest): Retrieve the datetime of the latest write operation. 32 | - [now](/docs/api/modules/jinbase/store/stack/class-Stack.md#now): Get the current datetime. 33 | - [now\_dt](/docs/api/modules/jinbase/store/stack/class-Stack.md#now_dt): Get the current datetime. 34 | - [peek](/docs/api/modules/jinbase/store/stack/class-Stack.md#peek): No docstring. 35 | - [pop](/docs/api/modules/jinbase/store/stack/class-Stack.md#pop): No docstring. 36 | - [push](/docs/api/modules/jinbase/store/stack/class-Stack.md#push): No docstring. 37 | - [push\_many](/docs/api/modules/jinbase/store/stack/class-Stack.md#push_many): No docstring. 38 | - [read\_transaction](/docs/api/modules/jinbase/store/stack/class-Stack.md#read_transaction): Context manager for executing a Read transaction. 39 | - [top\_uid](/docs/api/modules/jinbase/store/stack/class-Stack.md#top_uid): No docstring. 40 | - [transaction](/docs/api/modules/jinbase/store/stack/class-Stack.md#transaction): Context manager for executing a transaction. 41 | - [write\_transaction](/docs/api/modules/jinbase/store/stack/class-Stack.md#write_transaction): Context manager for executing a Write transaction. 42 | - [\_delete\_record](/docs/api/modules/jinbase/store/stack/class-Stack.md#_delete_record): No docstring. 43 | - [\_get\_top](/docs/api/modules/jinbase/store/stack/class-Stack.md#_get_top): No docstring. 44 | - [\_retrieve\_data](/docs/api/modules/jinbase/store/stack/class-Stack.md#_retrieve_data): No docstring. 45 | - [\_store\_data](/docs/api/modules/jinbase/store/stack/class-Stack.md#_store_data): No docstring. 46 | 47 |

Back to top

48 | -------------------------------------------------------------------------------- /docs/api/modules/jinbase/store/stack/class-Stack.md: -------------------------------------------------------------------------------- 1 | ###### Jinbase API Reference 2 | [Home](/docs/api/README.md) | [Project](/README.md) | [Module](/docs/api/modules/jinbase/store/stack/README.md) | [Source](/src/jinbase/store/stack.py) 3 | 4 | # Class Stack 5 | > Module: [jinbase.store.stack](/docs/api/modules/jinbase/store/stack/README.md) 6 | > 7 | > Class: **Stack** 8 | > 9 | > Inheritance: [jinbase.store.Store](/docs/api/modules/jinbase/store/class-Store.md) 10 | 11 | This class represents the Stack store. 12 | Note that a Stack object isn't intended to be directly 13 | instantiated by the user. 14 | 15 | ## Fields table 16 | Here are fields exposed in the class: 17 | 18 | | Field | Value | 19 | | --- | --- | 20 | | \_abc\_impl | `<_abc._abc_data object at 0x7eb5e3649cc0>` | 21 | 22 |

Back to top

23 | 24 | ## Properties table 25 | Here are properties exposed in the class: 26 | 27 | | Property | Methods | Description | 28 | | --- | --- | --- | 29 | | chunk\_size | _getter_ | No docstring. | 30 | | dbc | _getter_ | No docstring. | 31 | | filename | _getter_ | No docstring. | 32 | | in\_memory | _getter_ | No docstring. | 33 | | is\_closed | _getter_ | No docstring. | 34 | | is\_new | _getter_ | No docstring. | 35 | | is\_readonly | _getter_ | No docstring. | 36 | | jinbase | _getter_ | No docstring. | 37 | | model | _getter_ | No docstring. | 38 | | timeout | _getter_ | No docstring. | 39 | | type\_ref | _getter_ | No docstring. | 40 | 41 |

Back to top

42 | 43 | # Methods within class 44 | Here are methods exposed in the class: 45 | - [\_\_init\_\_](#__init__) 46 | - [count\_bytes](#count_bytes) 47 | - [count\_chunks](#count_chunks) 48 | - [count\_records](#count_records) 49 | - [count\_top\_bytes](#count_top_bytes) 50 | - [count\_top\_chunks](#count_top_chunks) 51 | - [delete\_all](#delete_all) 52 | - [info\_top](#info_top) 53 | - [is\_empty](#is_empty) 54 | - [latest](#latest) 55 | - [now](#now) 56 | - [now\_dt](#now_dt) 57 | - [peek](#peek) 58 | - [pop](#pop) 59 | - [push](#push) 60 | - [push\_many](#push_many) 61 | - [read\_transaction](#read_transaction) 62 | - [top\_uid](#top_uid) 63 | - [transaction](#transaction) 64 | - [write\_transaction](#write_transaction) 65 | - [\_delete\_record](#_delete_record) 66 | - [\_get\_top](#_get_top) 67 | - [\_retrieve\_data](#_retrieve_data) 68 | - [\_store\_data](#_store_data) 69 | 70 | ## \_\_init\_\_ 71 | Init 72 | 73 | ```python 74 | def __init__(self, jinbase): 75 | ... 76 | ``` 77 | 78 | | Parameter | Description | 79 | | --- | --- | 80 | | jinbase | Jinbase object | 81 | 82 |

Back to top

83 | 84 | ## count\_bytes 85 | Count all data bytes in the store. 86 | 87 | ```python 88 | def count_bytes(self): 89 | ... 90 | ``` 91 | 92 | ### Value to return 93 | Returns the count of data bytes 94 | 95 |

Back to top

96 | 97 | ## count\_chunks 98 | Count all data chunks in the store. 99 | 100 | ```python 101 | def count_chunks(self): 102 | ... 103 | ``` 104 | 105 | ### Value to return 106 | Returns the number of chunks 107 | 108 |

Back to top

109 | 110 | ## count\_records 111 | Count all records in the store. 112 | 113 | ```python 114 | def count_records(self): 115 | ... 116 | ``` 117 | 118 | ### Value to return 119 | Returns the number of records 120 | 121 |

Back to top

122 | 123 | ## count\_top\_bytes 124 | No docstring 125 | 126 | ```python 127 | def count_top_bytes(self): 128 | ... 129 | ``` 130 | 131 |

Back to top

132 | 133 | ## count\_top\_chunks 134 | No docstring 135 | 136 | ```python 137 | def count_top_chunks(self): 138 | ... 139 | ``` 140 | 141 |

Back to top

142 | 143 | ## delete\_all 144 | Delete all records in the store 145 | 146 | ```python 147 | def delete_all(self): 148 | ... 149 | ``` 150 | 151 |

Back to top

152 | 153 | ## info\_top 154 | No docstring 155 | 156 | ```python 157 | def info_top(self): 158 | ... 159 | ``` 160 | 161 |

Back to top

162 | 163 | ## is\_empty 164 | Tells whether the store is empty or not 165 | 166 | ```python 167 | def is_empty(self): 168 | ... 169 | ``` 170 | 171 | ### Value to return 172 | Return a boolean. 173 | 174 |

Back to top

175 | 176 | ## latest 177 | Retrieve the datetime of the latest write operation. 178 | 179 | ```python 180 | def latest(self): 181 | ... 182 | ``` 183 | 184 | ### Value to return 185 | Return a datetime string 186 | 187 |

Back to top

188 | 189 | ## now 190 | Get the current datetime. 191 | 192 | ```python 193 | @staticmethod 194 | def now(): 195 | ... 196 | ``` 197 | 198 | ### Value to return 199 | Return a datetime string. 200 | 201 |

Back to top

202 | 203 | ## now\_dt 204 | Get the current datetime. 205 | 206 | ```python 207 | @staticmethod 208 | def now_dt(): 209 | ... 210 | ``` 211 | 212 | ### Value to return 213 | Return a datetime object. 214 | 215 |

Back to top

216 | 217 | ## peek 218 | No docstring 219 | 220 | ```python 221 | def peek(self, default=None): 222 | ... 223 | ``` 224 | 225 |

Back to top

226 | 227 | ## pop 228 | No docstring 229 | 230 | ```python 231 | def pop(self, default=None): 232 | ... 233 | ``` 234 | 235 |

Back to top

236 | 237 | ## push 238 | No docstring 239 | 240 | ```python 241 | def push(self, value): 242 | ... 243 | ``` 244 | 245 |

Back to top

246 | 247 | ## push\_many 248 | No docstring 249 | 250 | ```python 251 | def push_many(self, values): 252 | ... 253 | ``` 254 | 255 |

Back to top

256 | 257 | ## read\_transaction 258 | Context manager for executing a Read transaction. 259 | 260 | ```python 261 | def read_transaction(self): 262 | ... 263 | ``` 264 | 265 | ### Value to yield 266 | Yields a `litedbc.Cursor` object 267 | 268 |

Back to top

269 | 270 | ## top\_uid 271 | No docstring 272 | 273 | ```python 274 | def top_uid(self): 275 | ... 276 | ``` 277 | 278 |

Back to top

279 | 280 | ## transaction 281 | Context manager for executing a transaction. 282 | 283 | ```python 284 | def transaction(self, transaction_mode=): 285 | ... 286 | ``` 287 | 288 | | Parameter | Description | 289 | | --- | --- | 290 | | transaction | Instance of `litedbc.TransactionMode` | 291 | 292 |

Back to top

293 | 294 | ## write\_transaction 295 | Context manager for executing a Write transaction. 296 | 297 | ```python 298 | def write_transaction(self): 299 | ... 300 | ``` 301 | 302 | ### Value to yield 303 | Yields a `litedbc.Cursor` object 304 | 305 |

Back to top

306 | 307 | ## \_delete\_record 308 | No docstring 309 | 310 | ```python 311 | def _delete_record(self, record_id): 312 | ... 313 | ``` 314 | 315 |

Back to top

316 | 317 | ## \_get\_top 318 | No docstring 319 | 320 | ```python 321 | def _get_top(self): 322 | ... 323 | ``` 324 | 325 |

Back to top

326 | 327 | ## \_retrieve\_data 328 | No docstring 329 | 330 | ```python 331 | def _retrieve_data(self, record_id, datatype): 332 | ... 333 | ``` 334 | 335 |

Back to top

336 | 337 | ## \_store\_data 338 | No docstring 339 | 340 | ```python 341 | def _store_data(self, record_id, datatype, value): 342 | ... 343 | ``` 344 | 345 |

Back to top

346 | -------------------------------------------------------------------------------- /mikedoc.kvf: -------------------------------------------------------------------------------- 1 | # project name 2 | project_name = 'Jinbase' 3 | 4 | # project's website or README 5 | project_url = '/README.md' 6 | 7 | # package directory (relative path) 8 | pkg_dir = 'src/jinbase' 9 | 10 | # API directory (relative path) 11 | api_dir = 'docs/api' 12 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | # https://stackoverflow.com/q/76248637 (this is why setup.cfg/setup.py are still relevant !) 2 | # https://packaging.python.org/en/latest/guides/writing-pyproject-toml 3 | # https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html 4 | # https://setuptools.pypa.io/en/latest/userguide/datafiles.html 5 | 6 | [build-system] 7 | requires = ["setuptools"] 8 | build-backend = "setuptools.build_meta" 9 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = jinbase 3 | version = file: VERSION 4 | url = https://github.com/pyrustic/jinbase 5 | author = Pyrustic Architect 6 | author_email = rusticalex@yahoo.com 7 | maintainer = Pyrustic Architect 8 | maintainer_email = rusticalex@yahoo.com 9 | description = Multi-model transactional embedded database 10 | long_description = file: README.md 11 | long_description_content_type = text/markdown 12 | license = MIT 13 | keywords = 14 | pyrustic 15 | # https://pypi.org/classifiers/ 16 | # Development Status :: 3 - Alpha 17 | # Development Status :: 4 - Beta 18 | # Development Status :: 5 - Production/Stable 19 | classifiers = 20 | Programming Language :: Python 21 | Programming Language :: Python :: 3 22 | License :: OSI Approved :: MIT License 23 | Operating System :: OS Independent 24 | Intended Audience :: Developers 25 | Development Status :: 4 - Beta 26 | 27 | [options] 28 | python_requires = >=3.5 29 | package_dir = 30 | = src 31 | packages = find: 32 | include_package_data = true 33 | zip_safe = false 34 | install_requires = 35 | paradict 36 | litedbc 37 | 38 | [options.packages.find] 39 | where = src 40 | 41 | [options.entry_points] 42 | console_scripts = 43 | jinbase = jinbase.__main__:main 44 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # File generated by Setupinit 2 | import setuptools 3 | 4 | 5 | if __name__ == "__main__": 6 | setuptools.setup() 7 | -------------------------------------------------------------------------------- /src/jinbase/__init__.py: -------------------------------------------------------------------------------- 1 | """The main module of Jinbase.""" 2 | from datetime import datetime, timezone 3 | from paradict import TypeRef 4 | from litedbc import LiteDBC, TransactionMode 5 | from jinbase import errors, queries, misc, const 6 | from jinbase.store import RecordInfo 7 | from jinbase.store.depot import Depot 8 | from jinbase.store.kv import Kv 9 | from jinbase.store.queue import Queue 10 | from jinbase.store.stack import Stack 11 | from jinbase.const import (Model, TimestampPrecision, TIMESTAMP_PRECISION, 12 | TIMEOUT, CHUNK_SIZE, JINBASE_HOME, JINBASE_VERSION, 13 | USER_HOME, DATETIME_FORMAT) 14 | 15 | 16 | __all__ = ["Jinbase", "Model", "TypeRef", "RecordInfo", 17 | "TimestampPrecision", "TIMEOUT", "CHUNK_SIZE", 18 | "TIMESTAMP_PRECISION", "DATETIME_FORMAT", 19 | "USER_HOME", "JINBASE_HOME", "JINBASE_VERSION"] 20 | 21 | 22 | class Jinbase: 23 | """The Jinbase class. A Jinbase object is intended to 24 | be directly instantiated by the user.""" 25 | def __init__(self, filename=None, *, auto_create=True, 26 | is_readonly=False, timeout=TIMEOUT, 27 | type_ref=None, chunk_size=CHUNK_SIZE, 28 | timestamp_precision=TIMESTAMP_PRECISION): 29 | """ 30 | Init. 31 | 32 | [params] 33 | - filename: The filename of the Jinbase database. 34 | If the pointed file doesn't exist, it will be created 35 | if `auto_create` is set to True. 36 | - auto_create: Boolean to tell whether a nonexistent database file 37 | should automatically be created or not. Defaults to True. 38 | - is_readonly: Boolean to tell whether the database connection should be in 39 | readonly or not. 40 | - timeout: Timeout in seconds for all database operations. 41 | Defaults to the value of `jinbase.TIMEOUT` 42 | - type_ref: A paradict.TypeRef instance 43 | - chunk_size: Chunk size in bytes. Defaults to `jinbase.CHUNK_SIZE`. 44 | Note that this value is only relevant when the Jinbase tables are created. 45 | - timestamp_precision: An instance of the `jinbase.TimestampPrecision` namedtuple. 46 | Defaults to `jinbase.TIMESTAMP_PRECISION`. 47 | Note that this value is only relevant when the Jinbase tables are created. 48 | """ 49 | self._dbc = create_dbc(filename, auto_create, is_readonly, timeout) 50 | with self._dbc.cursor() as cur: 51 | cur.executescript(queries.INIT_SCRIPT) 52 | chunk_size = int(chunk_size) if chunk_size else CHUNK_SIZE 53 | x = ensure_jinbase(self._dbc, chunk_size, 54 | TimestampPrecision(timestamp_precision)) 55 | self._version, self._created_at, self._chunk_size, self._timestamp_precision = x 56 | self._creation_dt = datetime.fromisoformat(self._created_at).astimezone(tz=timezone.utc) 57 | self._auto_create = auto_create 58 | self._filename = self._dbc.filename 59 | self._is_readonly = self._dbc.is_readonly 60 | self._timeout = self._dbc.timeout 61 | self._type_ref = TypeRef() if type_ref is None else type_ref 62 | # stores 63 | self._kv = Kv(self) 64 | self._depot = Depot(self) 65 | self._queue = Queue(self) 66 | self._stack = Stack(self) 67 | 68 | @property 69 | def kv(self): 70 | return self._kv 71 | 72 | @property 73 | def depot(self): 74 | return self._depot 75 | 76 | @property 77 | def queue(self): 78 | return self._queue 79 | 80 | @property 81 | def stack(self): 82 | return self._stack 83 | 84 | @property 85 | def filename(self): 86 | return self._filename 87 | 88 | @property 89 | def is_readonly(self): 90 | return self._is_readonly 91 | 92 | @property 93 | def timeout(self): 94 | return self._timeout 95 | 96 | @property 97 | def type_ref(self): 98 | return self._type_ref 99 | 100 | @property 101 | def chunk_size(self): 102 | return self._chunk_size 103 | 104 | @property 105 | def timestamp_precision(self): 106 | return self._timestamp_precision 107 | 108 | @property 109 | def dbc(self): 110 | """The instance of litedbc.LiteDBC""" 111 | return self._dbc 112 | 113 | @property 114 | def created_at(self): 115 | return self._created_at 116 | 117 | @property 118 | def creation_dt(self): 119 | return self._creation_dt 120 | 121 | @property 122 | def version(self): 123 | return self._version 124 | 125 | @property 126 | def is_new(self): 127 | return self._dbc.is_new 128 | 129 | @property 130 | def in_memory(self): 131 | return self._dbc.in_memory 132 | 133 | @property 134 | def is_closed(self): 135 | return self._dbc.is_closed 136 | 137 | @property 138 | def is_destroyed(self): 139 | return self._dbc.is_destroyed 140 | 141 | def scan(self): 142 | """ 143 | Scan the Jinbase database 144 | 145 | [returns] 146 | A dictionary object whose keys are jinbase.Model namedtuples 147 | and values are tuples of the total record count and total byte count. 148 | """ 149 | model2store = {Model.DEPOT: self._depot, 150 | Model.KV: self._kv, 151 | Model.QUEUE: self._queue, 152 | Model.STACK: self._stack} 153 | return {model: (store.count_records(), store.count_bytes()) 154 | for model, store in model2store.items()} 155 | 156 | @staticmethod 157 | def now(): 158 | """ 159 | Get the current utc datetime. 160 | 161 | [returns] 162 | A utc instance of `datetime.datetime` 163 | """ 164 | return misc.now() 165 | 166 | @staticmethod 167 | def now_dt(): 168 | """ 169 | Get the current utc datetime. 170 | 171 | [returns] 172 | A utc string 173 | """ 174 | return misc.now_dt() 175 | 176 | def latest(self): 177 | """ 178 | Get the utc datetime of the latest operation. 179 | 180 | [returns] 181 | A utc instance of `datetime.datetime` 182 | """ 183 | with self._dbc.cursor() as cur: 184 | timestamps = list() 185 | for model_name in [model.name.lower() for model in Model]: 186 | sql = queries.LATEST_WRITE.format(model=model_name) 187 | cur.execute(sql) # read 188 | r = cur.fetchone() 189 | if r is None: 190 | continue 191 | db_timestamp = r[0] 192 | timestamps.append(db_timestamp) 193 | db_timestamp = -1 194 | for t in timestamps: 195 | if t > db_timestamp: 196 | db_timestamp = t 197 | if db_timestamp == -1: 198 | return 199 | db_epoch = self._created_at 200 | return misc.get_datetime_str(db_epoch, db_timestamp, 201 | self._timestamp_precision) 202 | 203 | def count_records(self): 204 | with self._dbc.transaction() as cursor: 205 | n1 = self._kv.count_records() 206 | n2 = self._depot.count_records() 207 | n3 = self._queue.count_records() 208 | n4 = self._stack.count_records() 209 | return n1 + n2 + n3 + n4 210 | 211 | def count_bytes(self): 212 | with self._dbc.transaction() as cursor: 213 | n1 = self._kv.count_bytes() 214 | n2 = self._depot.count_bytes() 215 | n3 = self._queue.count_bytes() 216 | n4 = self._stack.count_bytes() 217 | return n1 + n2 + n3 + n4 218 | 219 | def count_chunks(self): 220 | with self._dbc.transaction() as cursor: 221 | n1 = self._kv.count_chunks() 222 | n2 = self._depot.count_chunks() 223 | n3 = self._queue.count_chunks() 224 | n4 = self._stack.count_chunks() 225 | return n1 + n2 + n3 + n4 226 | 227 | def transaction(self, transaction_mode=TransactionMode.DEFERRED): 228 | return self._dbc.transaction(transaction_mode=transaction_mode) 229 | 230 | def read_transaction(self): 231 | return self._dbc.transaction(transaction_mode=TransactionMode.DEFERRED) 232 | 233 | def write_transaction(self): 234 | return self._dbc.transaction(transaction_mode=TransactionMode.IMMEDIATE) 235 | 236 | def vacuum(self): 237 | """Vacuum the database""" 238 | self._dbc.vacuum() 239 | 240 | def vacuum_into(self, dst): 241 | """Vacuum into a file whose name is provided via `dst`.""" 242 | self._dbc.vacuum_into(dst) 243 | 244 | def set_locking_mode(self, locking_mode): 245 | return self._dbc.set_locking_mode(locking_mode) 246 | 247 | def get_locking_mode(self): 248 | return self._dbc.get_locking_mode() 249 | 250 | def set_sync_mode(self, sync_mode): 251 | return self._dbc.set_sync_mode(sync_mode) 252 | 253 | def get_sync_mode(self): 254 | return self._dbc.get_sync_mode() 255 | 256 | def set_journal_mode(self, journal_mode): 257 | return self._dbc.set_journal_mode(journal_mode) 258 | 259 | def get_journal_mode(self): 260 | return self._dbc.get_journal_mode() 261 | 262 | def set_progress_handler(self, callback, n): 263 | return self._dbc.set_progress_handler(callback, n) 264 | 265 | def set_trace_callback(self, callback): 266 | return self._dbc.set_trace_callback(callback) 267 | 268 | def interrupt(self): 269 | return self._dbc.interrupt() 270 | 271 | def backup(self, dst, *, pages=-1, 272 | progress=None, sleep=0.250): 273 | self._dbc.backup(dst, pages=pages, progress=progress, 274 | sleep=sleep) 275 | 276 | def iterdump(self): 277 | """Returns an iterator to the dump of the database 278 | in an SQL text format""" 279 | return self._dbc.iterdump() 280 | 281 | def copy(self): 282 | """Create a new Jinbase instance that 283 | points to the same database file""" 284 | return self.__copy__() 285 | 286 | def close(self): 287 | """Close the connection""" 288 | return self._dbc.close() 289 | 290 | def destroy(self): 291 | """Destroy the database file""" 292 | return self._dbc.destroy() 293 | 294 | def __enter__(self): 295 | return self 296 | 297 | def __exit__(self, exc_type, exc_val, exc_tb): 298 | self.close() 299 | 300 | def __copy__(self): 301 | return Jinbase(self._filename, auto_create=self._auto_create, 302 | is_readonly=self._is_readonly, timeout=self._timeout, 303 | type_ref=self._type_ref, chunk_size=self._chunk_size) 304 | 305 | 306 | def create_dbc(filename, auto_create, is_readonly, timeout): 307 | def on_create_conn(dbc): 308 | with dbc.cursor() as cur: 309 | cur.executescript(queries.CONNECTION_DIRECTIVES, 310 | transaction_mode=None) 311 | dbc = LiteDBC(filename, auto_create=auto_create, 312 | is_readonly=is_readonly, timeout=timeout, 313 | on_create_conn=on_create_conn) 314 | return dbc 315 | 316 | 317 | def ensure_jinbase(dbc, chunk_size, timestamp_precision): 318 | sql = queries.GET_JINBASE_INFO 319 | if dbc.is_readonly: 320 | with dbc.cursor() as cur: 321 | cur.execute(sql) 322 | r = cur.fetchone() 323 | if r is None: 324 | msg = "Not a Jinbase file." 325 | raise Exception(msg) 326 | else: 327 | version, created_at, chunk_size, timestamp_precision = r 328 | return version, created_at, chunk_size, TimestampPrecision(timestamp_precision) 329 | else: 330 | with dbc.immediate_transaction() as cursor: 331 | sql = queries.GET_JINBASE_INFO 332 | cursor.execute(sql) 333 | r = cursor.fetchone() 334 | if r is None: 335 | sql = queries.SET_JINBASE_INFO 336 | version = const.JINBASE_VERSION 337 | created_at = misc.now() 338 | cursor.execute(sql, (version, created_at, chunk_size, 339 | timestamp_precision.value)) 340 | else: 341 | version, created_at, chunk_size, timestamp_precision = r 342 | return version, created_at, chunk_size, TimestampPrecision(timestamp_precision) 343 | -------------------------------------------------------------------------------- /src/jinbase/__main__.py: -------------------------------------------------------------------------------- 1 | 2 | __all__ = [] 3 | 4 | 5 | def main(): 6 | print("github.com/pyrustic/jinbase") 7 | 8 | 9 | if __name__ == "__main__": 10 | main() 11 | -------------------------------------------------------------------------------- /src/jinbase/blob/__init__.py: -------------------------------------------------------------------------------- 1 | """The Blob class is defined here.""" 2 | import os 3 | from jinbase import queries 4 | 5 | 6 | __all__ = ["Blob"] 7 | 8 | 9 | class Blob: 10 | """The Blob class allows a Read access to the blobs of Jinbase records. 11 | This class isn't intended to be directly instantiated by the user.""" 12 | def __init__(self, store, record_id, n_bytes, 13 | n_chunks): 14 | """ 15 | Initialization. 16 | 17 | [params] 18 | - store: Store instance. 19 | - record_id: The record's uid. 20 | - n_bytes: The size of the blob in bytes. 21 | - n_chunks: The number of chunks. 22 | """ 23 | self._store = store 24 | self._record_id = record_id 25 | self._n_bytes = n_bytes 26 | self._n_chunks = n_chunks 27 | self._dbc = store.dbc 28 | self._model_name = store.model.name.lower() 29 | self._chunk_size = store.chunk_size 30 | self._position = 0 31 | self._slice_obj = slice(0, 0, 1) 32 | self._blob_io_files = dict() 33 | 34 | def read(self, length=-1, /): 35 | """ 36 | Read the blob. 37 | 38 | [params] 39 | - length: The number of bytes to read. 40 | Defaults to -1 to mean the entire blob. 41 | Note that the cursor moves as reads are done. 42 | 43 | [return] 44 | Returns bytes or an empty byte. 45 | """ 46 | data = self._read(self._position, length) 47 | self._position = update_position(self._position, len(data), 48 | os.SEEK_CUR, self._n_bytes) 49 | return data 50 | 51 | def write(self, data, /): 52 | """Jinbase doesn't allow Writes on blobs""" 53 | raise NotImplementedError # deliberately ! 54 | 55 | def tell(self): 56 | """Returns the current position of the cursor""" 57 | return self._position 58 | 59 | def seek(self, offset, origin=os.SEEK_SET, /): 60 | """ 61 | Move the cursor to another position 62 | 63 | [params] 64 | - offset: Offset value 65 | - origin: os.SEEK_SET, os.SEEK_CUR, or os.SEEK_END. 66 | Note that os.SEEK_END referes to position beyond the last 67 | character of the file, not the last character itself. 68 | """ 69 | self._position = update_position(self._position, 70 | offset, origin, 71 | self._n_bytes) 72 | 73 | def close(self): 74 | """Close this Blob instance. Note that this method 75 | is automatically called by the Store's open_blob method. 76 | """ 77 | for blob_io_file in self._blob_io_files.values(): 78 | try: 79 | blob_io_file.close() 80 | except Exception as e: 81 | pass 82 | 83 | def _read(self, position, length): 84 | if length == 0 or position == self._n_chunks: 85 | return b'' 86 | elif length < -1: 87 | msg = "Invalid length." 88 | raise ValueError(msg) 89 | start = position 90 | stop = self._n_bytes - 1 if length == -1 else start + length - 1 91 | stop = self._n_bytes -1 if stop >= self._n_bytes else stop 92 | blob_slices = get_blob_slices(start, stop, self._chunk_size) 93 | blob_slices = [blob_slice for blob_slice in blob_slices if blob_slice[0] <= self._n_chunks] 94 | if len(blob_slices) == 1: 95 | blob_slice = blob_slices[0] 96 | data = self._get_chunk(blob_slice) 97 | else: 98 | buffer = bytearray() 99 | for blob_slice in blob_slices: 100 | chunk = self._get_chunk(blob_slice) 101 | buffer.extend(chunk) 102 | data = bytes(buffer) 103 | return data 104 | 105 | def _get_blob_io_file(self, chunk_index): 106 | try: 107 | blob_io_file = self._blob_io_files[chunk_index] 108 | except KeyError as e: 109 | with self._dbc.cursor() as cur: 110 | sql = queries.GET_CHUNK_ID.format(model=self._model_name, 111 | offset=chunk_index) 112 | cur.execute(sql, (self._record_id,)) 113 | r = cur.fetchone() 114 | if r is None: 115 | msg = "Failed to get 'chunk_id' for record {}".format(self._record_id) 116 | raise Exception(msg) 117 | chunk_id = r[0] 118 | table_name = "jinbase_{}_data".format(self._model_name) 119 | blob_io_file = self._dbc.blobopen(table_name, "chunk", chunk_id) 120 | self._blob_io_files[chunk_index] = blob_io_file 121 | return blob_io_file 122 | 123 | def _get_chunk(self, blob_slice): 124 | chunk_index, slice_obj = blob_slice 125 | if chunk_index == self._n_chunks: 126 | return b'' 127 | elif chunk_index > self._n_chunks: 128 | msg = "BLOB index out of range for record {} (UID).".format(self._record_id) 129 | raise IndexError(msg) 130 | blob_io_file = self._get_blob_io_file(chunk_index) 131 | chunk = blob_io_file[slice_obj] 132 | return chunk 133 | 134 | def __getitem__(self, index): 135 | if isinstance(index, slice): 136 | slice_obj = index 137 | else: 138 | index = self._n_bytes + index if index < 0 else index 139 | slice_obj = slice(index, index + 1) 140 | slice_start, slice_stop, slice_step = slice_obj.indices(self._n_bytes) 141 | if slice_step != 1: 142 | msg = "The slice object should have 1 as step value." 143 | raise ValueError(msg) 144 | return self._read(slice_start, slice_stop-slice_start) 145 | 146 | def __setitem__(self, index, value): 147 | raise NotImplementedError # deliberately ! 148 | 149 | def __delitem__(self, index): 150 | raise NotImplementedError # deliberately ! 151 | 152 | 153 | def get_blob_slices(start_index, stop_index, chunk_size): 154 | blob_slices = list() 155 | chunk_index_1, sub_index_1 = divmod(start_index, chunk_size) 156 | chunk_index_2, sub_index_2 = divmod(stop_index, chunk_size) 157 | if start_index == stop_index: 158 | return ((chunk_index_1, slice(sub_index_2, sub_index_2 + 1)), ) 159 | if chunk_index_1 == chunk_index_2: 160 | return ((chunk_index_1, slice(start_index, stop_index+1)), ) 161 | blob_slices.append((chunk_index_1, slice(sub_index_1, chunk_size))) 162 | chunk_index = chunk_index_1 163 | for i in range(chunk_index_2-chunk_index_1-1): 164 | chunk_index += 1 165 | blob_slices.append((chunk_index, slice(0, chunk_size))) 166 | blob_slices.append((chunk_index+1, slice(0, sub_index_2+1))) 167 | return tuple(blob_slices) 168 | 169 | 170 | def update_position(cur_position, offset, origin, n_bytes): 171 | if origin == os.SEEK_SET: 172 | if offset < 0: 173 | msg = "Only positive offset is allowed with os.SEEK_SET." 174 | raise ValueError(msg) 175 | new_position = offset 176 | elif origin == os.SEEK_CUR: 177 | new_position = cur_position + offset 178 | elif origin == os.SEEK_END: 179 | if offset > 0: 180 | msg = "Only negative offset values are allowed with os.SEEK_END." 181 | raise ValueError(msg) 182 | new_position = n_bytes + offset 183 | else: 184 | msg = "Unsupported origin value." 185 | raise ValueError(msg) 186 | if new_position > n_bytes or new_position < 0: 187 | msg = "Offset out of range." 188 | raise ValueError(msg) 189 | return new_position 190 | -------------------------------------------------------------------------------- /src/jinbase/const/__init__.py: -------------------------------------------------------------------------------- 1 | """Project-wide constants are defined in this module.""" 2 | import os.path 3 | from enum import Enum, unique 4 | 5 | __all__ = ["Model", "TimestampPrecision", 6 | "TimeUnit", "StorageUnit", "CHUNK_SIZE", "JINBASE_HOME", 7 | "JINBASE_VERSION", "USER_HOME", "DATETIME_FORMAT", 8 | "TIMESTAMP_PRECISION", "TIMEOUT"] 9 | 10 | 11 | # models (key-value, depot, queue, and stack) 12 | @unique 13 | class Model(Enum): 14 | KV = 1 15 | DEPOT = 2 16 | QUEUE = 3 17 | STACK = 4 18 | 19 | 20 | @unique 21 | class TimestampPrecision(Enum): 22 | SECONDS = 0 23 | MILLISECONDS = 3 24 | MICROSECONDS = 6 25 | NANOSECONDS = 9 26 | 27 | 28 | @unique 29 | class StorageUnit(Enum): 30 | BYTE = "B" 31 | KIBIBYTE = "KiB" 32 | MEBIBYTE = "MiB" 33 | GIBIBYTE = "GiB" 34 | TEBIBYTE = "TiB" 35 | 36 | 37 | @unique 38 | class TimeUnit(Enum): 39 | SECOND = "sec" 40 | MINUTE = "min" 41 | HOUR = "hour" 42 | DAY = "day" 43 | WEEK = "week" 44 | 45 | 46 | # Default timestamp precision 47 | TIMESTAMP_PRECISION = TimestampPrecision.MILLISECONDS 48 | 49 | 50 | # directories 51 | USER_HOME = os.path.expanduser("~") 52 | JINBASE_HOME = os.path.join(USER_HOME, "JinbaseHome") 53 | 54 | # chunk size 55 | CHUNK_SIZE = 2**20 # 1 MiB 56 | 57 | # timeout 58 | TIMEOUT = 5.0 59 | 60 | # version 61 | JINBASE_VERSION = 1 62 | 63 | # datetime string 64 | DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S.%fZ" 65 | -------------------------------------------------------------------------------- /src/jinbase/errors/__init__.py: -------------------------------------------------------------------------------- 1 | """Exception classes are defined in this meodule.""" -------------------------------------------------------------------------------- /src/jinbase/misc/__init__.py: -------------------------------------------------------------------------------- 1 | """Misc functions""" 2 | import os 3 | import os.path 4 | import math 5 | from datetime import datetime, timezone 6 | from jinbase import const 7 | 8 | 9 | __all__ = [] 10 | 11 | 12 | def now(): 13 | return datetime.now(timezone.utc).strftime(const.DATETIME_FORMAT) 14 | 15 | 16 | def now_dt(): 17 | return datetime.now(timezone.utc) 18 | 19 | 20 | def get_timestamp(epoch_dt, dt, timestamp_precision): 21 | """returns milliseconds""" 22 | timestamp_precision = const.TimestampPrecision(timestamp_precision) 23 | if isinstance(dt, str): 24 | dt = datetime.fromisoformat(dt) 25 | target_dt = dt.astimezone(tz=timezone.utc) 26 | epoch_dt = ensure_datetime(epoch_dt) 27 | t = target_dt.timestamp() - epoch_dt.timestamp() 28 | t = 0 if t < 0 else t 29 | return int(t * (10**timestamp_precision.value)) 30 | 31 | 32 | def get_datetime(epoch_dt, timestamp, timestamp_precision): 33 | epoch_dt = ensure_datetime(epoch_dt) 34 | ts = epoch_dt.timestamp() + (timestamp / (10**timestamp_precision.value)) 35 | return datetime.fromtimestamp(ts, tz=timezone.utc) 36 | 37 | 38 | def get_datetime_str(epoch_dt, timestamp, timestamp_precision): 39 | epoch_dt = ensure_datetime(epoch_dt) 40 | ts = epoch_dt.timestamp() + (timestamp / (10**timestamp_precision.value)) 41 | return datetime.fromtimestamp(ts, tz=timezone.utc).strftime(const.DATETIME_FORMAT) 42 | 43 | 44 | def ensure_datatype(value, type_ref): 45 | value = type_ref.adapt(value) 46 | if value is None: 47 | return 48 | datatype = type_ref.check(type(value)) 49 | if datatype is None: 50 | raise TypeError 51 | return datatype 52 | 53 | 54 | def ensure_datetime(dt): 55 | if isinstance(dt, str): 56 | # datetime.fromisoformat(dt_str) is faster than datetime.strptime(dt_str, format) 57 | # https://ehmatthes.com/blog/faster_than_strptime/ 58 | # https://stackoverflow.com/questions/13468126/a-faster-strptime 59 | dt = datetime.fromisoformat(dt) 60 | return dt.astimezone(tz=timezone.utc) 61 | 62 | 63 | def split_bin(data, chunk_size): 64 | if chunk_size: 65 | for i in range(0, len(data), chunk_size): 66 | yield data[i:i+chunk_size] 67 | else: 68 | yield data 69 | 70 | 71 | def time_range_to_timestamps(epoch_dt, time_range, timestamp_precision): 72 | begin, end = time_range 73 | begin = epoch_dt if begin is None else begin 74 | end = now_dt() if end is None else end 75 | timestamp_begin = get_timestamp(epoch_dt, begin, timestamp_precision) 76 | timestamp_end = get_timestamp(epoch_dt, end, timestamp_precision) 77 | if timestamp_begin > timestamp_end: 78 | x = timestamp_begin 79 | timestamp_begin = timestamp_end 80 | timestamp_end = x 81 | return timestamp_begin, timestamp_end 82 | 83 | 84 | def get_limit_spec(limit): 85 | if limit is None: 86 | return "" 87 | return "LIMIT {}".format(int(limit)) 88 | 89 | 90 | def create_backup_filename(db_filename): 91 | current_datetime = datetime.now() 92 | dt = current_datetime.strftime("%Y-%m-%dT%H:%M:%S") 93 | basename, ext = os.path.splitext(os.path.basename(db_filename)) 94 | return "{dt}_{basename}_backup{ext}".format(dt=dt, 95 | basename=basename, 96 | ext=ext) 97 | 98 | 99 | def convert_size(size): 100 | """ Size should be in bytes. 101 | Return a tuple (float_or_int_val, StorageUnit instance) """ 102 | if size == 0: 103 | return 0, const.StorageUnit.BYTE 104 | kib = 1024 105 | units = list(const.StorageUnit) 106 | i = int(math.floor(math.log(size, kib))) 107 | p = math.pow(kib, i) 108 | result = round(size/p, 2) 109 | if result.is_integer(): 110 | result = int(result) 111 | return result, units[i] 112 | 113 | 114 | def calc_duration(dt1, dt2=None): 115 | dt1 = ensure_datetime(dt1) 116 | dt2 = now_dt() if dt2 is None else ensure_datetime(dt2) 117 | time_diff = abs(dt1 - dt2) 118 | total_seconds = time_diff.total_seconds() 119 | total_minutes = total_seconds / 60 120 | total_hours = total_minutes / 60 121 | total_days = total_hours / 24 122 | total_weeks = total_days / 7 123 | if total_weeks >= 1: 124 | result, unit = round(total_weeks, 2), const.TimeUnit.WEEK 125 | elif total_days >= 1: 126 | result, unit = round(total_days, 2), const.TimeUnit.DAY 127 | elif total_hours >= 1: 128 | result, unit = round(total_hours, 2), const.TimeUnit.HOUR 129 | elif total_minutes >= 1: 130 | result, unit = round(total_minutes, 2), const.TimeUnit.MINUTE 131 | else: 132 | result, unit = round(total_seconds, 2), const.TimeUnit.SECOND 133 | if result.is_integer(): 134 | result = int(result) 135 | return result, unit 136 | -------------------------------------------------------------------------------- /src/jinbase/queries/__init__.py: -------------------------------------------------------------------------------- 1 | """All SQL queries are defined in this module.""" 2 | 3 | 4 | __all__ = [] 5 | 6 | 7 | # Init script 8 | INIT_SCRIPT = """ 9 | 10 | -- Create the JINBASE_INFO table 11 | CREATE TABLE IF NOT EXISTS jinbase_info ( 12 | id INTEGER NOT NULL UNIQUE DEFAULT 0, 13 | version INTEGER NOT NULL, 14 | created_at TEXT NOT NULL, 15 | chunk_size INTEGER NOT NULL, 16 | timestamp_precision INTEGER NOT NULL, 17 | CONSTRAINT chk_id 18 | CHECK (id == 0)); 19 | 20 | 21 | -- Create the JINBASE_KV_RECORD table 22 | CREATE TABLE IF NOT EXISTS jinbase_kv_record ( 23 | id INTEGER PRIMARY KEY AUTOINCREMENT, 24 | datatype INTEGER NOT NULL, 25 | timestamp INTEGER NOT NULL, 26 | int_key INTEGER UNIQUE, 27 | str_key TEXT UNIQUE, 28 | CONSTRAINT chk_key 29 | CHECK ((int_key IS NULL AND str_key IS NOT NULL) 30 | OR 31 | (int_key IS NOT NULL AND str_key IS NULL))); 32 | 33 | -- Create index for JINBASE_KV_RECORD's timestamp 34 | CREATE INDEX IF NOT EXISTS idx_jinbase_kv_record_timestamp 35 | ON jinbase_kv_record (timestamp); 36 | 37 | -- Create the JINBASE_KV_DATA table 38 | CREATE TABLE IF NOT EXISTS jinbase_kv_data ( 39 | id INTEGER PRIMARY KEY AUTOINCREMENT, 40 | record_id INTEGER NOT NULL, 41 | chunk BLOB NOT NULL, 42 | CONSTRAINT fk_jinbase_kv_data_record_id 43 | FOREIGN KEY (record_id) 44 | REFERENCES jinbase_kv_record(id) 45 | ON DELETE CASCADE); 46 | 47 | -- Create index for JINBASE_KV_DATA's record_id 48 | CREATE INDEX IF NOT EXISTS idx_jinbase_kv_data_record_id 49 | ON jinbase_kv_data (record_id); 50 | 51 | -- Create the JINBASE_KV_POINTER table 52 | CREATE TABLE IF NOT EXISTS jinbase_kv_pointer ( 53 | field TEXT NOT NULL, 54 | record_id INTEGER NOT NULL, 55 | slice_start INTEGER NOT NULL, 56 | slice_stop INTEGER NOT NULL, 57 | PRIMARY KEY (field, record_id), 58 | CONSTRAINT fk_jinbase_kv_pointer_record_id 59 | FOREIGN KEY (record_id) 60 | REFERENCES jinbase_kv_record(id) 61 | ON DELETE CASCADE); 62 | 63 | -- Create index for JINBASE_KV_POINTER's record_id 64 | CREATE INDEX IF NOT EXISTS idx_jinbase_kv_pointer_record_id 65 | ON jinbase_kv_pointer (record_id); 66 | 67 | 68 | -- Create the JINBASE_DEPOT_RECORD table 69 | CREATE TABLE IF NOT EXISTS jinbase_depot_record ( 70 | id INTEGER PRIMARY KEY AUTOINCREMENT, 71 | datatype INTEGER NOT NULL, 72 | timestamp INTEGER NOT NULL); 73 | 74 | -- Create index for JINBASE_DEPOT_RECORD's timestamp 75 | CREATE INDEX IF NOT EXISTS idx_jinbase_depot_record_timestamp 76 | ON jinbase_depot_record (timestamp); 77 | 78 | -- Create the JINBASE_DEPOT_DATA table 79 | CREATE TABLE IF NOT EXISTS jinbase_depot_data ( 80 | id INTEGER PRIMARY KEY AUTOINCREMENT, 81 | record_id INTEGER NOT NULL, 82 | chunk BLOB NOT NULL, 83 | CONSTRAINT fk_jinbase_depot_data_record_id 84 | FOREIGN KEY (record_id) 85 | REFERENCES jinbase_depot_record(id) 86 | ON DELETE CASCADE); 87 | 88 | -- Create index for JINBASE_DEPOT_DATA's record_id 89 | CREATE INDEX IF NOT EXISTS idx_jinbase_depot_data_record_id 90 | ON jinbase_depot_data (record_id); 91 | 92 | -- Create the JINBASE_DEPOT_POINTER table 93 | CREATE TABLE IF NOT EXISTS jinbase_depot_pointer ( 94 | field TEXT NOT NULL, 95 | record_id INTEGER NOT NULL, 96 | slice_start INTEGER NOT NULL, 97 | slice_stop INTEGER NOT NULL, 98 | PRIMARY KEY (field, record_id), 99 | CONSTRAINT fk_jinbase_depot_pointer_record_id 100 | FOREIGN KEY (record_id) 101 | REFERENCES jinbase_depot_record(id) 102 | ON DELETE CASCADE); 103 | 104 | -- Create index for JINBASE_DEPOT_POINTER's record_id 105 | CREATE INDEX IF NOT EXISTS idx_jinbase_depot_pointer_record_id 106 | ON jinbase_depot_pointer (record_id); 107 | 108 | 109 | -- Create the JINBASE_QUEUE_RECORD table 110 | CREATE TABLE IF NOT EXISTS jinbase_queue_record ( 111 | id INTEGER PRIMARY KEY AUTOINCREMENT, 112 | datatype INTEGER NOT NULL, 113 | timestamp INTEGER NOT NULL); 114 | 115 | -- Create index for JINBASE_QUEUE_RECORD's timestamp 116 | CREATE INDEX IF NOT EXISTS idx_jinbase_queue_record_timestamp 117 | ON jinbase_queue_record (timestamp); 118 | 119 | -- Create the JINBASE_QUEUE_DATA table 120 | CREATE TABLE IF NOT EXISTS jinbase_queue_data ( 121 | id INTEGER PRIMARY KEY AUTOINCREMENT, 122 | record_id INTEGER NOT NULL, 123 | chunk BLOB NOT NULL, 124 | CONSTRAINT fk_jinbase_queue_data_record_id 125 | FOREIGN KEY (record_id) 126 | REFERENCES jinbase_queue_record(id) 127 | ON DELETE CASCADE); 128 | 129 | -- Create index for JINBASE_QUEUE_DATA's record_id 130 | CREATE INDEX IF NOT EXISTS idx_jinbase_queue_data_record_id 131 | ON jinbase_queue_data (record_id); 132 | 133 | 134 | -- Create the JINBASE_STACK_RECORD table 135 | CREATE TABLE IF NOT EXISTS jinbase_stack_record ( 136 | id INTEGER PRIMARY KEY AUTOINCREMENT, 137 | datatype INTEGER NOT NULL, 138 | timestamp INTEGER NOT NULL); 139 | 140 | -- Create index for JINBASE_STACK_RECORD's timestamp 141 | CREATE INDEX IF NOT EXISTS idx_jinbase_stack_record_timestamp 142 | ON jinbase_stack_record (timestamp); 143 | 144 | -- Create the JINBASE_STACK_DATA table 145 | CREATE TABLE IF NOT EXISTS jinbase_stack_data ( 146 | id INTEGER PRIMARY KEY AUTOINCREMENT, 147 | record_id INTEGER NOT NULL, 148 | chunk BLOB NOT NULL, 149 | CONSTRAINT fk_jinbase_stack_data_record_id 150 | FOREIGN KEY (record_id) 151 | REFERENCES jinbase_stack_record(id) 152 | ON DELETE CASCADE); 153 | 154 | -- Create index for JINBASE_STACK_DATA's record_id 155 | CREATE INDEX IF NOT EXISTS idx_jinbase_stack_data_record_id 156 | ON jinbase_stack_data (record_id); 157 | """ 158 | 159 | 160 | # PRAGMA to run at connection creation 161 | CONNECTION_DIRECTIVES = """ 162 | PRAGMA foreign_keys=ON; 163 | PRAGMA synchronous=NORMAL; 164 | """ 165 | 166 | 167 | # Jinbase info 168 | GET_JINBASE_INFO = """ 169 | SELECT version, created_at, chunk_size, timestamp_precision FROM jinbase_info 170 | """ 171 | SET_JINBASE_INFO = """ 172 | INSERT INTO jinbase_info (version, created_at, chunk_size, timestamp_precision) 173 | VALUES (?, ?, ?, ?) 174 | """ 175 | 176 | 177 | # Record management 178 | LATEST_WRITE = """ 179 | SELECT timestamp FROM jinbase_{model}_record ORDER BY timestamp DESC LIMIT 1 180 | """ 181 | COUNT_RECORDS = """ 182 | SELECT COUNT(*) AS n FROM jinbase_{model}_record 183 | """ 184 | RETRIEVE_RECORDS = """ 185 | SELECT id FROM jinbase_{model}_record WHERE ORDER BY id 186 | """ 187 | DELETE_RECORD = """ 188 | DELETE FROM jinbase_{model}_record WHERE id=? 189 | """ 190 | DELETE_RECORDS = """ 191 | DELETE FROM jinbase_{model}_record 192 | """ 193 | 194 | 195 | # Data management 196 | GET_CHUNK_ID = """ 197 | SELECT id FROM jinbase_{model}_data WHERE record_id = ? 198 | ORDER BY id LIMIT 1 OFFSET {offset} 199 | """ 200 | STORE_DATA = """ 201 | INSERT INTO jinbase_{model}_data (record_id, chunk) VALUES (?, ?) 202 | """ 203 | RETRIEVE_DATA = """ 204 | SELECT chunk FROM jinbase_{model}_data WHERE record_id=? ORDER BY id 205 | """ 206 | COUNT_STORE_CHUNKS = """SELECT COUNT(*) AS n FROM jinbase_{model}_data 207 | """ 208 | COUNT_STORE_BYTES = """ 209 | SELECT SUM(LENGTH(chunk)) AS n FROM jinbase_{model}_data 210 | """ 211 | COUNT_RECORD_BYTES = """ 212 | SELECT SUM(LENGTH(chunk)) AS n FROM jinbase_{model}_data WHERE record_id = ? 213 | """ 214 | COUNT_RECORD_CHUNKS = """ 215 | SELECT COUNT(*) AS n FROM jinbase_{model}_data WHERE record_id = ? 216 | """ 217 | 218 | # Pointer management 219 | ADD_POINTER = """ 220 | INSERT INTO jinbase_{model}_pointer (field, record_id, slice_start, slice_stop) 221 | VALUES (?, ?, ?, ?) 222 | """ 223 | GET_POINTER = """ 224 | SELECT slice_start, slice_stop FROM jinbase_{model}_pointer WHERE field = ? AND record_id = ? 225 | """ 226 | GET_POINTED_FIELDS = """ 227 | SELECT field FROM jinbase_{model}_pointer ORDER BY field 228 | """ 229 | 230 | 231 | # Key-value store 232 | COUNT_KEY_OCCURRENCE = """ 233 | SELECT COUNT(*) AS n FROM jinbase_kv_record WHERE {key_type}_key=? 234 | """ 235 | SET_KV_RECORD = """ 236 | INSERT INTO jinbase_kv_record (datatype, timestamp, {key_type}_key) 237 | VALUES (?, ?, ?) 238 | """ 239 | GET_KV_RECORD_BY_KEY = """ 240 | SELECT id, datatype, timestamp FROM jinbase_kv_record WHERE {key_type}_key=? 241 | """ 242 | GET_KV_KEY_BY_UID = """ 243 | SELECT 244 | CASE 245 | WHEN int_key IS NOT NULL THEN int_key 246 | ELSE str_key 247 | END AS key 248 | FROM jinbase_kv_record WHERE id=? 249 | """ 250 | SELECT_KEYS = """ 251 | SELECT 252 | CASE 253 | WHEN int_key IS NOT NULL THEN int_key 254 | ELSE str_key 255 | END AS key 256 | FROM jinbase_kv_record {criteria} ORDER BY key {sort_order} {limit} 257 | """ 258 | SELECT_INT_KEYS = """ 259 | SELECT int_key as key 260 | FROM jinbase_kv_record 261 | WHERE int_key IS NOT NULL {criteria} 262 | ORDER BY key {sort_order} {limit} 263 | """ 264 | SELECT_STR_KEYS = """ 265 | SELECT str_key as key 266 | FROM jinbase_kv_record 267 | WHERE str_key IS NOT NULL {criteria} 268 | ORDER BY key {sort_order} {limit} 269 | """ 270 | SELECT_STR_KEYS_WITH_GLOB = """ 271 | SELECT str_key as key 272 | FROM jinbase_kv_record 273 | WHERE str_key IS NOT NULL AND str_key GLOB ? {criteria} 274 | ORDER BY key {sort_order} {limit} 275 | """ 276 | KV_CRITERIA_1 = "int_key >= {val}" 277 | KV_CRITERIA_2 = "int_key <= {val}" 278 | KV_CRITERIA_3 = "int_key BETWEEN {first} AND {last}" 279 | KV_CRITERIA_4 = "timestamp BETWEEN {start} AND {stop}" 280 | 281 | 282 | # Depot store 283 | GET_DEPOT_RECORD = """ 284 | SELECT datatype, timestamp 285 | FROM jinbase_depot_record WHERE id = ? 286 | """ 287 | GET_DEPOT_RECORD_BY_POSITION = """ 288 | SELECT id, datatype, timestamp 289 | FROM jinbase_depot_record ORDER BY id LIMIT 1 OFFSET {offset} 290 | """ 291 | APPEND_TO_DEPOT = """ 292 | INSERT INTO jinbase_depot_record (datatype, timestamp) VALUES (?, ?) 293 | """ 294 | GET_DEPOT_RECORDS_BETWEEN_TIMESTAMPS = """ 295 | SELECT id FROM jinbase_depot_record WHERE timestamp BETWEEN ? AND ? 296 | ORDER BY id {sort_order} {limit} 297 | """ 298 | COUNT_DEPOT_RECORD_OFFSET = """ 299 | SELECT COUNT(*) AS n FROM jinbase_depot_record WHERE id <= ? 300 | ORDER BY id 301 | """ 302 | 303 | 304 | 305 | # Queue store 306 | GET_QUEUE_FRONT = """ 307 | SELECT id, datatype, timestamp 308 | FROM jinbase_queue_record ORDER BY id LIMIT 1 309 | """ 310 | GET_QUEUE_FRONT_UID = """ 311 | SELECT id FROM jinbase_queue_record ORDER BY id LIMIT 1 312 | """ 313 | GET_QUEUE_BACK = """ 314 | SELECT id, datatype, timestamp 315 | FROM jinbase_queue_record ORDER BY id DESC LIMIT 1 316 | """ 317 | GET_QUEUE_BACK_UID = """ 318 | SELECT id FROM jinbase_queue_record ORDER BY id DESC LIMIT 1 319 | """ 320 | ENQUEUE = """ 321 | INSERT INTO jinbase_queue_record (datatype, timestamp) VALUES (?, ?) 322 | """ 323 | 324 | 325 | # Stack store 326 | STACK_PUSH = """ 327 | INSERT INTO jinbase_stack_record (datatype, timestamp) VALUES (?, ?) 328 | """ 329 | GET_STACK_TOP = """ 330 | SELECT id, datatype, timestamp FROM jinbase_stack_record ORDER BY id DESC LIMIT 1 331 | """ 332 | GET_STACK_TOP_UID = """ 333 | SELECT id FROM jinbase_stack_record ORDER BY id DESC LIMIT 1 334 | """ 335 | -------------------------------------------------------------------------------- /src/jinbase/store/__init__.py: -------------------------------------------------------------------------------- 1 | """The abstract Store class is defined in this module.""" 2 | from abc import ABC 3 | from collections import namedtuple 4 | from paradict import Unpacker, Packer, Datatype 5 | from litedbc import TransactionMode 6 | from jinbase import misc 7 | from jinbase import queries 8 | from jinbase.const import Model 9 | 10 | 11 | __all__ = ["Store", "RecordInfo"] 12 | 13 | 14 | RecordInfo = namedtuple("RecordInfo", 15 | ("uid", "datatype", "created_at")) 16 | RecordInfo.__doc__ = """\ 17 | Named tuple returned by store.info() 18 | 19 | [params] 20 | uid: The record id 21 | datatype: An instance of `paradict.Datatype` 22 | created_at: Datetime string representing the creation datetime of the record 23 | """ 24 | 25 | 26 | class Store(ABC): 27 | """Abstract Store class intended to be subclassed by the 28 | Kv, Depot, Queue, and Stack stores""" 29 | def __init__(self, model, jinbase): 30 | """Init. 31 | 32 | [params] 33 | - model: A Model namedtuple instance 34 | - jinbase: Jinbase instance 35 | """ 36 | self._model = Model(model) 37 | self._model_name = self._model.name.lower() 38 | self._jinbase = jinbase 39 | self._db_epoch = jinbase.created_at 40 | self._timestamp_precision = jinbase.timestamp_precision 41 | self._dbc = jinbase.dbc 42 | self._type_ref = jinbase.type_ref 43 | self._chunk_size = jinbase.chunk_size 44 | 45 | @property 46 | def model(self): 47 | return self._model 48 | 49 | @property 50 | def jinbase(self): 51 | return self._jinbase 52 | 53 | @property 54 | def filename(self): 55 | return self._dbc.filename 56 | 57 | @property 58 | def is_readonly(self): 59 | return self._dbc.is_readonly 60 | 61 | @property 62 | def timeout(self): 63 | return self._dbc.timeout 64 | 65 | @property 66 | def type_ref(self): 67 | return self._jinbase.type_ref 68 | 69 | @property 70 | def chunk_size(self): 71 | return self._jinbase.chunk_size 72 | 73 | @property 74 | def dbc(self): 75 | return self._dbc 76 | 77 | @property 78 | def is_new(self): 79 | return self._dbc.is_new 80 | 81 | @property 82 | def in_memory(self): 83 | return self._dbc.in_memory 84 | 85 | @property 86 | def is_closed(self): 87 | return self._dbc.is_closed 88 | 89 | def transaction(self, transaction_mode=TransactionMode.DEFERRED): 90 | """ 91 | Context manager for executing a transaction. 92 | 93 | [params] 94 | - transaction: Instance of `litedbc.TransactionMode` 95 | """ 96 | return self._dbc.transaction(transaction_mode=transaction_mode) 97 | 98 | def read_transaction(self): 99 | """ 100 | Context manager for executing a Read transaction. 101 | 102 | [yield] 103 | Yields a `litedbc.Cursor` object 104 | """ 105 | return self._dbc.transaction(transaction_mode=TransactionMode.DEFERRED) 106 | 107 | def write_transaction(self): 108 | """ 109 | Context manager for executing a Write transaction. 110 | 111 | [yield] 112 | Yields a `litedbc.Cursor` object 113 | """ 114 | return self._dbc.transaction(transaction_mode=TransactionMode.IMMEDIATE) 115 | 116 | def count_records(self): 117 | """ 118 | Count all records in the store. 119 | 120 | [return] 121 | Returns the number of records 122 | """ 123 | with self._dbc.cursor() as cur: 124 | sql = queries.COUNT_RECORDS.format(model=self._model_name) 125 | cur.execute(sql) # read 126 | r = cur.fetchone()[0] 127 | return r if r else 0 128 | 129 | def count_bytes(self): 130 | """ 131 | Count all data bytes in the store. 132 | 133 | [return] 134 | Returns the count of data bytes""" 135 | with self._dbc.cursor() as cur: 136 | sql = queries.COUNT_STORE_BYTES.format(model=self._model_name) 137 | cur.execute(sql) # read 138 | r = cur.fetchone()[0] 139 | return r if r else 0 140 | 141 | def count_chunks(self): 142 | """ 143 | Count all data chunks in the store. 144 | 145 | [return] 146 | Returns the number of chunks""" 147 | with self._dbc.cursor() as cur: 148 | sql = queries.COUNT_STORE_CHUNKS.format(model=self._model_name) 149 | cur.execute(sql) # read 150 | r = cur.fetchone()[0] 151 | return r if r else 0 152 | 153 | def is_empty(self): 154 | """ 155 | Tells whether the store is empty or not 156 | 157 | [return] 158 | Return a boolean. 159 | """ 160 | return True if self.count_records() == 0 else False 161 | 162 | @staticmethod 163 | def now(): 164 | """ 165 | Get the current datetime. 166 | 167 | [return] 168 | Return a datetime string. 169 | """ 170 | return misc.now() 171 | 172 | @staticmethod 173 | def now_dt(): 174 | """ 175 | Get the current datetime. 176 | 177 | [return] 178 | Return a datetime object. 179 | """ 180 | return misc.now_dt() 181 | 182 | def latest(self): 183 | """ 184 | Retrieve the datetime of the latest write operation. 185 | 186 | [return] 187 | Return a datetime string 188 | """ 189 | with self._dbc.cursor() as cur: 190 | sql = queries.LATEST_WRITE.format(model=self._model_name) 191 | cur.execute(sql) # read 192 | r = cur.fetchone() 193 | if r is None: 194 | return 195 | db_timestamp = r[0] 196 | return misc.get_datetime_str(self._db_epoch, db_timestamp, 197 | self._timestamp_precision) 198 | 199 | def delete_all(self): 200 | """Delete all records in the store""" 201 | with self._dbc.cursor() as cur: 202 | sql = queries.DELETE_RECORDS.format(model=self._model_name) 203 | cur.execute(sql) # write 204 | 205 | def _store_data(self, record_id, datatype, value): 206 | with self._dbc.cursor() as cur: 207 | sql = queries.STORE_DATA.format(model=self._model_name) 208 | if datatype == Datatype.BIN: 209 | for chunk in misc.split_bin(value, chunk_size=self._chunk_size): 210 | cur.execute(sql, (record_id, chunk)) 211 | else: 212 | buffer = bytearray() 213 | packer = Packer(type_ref=self._type_ref, auto_index=True) 214 | for x in packer.pack(value): 215 | buffer.extend(x) 216 | while len(buffer) >= self._chunk_size: 217 | chunk = buffer[:self._chunk_size] 218 | del buffer[:self._chunk_size] 219 | cur.execute(sql, (record_id, chunk)) 220 | if buffer: 221 | cur.execute(sql, (record_id, buffer)) 222 | # create pointers 223 | if datatype == Datatype.DICT and self._model in (Model.KV, 224 | Model.DEPOT): 225 | sql = queries.ADD_POINTER.format(model=self._model_name) 226 | for field, slice_obj in packer.index_dict.items(): 227 | if isinstance(field, str): 228 | cur.execute(sql, (field, 229 | record_id, 230 | slice_obj.start, 231 | slice_obj.stop)) 232 | 233 | def _retrieve_data(self, record_id, datatype): 234 | with self._dbc.cursor() as cur: 235 | is_serialized = False if datatype == Datatype.BIN else True 236 | sql = queries.RETRIEVE_DATA.format(model=self._model_name) 237 | chunks = bytearray() 238 | unpacker = Unpacker(type_ref=self._type_ref) 239 | cur.execute(sql, (record_id, )) 240 | for row in cur.fetch(): 241 | chunk = row[0] 242 | if is_serialized: 243 | unpacker.feed(chunk) 244 | else: 245 | chunks.extend(chunk) 246 | if is_serialized: 247 | return unpacker.data 248 | else: 249 | return self._type_ref.bin_type(chunks) 250 | 251 | def _delete_record(self, record_id): 252 | with self._dbc.cursor() as cur: 253 | sql = queries.DELETE_RECORD.format(model=self._model_name) 254 | cur.execute(sql, (record_id, )) 255 | return cur.rowcount 256 | -------------------------------------------------------------------------------- /src/jinbase/store/depot.py: -------------------------------------------------------------------------------- 1 | """The Depot store is defined in this module.""" 2 | from contextlib import contextmanager 3 | from paradict import Datatype, unpack 4 | from jinbase import queries, misc 5 | from jinbase.const import Model 6 | from jinbase.store import Store, RecordInfo 7 | from jinbase.blob import Blob 8 | 9 | 10 | __all__ = ["Depot"] 11 | 12 | 13 | class Depot(Store): 14 | """ 15 | This class represents the Depot store. 16 | Note that a Depot object isn't intended to be directly 17 | instantiated by the user. 18 | """ 19 | def __init__(self, jinbase): 20 | """ 21 | Init 22 | 23 | [params] 24 | - jinbase: Jinbase object 25 | """ 26 | super().__init__(Model.DEPOT, jinbase) 27 | 28 | def exists(self, uid): 29 | r = self._get_record(uid) 30 | if r is None: # nonexistent 31 | return False 32 | return True 33 | 34 | def info(self, uid): 35 | # returns a paradict.Datatype instance + creation datetime 36 | r = self._get_record(uid) 37 | if r is None: # nonexistent 38 | return 39 | datatype, db_timestamp = r 40 | created_at = misc.get_datetime_str(self._db_epoch, db_timestamp, 41 | self._timestamp_precision) 42 | return RecordInfo(uid=uid, datatype=datatype, created_at=created_at) 43 | 44 | def get(self, uid, default=None): 45 | with self._dbc.transaction(): 46 | r = self._get_record(uid) # read 47 | if r is None: # nonexistent 48 | return default 49 | datatype, _ = r 50 | return self._retrieve_data(uid, datatype) # read 51 | 52 | def get_first(self, default=None): 53 | with self._dbc.transaction() as cursor: 54 | uid = self.uid(0) 55 | if uid is None: 56 | return default 57 | return self.get(uid, default=default) 58 | 59 | def get_last(self, default=None): 60 | with self._dbc.transaction() as cursor: 61 | uid = self.uid(-1) 62 | if uid is None: 63 | return default 64 | return self.get(uid, default=default) 65 | 66 | def append(self, value): 67 | if value is None: 68 | return 69 | with self._dbc.immediate_transaction() as cursor: 70 | value = self._type_ref.adapt(value) 71 | datatype = misc.ensure_datatype(value, self._type_ref) 72 | if datatype is None: 73 | raise TypeError 74 | sql = queries.APPEND_TO_DEPOT 75 | db_timestamp = misc.get_timestamp(self._db_epoch, misc.now_dt(), 76 | self._timestamp_precision) 77 | cursor.execute(sql, (datatype.value, db_timestamp)) # write 78 | record_id = cursor.lastrowid 79 | self._store_data(record_id, datatype, value) # write 80 | return record_id 81 | 82 | def extend(self, values): 83 | with self._dbc.immediate_transaction() as cursor: 84 | uids = list() 85 | for value in values: 86 | uid = self.append(value) #writeS 87 | uids.append(uid) 88 | return tuple(uids) 89 | 90 | def uid(self, position): 91 | with self._dbc.transaction() as cursor: 92 | try: 93 | position = _ensure_position(self, position) # possible read 94 | except IndexError as e: 95 | return 96 | r = self._get_record_by_position(position) # read 97 | if r is None: 98 | return 99 | record_id, _, _ = r 100 | return record_id 101 | 102 | def position(self, uid): 103 | with self._dbc.transaction() as cursor: 104 | if not self.exists(uid): 105 | return 106 | sql = queries.COUNT_DEPOT_RECORD_OFFSET 107 | cursor.execute(sql, (uid,)) 108 | r = cursor.fetchone()[0] 109 | return r - 1 110 | 111 | def uids(self, *, time_range=None, limit=None, asc=True): 112 | with self._dbc.cursor() as cur: 113 | if time_range is None: 114 | start, stop = 0, misc.get_timestamp(self._db_epoch, misc.now_dt(), 115 | self._timestamp_precision) 116 | else: 117 | timestamps = misc.time_range_to_timestamps(self._db_epoch, time_range, 118 | self._timestamp_precision) 119 | start, stop = timestamps 120 | # retrieve uids 121 | sort_order = "ASC" if asc else "DESC" 122 | limit = misc.get_limit_spec(limit) 123 | sql = queries.GET_DEPOT_RECORDS_BETWEEN_TIMESTAMPS.format(sort_order=sort_order, 124 | limit=limit) 125 | cur.execute(sql, (start, stop)) 126 | for row in cur.fetch(): 127 | uid = row[0] 128 | yield uid 129 | 130 | def iterate(self, *, time_range=None, limit=None, asc=True): 131 | for uid in self.uids(time_range=time_range, limit=limit, asc=asc): 132 | yield uid, self.get(uid) 133 | 134 | def count_bytes(self, uid=None): 135 | if uid is None: 136 | return super().count_bytes() 137 | with self._dbc.transaction() as cur: 138 | r = self._get_record(uid) # read 139 | if r is None: 140 | return 0 141 | sql = queries.COUNT_RECORD_BYTES.format(model=self._model_name) 142 | cur.execute(sql, (uid,)) # read 143 | r = cur.fetchone()[0] 144 | return r if r else 0 145 | 146 | def count_chunks(self, uid=None): 147 | if uid is None: 148 | return super().count_chunks() 149 | with self._dbc.transaction() as cur: 150 | r = self._get_record(uid) # read 151 | if r is None: 152 | return 0 153 | sql = queries.COUNT_RECORD_CHUNKS.format(model=self._model_name) 154 | cur.execute(sql, (uid,)) # read 155 | r = cur.fetchone()[0] 156 | return r if r else 0 157 | 158 | @contextmanager 159 | def open_blob(self, uid): 160 | with self._dbc.transaction() as cursor: 161 | n_chunks = self.count_chunks(uid) 162 | n_bytes = self.count_bytes(uid) 163 | blob = Blob(self, uid, n_bytes, n_chunks) 164 | try: 165 | yield blob 166 | finally: 167 | blob.close() 168 | 169 | def load_field(self, uid, field, default=None): 170 | with self._dbc.transaction() as cur: 171 | sql = queries.GET_POINTER.format(model=self._model_name) 172 | cur.execute(sql, (field, uid)) # read 173 | r = cur.fetchone() 174 | if r is None: 175 | return default 176 | slice_obj = slice(*r) 177 | with self.open_blob(uid) as blob: 178 | data = blob[slice_obj] 179 | return unpack(data) 180 | 181 | def fields(self): 182 | with self._dbc.transaction() as cur: 183 | sql = queries.GET_POINTED_FIELDS.format(model=self._model_name) 184 | cur.execute(sql) # read 185 | for r in cur.fetch(): 186 | yield r[0] 187 | 188 | def delete(self, uid): 189 | with self._dbc.immediate_transaction() as cursor: 190 | n = self._delete_record(uid) # write 191 | return True if n > 0 else False 192 | 193 | def delete_many(self, uids): 194 | with self._dbc.immediate_transaction() as cursor: 195 | deleted_uids = list() 196 | for uid in uids: 197 | if self.delete(uid): 198 | deleted_uids.append(uid) 199 | return tuple(deleted_uids) 200 | 201 | def _get_record(self, uid): 202 | with self._dbc.cursor() as cur: 203 | sql = queries.GET_DEPOT_RECORD 204 | cur.execute(sql, (uid,)) 205 | r = cur.fetchone() 206 | if r is None: # nonexistent 207 | return 208 | dtype, db_timestamp = r 209 | return Datatype(dtype), db_timestamp 210 | 211 | def _get_record_by_position(self, position): 212 | with self._dbc.cursor() as cur: 213 | sql = queries.GET_DEPOT_RECORD_BY_POSITION.format(offset=position) 214 | cur.execute(sql) 215 | r = cur.fetchone() 216 | if r is None: # nonexistent 217 | return 218 | record_id, dtype, db_timestamp = r 219 | return record_id, Datatype(dtype), db_timestamp 220 | 221 | 222 | def _ensure_position(store, position): 223 | position = int(position) 224 | if position >= 0: 225 | return position 226 | n = store.count_records() 227 | abs_position = abs(position) 228 | if abs_position > n: 229 | raise IndexError 230 | return n - abs_position 231 | -------------------------------------------------------------------------------- /src/jinbase/store/queue.py: -------------------------------------------------------------------------------- 1 | """The Queue store is defined in this module.""" 2 | from paradict import Datatype 3 | from jinbase import queries, misc 4 | from jinbase.const import Model 5 | from jinbase.store import Store, RecordInfo 6 | 7 | 8 | __all__ = ["Queue"] 9 | 10 | 11 | class Queue(Store): 12 | """ 13 | This class represents the Queue store. 14 | Note that a Queue object isn't intended to be directly 15 | instantiated by the user. 16 | """ 17 | def __init__(self, jinbase): 18 | """ 19 | Init 20 | 21 | [params] 22 | - jinbase: Jinbase object 23 | """ 24 | super().__init__(Model.QUEUE, jinbase) 25 | 26 | def enqueue(self, value): 27 | if value is None: 28 | return 29 | with self._dbc.immediate_transaction() as cursor: 30 | value = self._type_ref.adapt(value) 31 | datatype = misc.ensure_datatype(value, self._type_ref) 32 | if datatype is None: 33 | raise TypeError 34 | sql = queries.ENQUEUE 35 | db_timestamp = misc.get_timestamp(self._db_epoch, misc.now_dt(), 36 | self._timestamp_precision) 37 | cursor.execute(sql, (datatype.value, db_timestamp)) # write 38 | record_id = cursor.lastrowid 39 | self._store_data(record_id, datatype, value) # write 40 | return record_id 41 | 42 | def enqueue_many(self, values): 43 | with self._dbc.immediate_transaction() as cursor: 44 | uids = list() 45 | for value in values: 46 | uid = self.enqueue(value) 47 | uids.append(uid) 48 | return tuple(uids) 49 | 50 | def dequeue(self, default=None): 51 | with self._dbc.immediate_transaction() as cursor: 52 | r = self._get_front() # read 53 | if r is None: # nonexistent 54 | return default 55 | record_id, datatype, _ = r 56 | # get value 57 | value = self._retrieve_data(record_id, datatype) # read 58 | # delete record 59 | self._delete_record(record_id) 60 | return value 61 | 62 | def peek_front(self, default=None): 63 | with self._dbc.transaction(): 64 | r = self._get_front() # read 65 | if r is None: 66 | return default 67 | record_id, datatype, _ = r 68 | return self._retrieve_data(record_id, datatype) # read 69 | 70 | def peek_back(self, default=None): 71 | with self._dbc.transaction(): 72 | r = self._get_back() # read 73 | if r is None: 74 | return default 75 | record_id, datatype, _ = r 76 | return self._retrieve_data(record_id, datatype) # read 77 | 78 | def count_front_bytes(self): 79 | with self._dbc.transaction() as cur: 80 | r = self._get_front() # read 81 | if r is None: 82 | return 0 83 | record_id, _, _ = r 84 | sql = queries.COUNT_RECORD_BYTES.format(model=self._model_name) 85 | cur.execute(sql, (record_id,)) # read 86 | r = cur.fetchone()[0] 87 | return r if r else 0 88 | 89 | def count_back_bytes(self): 90 | with self._dbc.transaction() as cur: 91 | r = self._get_back() # read 92 | if r is None: 93 | return 0 94 | record_id, _, _ = r 95 | sql = queries.COUNT_RECORD_BYTES.format(model=self._model_name) 96 | cur.execute(sql, (record_id,)) # read 97 | r = cur.fetchone()[0] 98 | return r if r else 0 99 | 100 | def count_front_chunks(self): 101 | with self._dbc.transaction() as cur: 102 | r = self._get_front() # read 103 | if r is None: 104 | return 0 105 | record_id, _, _ = r 106 | sql = queries.COUNT_RECORD_CHUNKS.format(model=self._model_name) 107 | cur.execute(sql, (record_id,)) # read 108 | r = cur.fetchone()[0] 109 | return r if r else 0 110 | 111 | def count_back_chunks(self): 112 | with self._dbc.transaction() as cur: 113 | r = self._get_back() # read 114 | if r is None: 115 | return 0 116 | record_id, _, _ = r 117 | sql = queries.COUNT_RECORD_CHUNKS.format(model=self._model_name) 118 | cur.execute(sql, (record_id,)) # read 119 | r = cur.fetchone()[0] 120 | return r if r else 0 121 | 122 | def front_uid(self): 123 | with self._dbc.cursor() as cur: 124 | sql = queries.GET_QUEUE_FRONT_UID 125 | cur.execute(sql) 126 | r = cur.fetchone() 127 | if r is None: 128 | return 129 | return r[0] 130 | 131 | def back_uid(self): 132 | with self._dbc.cursor() as cur: 133 | sql = queries.GET_QUEUE_BACK_UID 134 | cur.execute(sql) 135 | r = cur.fetchone() 136 | if r is None: 137 | return 138 | return r[0] 139 | 140 | def info_front(self): 141 | r = self._get_front() # read 142 | if r is None: 143 | return 144 | record_id, datatype, db_timestamp = r 145 | created_at = misc.get_datetime_str(self._db_epoch, db_timestamp, 146 | self._timestamp_precision) 147 | return RecordInfo(uid=record_id, datatype=datatype, created_at=created_at) 148 | 149 | def info_back(self): 150 | r = self._get_back() # read 151 | if r is None: 152 | return 153 | record_id, datatype, db_timestamp = r 154 | created_at = misc.get_datetime_str(self._db_epoch, db_timestamp, 155 | self._timestamp_precision) 156 | return RecordInfo(uid=record_id, datatype=datatype, created_at=created_at) 157 | 158 | def _get_front(self): 159 | with self._dbc.cursor() as cur: 160 | sql = queries.GET_QUEUE_FRONT 161 | cur.execute(sql) 162 | r = cur.fetchone() 163 | if r is None: 164 | return 165 | record_id, dtype, db_timestamp = r 166 | return record_id, Datatype(dtype), db_timestamp 167 | 168 | def _get_back(self): 169 | with self._dbc.cursor() as cur: 170 | sql = queries.GET_QUEUE_BACK 171 | cur.execute(sql) 172 | r = cur.fetchone() 173 | if r is None: 174 | return 175 | record_id, dtype, db_timestamp = r 176 | return record_id, Datatype(dtype), db_timestamp 177 | -------------------------------------------------------------------------------- /src/jinbase/store/stack.py: -------------------------------------------------------------------------------- 1 | """The Stack store is defined in this module.""" 2 | from paradict import Datatype 3 | from jinbase import queries, misc 4 | from jinbase.const import Model 5 | from jinbase.store import Store, RecordInfo 6 | 7 | 8 | __all__ = ["Stack"] 9 | 10 | 11 | class Stack(Store): 12 | """ 13 | This class represents the Stack store. 14 | Note that a Stack object isn't intended to be directly 15 | instantiated by the user. 16 | """ 17 | def __init__(self, jinbase): 18 | """ 19 | Init 20 | 21 | [params] 22 | - jinbase: Jinbase object 23 | """ 24 | super().__init__(Model.STACK, jinbase) 25 | 26 | def push(self, value): 27 | if value is None: 28 | return 29 | with self._dbc.immediate_transaction() as cursor: 30 | value = self._type_ref.adapt(value) 31 | datatype = misc.ensure_datatype(value, self._type_ref) 32 | if datatype is None: 33 | raise TypeError 34 | sql = queries.STACK_PUSH 35 | db_timestamp = misc.get_timestamp(self._db_epoch, misc.now_dt(), 36 | self._timestamp_precision) 37 | cursor.execute(sql, (datatype.value, db_timestamp)) # write 38 | record_id = cursor.lastrowid 39 | self._store_data(record_id, datatype, value) # write 40 | return record_id 41 | 42 | def push_many(self, values): 43 | with self._dbc.immediate_transaction() as cursor: 44 | uids = list() 45 | for value in values: 46 | uid = self.push(value) 47 | uids.append(uid) 48 | return tuple(uids) 49 | 50 | def pop(self, default=None): 51 | with self._dbc.immediate_transaction() as cursor: 52 | r = self._get_top() # read 53 | if r is None: 54 | return default 55 | record_id, datatype, _ = r 56 | # get value 57 | value = self._retrieve_data(record_id, datatype) # read 58 | # delete record 59 | self._delete_record(record_id) 60 | return value 61 | 62 | def peek(self, default=None): 63 | with self._dbc.transaction(): 64 | r = self._get_top() # read 65 | if r is None: 66 | return default 67 | record_id, datatype, _ = r 68 | return self._retrieve_data(record_id, datatype) 69 | 70 | def top_uid(self): 71 | with self._dbc.cursor() as cur: 72 | sql = queries.GET_STACK_TOP_UID 73 | cur.execute(sql) 74 | r = cur.fetchone() 75 | if r is None: 76 | return 77 | return r[0] 78 | 79 | def count_top_bytes(self): 80 | with self._dbc.transaction() as cur: 81 | r = self._get_top() # read 82 | if r is None: 83 | return 0 84 | record_id, _, _ = r 85 | sql = queries.COUNT_RECORD_BYTES.format(model=self._model_name) 86 | cur.execute(sql, (record_id,)) # read 87 | r = cur.fetchone()[0] 88 | return r if r else 0 89 | 90 | def count_top_chunks(self): 91 | with self._dbc.transaction() as cur: 92 | r = self._get_top() # read 93 | if r is None: 94 | return 0 95 | record_id, _, _ = r 96 | sql = queries.COUNT_RECORD_CHUNKS.format(model=self._model_name) 97 | cur.execute(sql, (record_id,)) # read 98 | r = cur.fetchone()[0] 99 | return r if r else 0 100 | 101 | def info_top(self): 102 | r = self._get_top() # read 103 | if r is None: 104 | return 105 | record_id, datatype, db_timestamp = r 106 | created_at = misc.get_datetime_str(self._db_epoch, db_timestamp, 107 | self._timestamp_precision) 108 | return RecordInfo(uid=record_id, datatype=datatype, created_at=created_at) 109 | 110 | def _get_top(self): 111 | with self._dbc.cursor() as cur: 112 | sql = queries.GET_STACK_TOP 113 | cur.execute(sql) 114 | r = cur.fetchone() 115 | if r is None: 116 | return 117 | record_id, dtype, db_timestamp = r 118 | return record_id, Datatype(dtype), db_timestamp 119 | -------------------------------------------------------------------------------- /src/jinbase/transaction_policy.txt: -------------------------------------------------------------------------------- 1 | TRANSACTION POLICY 2 | ================== 3 | 4 | Use litedbc.LiteDBC.cursor context: 5 | - for a single Read 6 | - for a single Write 7 | - for a non-transactional sequence of Reads 8 | - for a non-transactional sequence of Writes 9 | 10 | Use litedbc.LiteDBC.transaction context: 11 | - for a transactional sequence of Reads 12 | 13 | Use litedbc.LiteDBC.immediate_transaction context: 14 | - for Read-then-Write 15 | - for a transactional sequence of Writes 16 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyrustic/jinbase/baecf08698a39bd565c6938215e80cdbad910843/tests/__init__.py -------------------------------------------------------------------------------- /tests/__main__.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | 4 | def run_tests(): 5 | test_loader = unittest.defaultTestLoader 6 | test_suite = test_loader.discover("tests", pattern="test_*.py") 7 | test_runner = unittest.TextTestRunner(verbosity=1) 8 | test_runner.run(test_suite) 9 | 10 | 11 | if __name__ == "__main__": 12 | run_tests() 13 | -------------------------------------------------------------------------------- /tests/test_blob.py: -------------------------------------------------------------------------------- 1 | import os 2 | import unittest 3 | from jinbase.blob import get_blob_slices, update_position 4 | 5 | 6 | class TestGetBlobSlicesFunction(unittest.TestCase): 7 | """ 8 | 1 2 3 4 5 9 | 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 10 | """ 11 | def test(self): 12 | chunk_size = 5 13 | with self.subTest(): 14 | start_index, stop_index = 0, 1 15 | r = get_blob_slices(start_index, stop_index, chunk_size) 16 | expected = ((0, slice(0, 2)),) 17 | self.assertEqual(expected, r) 18 | with self.subTest(): 19 | start_index, stop_index = 0, 4 20 | r = get_blob_slices(start_index, stop_index, chunk_size) 21 | expected = ((0, slice(0, 5)),) 22 | self.assertEqual(expected, r) 23 | with self.subTest(): 24 | start_index, stop_index = 0, 6 25 | r = get_blob_slices(start_index, stop_index, chunk_size) 26 | expected = ((0, slice(0, 5)), 27 | (1, slice(0, 2))) 28 | self.assertEqual(expected, r) 29 | with self.subTest(): 30 | start_index, stop_index = 0, 13 31 | r = get_blob_slices(start_index, stop_index, chunk_size) 32 | expected = ((0, slice(0, 5)), 33 | (1, slice(0, 5)), 34 | (2, slice(0, 4))) 35 | self.assertEqual(expected, r) 36 | with self.subTest(): 37 | start_index, stop_index = 6, 13 38 | r = get_blob_slices(start_index, stop_index, chunk_size) 39 | expected = ((1, slice(1, 5)), 40 | (2, slice(0, 4))) 41 | self.assertEqual(expected, r) 42 | with self.subTest(): 43 | start_index, stop_index = 6, 18 44 | r = get_blob_slices(start_index, stop_index, chunk_size) 45 | expected = ((1, slice(1, 5)), 46 | (2, slice(0, 5)), 47 | (3, slice(0, 4))) 48 | self.assertEqual(expected, r) 49 | 50 | def test_start_equals_stop(self): 51 | chunk_size = 5 52 | with self.subTest(): 53 | start_index, stop_index = 0, 0 54 | r = get_blob_slices(start_index, stop_index, chunk_size) 55 | expected = ((0, slice(0, 1)), ) 56 | self.assertEqual(expected, r) 57 | with self.subTest(): 58 | start_index, stop_index = 1, 1 59 | r = get_blob_slices(start_index, stop_index, chunk_size) 60 | expected = ((0, slice(1, 2)),) 61 | self.assertEqual(expected, r) 62 | with self.subTest(): 63 | start_index, stop_index = 5, 5 64 | r = get_blob_slices(start_index, stop_index, chunk_size) 65 | expected = ((1, slice(0, 1)), ) 66 | self.assertEqual(expected, r) 67 | with self.subTest(): 68 | start_index, stop_index = 18, 18 69 | r = get_blob_slices(start_index, stop_index, chunk_size) 70 | expected = ((3, slice(3, 4)),) 71 | self.assertEqual(expected, r) 72 | 73 | 74 | class TestUpdatePositionFunction(unittest.TestCase): 75 | 76 | def test_with_seek_set_origin(self): 77 | n_bytes = 20 78 | with self.subTest("Offset equals 0"): 79 | cur_position = 5 80 | offset, origin = 0, os.SEEK_SET 81 | r = update_position(cur_position, offset, origin, n_bytes) 82 | expected = 0 83 | self.assertEqual(expected, r) 84 | with self.subTest("Offset is positive"): 85 | cur_position = 5 86 | offset, origin = 1, os.SEEK_SET 87 | r = update_position(cur_position, offset, origin, n_bytes) 88 | expected = 1 89 | self.assertEqual(expected, r) 90 | with self.subTest("Offset is negative"): 91 | cur_position = 5 92 | offset, origin = -1, os.SEEK_SET 93 | with self.assertRaises(ValueError): 94 | update_position(cur_position, offset, origin, n_bytes) 95 | with self.subTest("Offset to end of file"): 96 | cur_position = 5 97 | offset, origin = n_bytes, os.SEEK_SET 98 | r = update_position(cur_position, offset, origin, n_bytes) 99 | expected = n_bytes 100 | self.assertEqual(expected, r) 101 | with self.subTest("Offset is out of range"): 102 | cur_position = 5 103 | offset, origin = n_bytes+1, os.SEEK_SET 104 | with self.assertRaises(ValueError): 105 | update_position(cur_position, offset, origin, n_bytes) 106 | 107 | def test_with_seek_cur_origin(self): 108 | n_bytes = 20 109 | with self.subTest("Offset equals 0"): 110 | cur_position = 5 111 | offset, origin = 0, os.SEEK_CUR 112 | r = update_position(cur_position, offset, origin, n_bytes) 113 | expected = 5 114 | self.assertEqual(expected, r) 115 | with self.subTest("Offset is positive"): 116 | cur_position = 5 117 | offset, origin = 1, os.SEEK_CUR 118 | r = update_position(cur_position, offset, origin, n_bytes) 119 | expected = 6 120 | self.assertEqual(expected, r) 121 | with self.subTest("Offset is negative"): 122 | cur_position = 5 123 | offset, origin = -1, os.SEEK_CUR 124 | r = update_position(cur_position, offset, origin, n_bytes) 125 | expected = 4 126 | self.assertEqual(expected, r) 127 | with self.subTest("Offset to end of file"): 128 | cur_position = 5 129 | offset, origin = n_bytes - cur_position, os.SEEK_CUR 130 | r = update_position(cur_position, offset, origin, n_bytes) 131 | expected = n_bytes 132 | self.assertEqual(expected, r) 133 | with self.subTest("Offset is out of range"): 134 | cur_position = 5 135 | offset, origin = n_bytes - cur_position +1, os.SEEK_CUR 136 | with self.assertRaises(ValueError): 137 | update_position(cur_position, offset, origin, n_bytes) 138 | 139 | def test_with_seek_end_origin(self): 140 | n_bytes = 20 141 | with self.subTest("Offset equals 0"): 142 | cur_position = 5 143 | offset, origin = 0, os.SEEK_END # end of file 144 | r = update_position(cur_position, offset, origin, n_bytes) 145 | expected = n_bytes 146 | self.assertEqual(expected, r) 147 | with self.subTest("Offset is positive"): 148 | cur_position = 5 149 | offset, origin = 1, os.SEEK_END 150 | with self.assertRaises(ValueError): 151 | update_position(cur_position, offset, origin, n_bytes) 152 | with self.subTest("Offset is negative"): 153 | cur_position = 5 154 | offset, origin = -1, os.SEEK_END 155 | r = update_position(cur_position, offset, origin, n_bytes) 156 | expected = n_bytes - 1 157 | self.assertEqual(expected, r) 158 | with self.subTest("Offset to begin of file"): 159 | cur_position = 5 160 | offset, origin = -n_bytes, os.SEEK_END 161 | r = update_position(cur_position, offset, origin, n_bytes) 162 | expected = 0 163 | self.assertEqual(expected, r) 164 | with self.subTest("Offset is out of range"): 165 | cur_position = 5 166 | offset, origin = -n_bytes-1, os.SEEK_END 167 | with self.assertRaises(ValueError): 168 | update_position(cur_position, offset, origin, n_bytes) 169 | 170 | 171 | if __name__ == "__main__": 172 | unittest.main() 173 | -------------------------------------------------------------------------------- /tests/test_imports.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | 4 | class TestImports(unittest.TestCase): 5 | 6 | def test_import_classes(self): 7 | try: 8 | # import classes 9 | from jinbase import Jinbase 10 | from jinbase import TypeRef 11 | # import enums 12 | from jinbase import Model 13 | from jinbase import TimestampPrecision 14 | # import namedtuple 15 | from jinbase import RecordInfo 16 | # import consts 17 | from jinbase import TIMEOUT 18 | from jinbase import CHUNK_SIZE 19 | from jinbase import TIMESTAMP_PRECISION 20 | from jinbase import DATETIME_FORMAT 21 | from jinbase import USER_HOME 22 | from jinbase import JINBASE_HOME 23 | from jinbase import JINBASE_VERSION 24 | except ImportError: 25 | self.assertTrue(False) 26 | 27 | 28 | if __name__ == "__main__": 29 | unittest.main() 30 | -------------------------------------------------------------------------------- /tests/test_jinbase.py: -------------------------------------------------------------------------------- 1 | import os.path 2 | import unittest 3 | import tempfile 4 | from datetime import datetime 5 | from litedbc import LiteDBC 6 | from jinbase import Jinbase, Model 7 | from jinbase.store.kv import Kv 8 | from jinbase.store.depot import Depot 9 | from jinbase.store.queue import Queue 10 | from jinbase.store.stack import Stack 11 | 12 | 13 | class TestEmptyJinbase(unittest.TestCase): 14 | 15 | def setUp(self): 16 | self._tempdir = tempfile.TemporaryDirectory() 17 | self._filename = os.path.join(self._tempdir.name, "my.db") 18 | self._jinbase = Jinbase(self._filename) 19 | 20 | def tearDown(self): 21 | self._jinbase.close() 22 | # the Try/Except is needed here because I can only 23 | # benefit from the constructor's "ignore_cleanup_errors=True" 24 | # in Python 3.10 25 | try: 26 | self._tempdir.cleanup() 27 | except Exception as e: 28 | pass 29 | 30 | def test_properties(self): 31 | with self.subTest("Test .filename property"): 32 | self.assertEqual(self._filename, self._jinbase.filename) 33 | with self.subTest("Test .is_new property"): 34 | self.assertTrue(self._jinbase.is_new) 35 | with self.subTest("Test .dbc property"): 36 | self.assertIsInstance(self._jinbase.dbc, LiteDBC) 37 | with self.subTest("Test .in_memory property"): 38 | self.assertFalse(self._jinbase.in_memory) 39 | with self.subTest("Test .version property"): 40 | self.assertEqual(1, self._jinbase.version) 41 | with self.subTest("Test .created_at property"): 42 | created_at = self._jinbase.created_at # ISO 8601 datetime string 43 | now = self._jinbase.now() # ISO 8601 datetime string 44 | self.assertGreaterEqual(datetime.fromisoformat(now), 45 | datetime.fromisoformat(created_at)) 46 | 47 | def test_stores(self): 48 | with self.subTest("Test .kv property"): 49 | self.assertIsInstance(self._jinbase.kv, Kv) 50 | with self.subTest("Test .depot property"): 51 | self.assertIsInstance(self._jinbase.depot, Depot) 52 | with self.subTest("Test .queue property"): 53 | self.assertIsInstance(self._jinbase.queue, Queue) 54 | with self.subTest("Test .stack property"): 55 | self.assertIsInstance(self._jinbase.stack, Stack) 56 | 57 | def test_stats(self): 58 | with self.subTest("Test .count_records method"): 59 | self.assertEqual(0, self._jinbase.count_records()) 60 | with self.subTest("Test .count_chunks method"): 61 | self.assertEqual(0, self._jinbase.count_chunks()) 62 | with self.subTest("Test .count_bytes method"): 63 | self.assertEqual(0, self._jinbase.count_bytes()) 64 | 65 | def test_scan_method(self): 66 | n_records = n_bytes = 0 67 | expected = {Model.KV: (n_records, n_bytes), 68 | Model.DEPOT: (n_records, n_bytes), 69 | Model.QUEUE: (n_records, n_bytes), 70 | Model.STACK: (n_records, n_bytes)} 71 | r = self._jinbase.scan() 72 | self.assertEqual(expected, self._jinbase.scan()) 73 | 74 | def test_latest_method(self): 75 | user = {"id": 42, "name": "alex"} 76 | self._jinbase.kv.set("user", user) 77 | latest_write = self._jinbase.latest() # ISO 8601 datetime string 78 | now = self._jinbase.now_dt() 79 | self.assertGreaterEqual(now, datetime.fromisoformat(latest_write)) 80 | 81 | 82 | class TestJinbaseControl(unittest.TestCase): 83 | 84 | def setUp(self): 85 | self._tempdir = tempfile.TemporaryDirectory() 86 | self._filename = os.path.join(self._tempdir.name, "my.db") 87 | self._jinbase = Jinbase(self._filename) 88 | 89 | def tearDown(self): 90 | self._jinbase.close() 91 | try: 92 | self._tempdir.cleanup() 93 | except Exception as e: 94 | pass 95 | 96 | def test_backup(self): 97 | kv_store = self._jinbase.kv 98 | user_data = {"id": 42, "name": "alex"} 99 | kv_store.set("user", user_data) 100 | dst_filename = os.path.join(self._tempdir.name, "backup.db") 101 | self._jinbase.backup(dst_filename) 102 | jinbase2 = Jinbase(dst_filename) 103 | kv_store2 = jinbase2.kv 104 | self.assertEqual(user_data, kv_store2.get("user")) 105 | 106 | def test_vacuum_into(self): 107 | kv_store = self._jinbase.kv 108 | user_data = {"id": 42, "name": "alex"} 109 | kv_store.set("user", user_data) 110 | dst_filename = os.path.join(self._tempdir.name, "backup.db") 111 | self._jinbase.vacuum_into(dst_filename) 112 | jinbase2 = Jinbase(dst_filename) 113 | kv_store2 = jinbase2.kv 114 | self.assertEqual(user_data, kv_store2.get("user")) 115 | 116 | def test_close(self): 117 | self._jinbase.close() 118 | self.assertTrue(os.path.isfile(self._filename)) 119 | with self.assertRaises(Exception): 120 | self._jinbase.scan() 121 | 122 | def test_destroy(self): 123 | self._jinbase.destroy() 124 | self.assertFalse(os.path.isfile(self._filename)) 125 | with self.assertRaises(Exception): 126 | self._jinbase.scan() 127 | 128 | 129 | class TestMultipleJinbaseConnections(unittest.TestCase): 130 | 131 | def setUp(self): 132 | self._tempdir = tempfile.TemporaryDirectory() 133 | self._filename = os.path.join(self._tempdir.name, "my.db") 134 | self._jinbase = Jinbase(self._filename) 135 | 136 | def tearDown(self): 137 | self._jinbase.close() 138 | try: 139 | self._tempdir.cleanup() 140 | except Exception as e: 141 | pass 142 | 143 | def test_copy_method(self): 144 | user_data1 = {"id": 42, "name": "alex"} 145 | user_data2 = {"id": 420} 146 | # jinbase1 get kv store then store item1 147 | kv_store = self._jinbase.kv 148 | kv_store.set("user1", user_data1) 149 | # jinbase2 accesses kv store then read item1 150 | jinbase2 = self._jinbase.copy() 151 | kv_store2 = jinbase2.kv 152 | self.assertEqual(user_data1, kv_store2.get("user1")) 153 | # jinbase2 stores item2 in kv store 154 | kv_store2.set("user2", user_data2) 155 | # jinbase1 reads item2 156 | self.assertEqual(user_data2, kv_store.get("user2")) 157 | 158 | 159 | class TestReadonlyJinbase(unittest.TestCase): 160 | 161 | def setUp(self): 162 | self._tempdir = tempfile.TemporaryDirectory() 163 | self._filename = os.path.join(self._tempdir.name, "my.db") 164 | self._jinbase = Jinbase(self._filename) 165 | 166 | def tearDown(self): 167 | self._jinbase.close() 168 | try: 169 | self._tempdir.cleanup() 170 | except Exception as e: 171 | pass 172 | 173 | def test(self): 174 | user_data = {"id": 42, "name": "alex"} 175 | kv_store = self._jinbase.kv 176 | with self.subTest("Readonly: False"): 177 | kv_store.set("user", user_data) 178 | self.assertEqual(user_data, kv_store.get("user")) 179 | with self.subTest("Readonly: True"): 180 | jinbase2 = Jinbase(self._filename, is_readonly=True) 181 | kv_store2 = jinbase2.kv 182 | self.assertEqual(user_data, kv_store2.get("user")) 183 | with self.assertRaises(Exception): 184 | kv_store2.set("user2", {"id": 420}) 185 | 186 | 187 | class TestJinbaseContextManager(unittest.TestCase): 188 | 189 | def setUp(self): 190 | self._tempdir = tempfile.TemporaryDirectory() 191 | self._filename = os.path.join(self._tempdir.name, "my.db") 192 | 193 | def tearDown(self): 194 | try: 195 | self._tempdir.cleanup() 196 | except Exception as e: 197 | pass 198 | 199 | def test(self): 200 | with Jinbase(self._filename) as jinbase: 201 | pass 202 | self.assertTrue(jinbase.is_closed) 203 | 204 | 205 | class TestTransactionContext(unittest.TestCase): 206 | 207 | def setUp(self): 208 | self._tempdir = tempfile.TemporaryDirectory() 209 | self._filename = os.path.join(self._tempdir.name, "my.db") 210 | self._jinbase = Jinbase(self._filename) 211 | 212 | def tearDown(self): 213 | self._jinbase.close() 214 | try: 215 | self._tempdir.cleanup() 216 | except Exception as e: 217 | pass 218 | 219 | def test(self): 220 | kv_store = self._jinbase.kv 221 | depot_store = self._jinbase.depot 222 | queue_store = self._jinbase.queue 223 | stack_store = self._jinbase.stack 224 | with self._jinbase.transaction(): # TransactionMode.IMMEDIATE by default 225 | kv_store.set("user", 42) 226 | depot_store.append(42) 227 | queue_store.enqueue(42) 228 | stack_store.push(42) 229 | 230 | 231 | if __name__ == "__main__": 232 | unittest.main() 233 | -------------------------------------------------------------------------------- /tests/test_misc.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from jinbase import misc 3 | 4 | 5 | if __name__ == "__main__": 6 | unittest.main() 7 | -------------------------------------------------------------------------------- /tests/test_stack.py: -------------------------------------------------------------------------------- 1 | import os.path 2 | import unittest 3 | import tempfile 4 | import paradict 5 | from datetime import datetime 6 | from paradict import Datatype 7 | from jinbase import Jinbase, RecordInfo, const 8 | 9 | 10 | USER_CARD = {"id": 42, "name": "alex", "pi": 3.14, 11 | "photo": b'avatar.png', "permission": None, 12 | "birthday": datetime(2042, 12, 25, 13 | 16, 20, 59, 420), 14 | "books": {"sci_fi": ["Dune", 15 | "Neuromancer"], 16 | "romance": ["Happy Place", 17 | "Romantic Comedy"]}} 18 | EMPTY_USER_CARD = dict() 19 | 20 | 21 | class TestStackStore(unittest.TestCase): 22 | 23 | def setUp(self): 24 | self._tempdir = tempfile.TemporaryDirectory() 25 | self._filename = os.path.join(self._tempdir.name, "my.db") 26 | self._jinbase = Jinbase(self._filename) 27 | self._store = self._jinbase.stack 28 | 29 | def tearDown(self): 30 | try: 31 | self._tempdir.cleanup() 32 | except Exception as e: 33 | pass 34 | 35 | def test_info_top_method(self): 36 | with self.subTest("Non existent record"): 37 | self.assertIsNone(self._store.info_top()) 38 | self._store.push("hello world") 39 | self._store.push(USER_CARD) 40 | with self.subTest("Existent record"): 41 | info = self._store.info_top() 42 | self.assertIsInstance(info, RecordInfo) 43 | self.assertEqual(Datatype.DICT, info.datatype) 44 | self.assertGreaterEqual(datetime.fromisoformat(self._store.now()), 45 | datetime.fromisoformat(info.created_at)) 46 | 47 | def test_count_records_method(self): 48 | with self.subTest("Test that new store is empty"): 49 | self.assertEqual(0, self._store.count_records()) 50 | with self.subTest("Test that store contains 1 item"): 51 | self._store.push(USER_CARD) 52 | self.assertEqual(1, self._store.count_records()) 53 | 54 | def test_count_bytes_method(self): 55 | size_of_user = len(paradict.pack(USER_CARD)) 56 | # set data 57 | self._store.push(USER_CARD) 58 | self._store.push(USER_CARD) 59 | # count bytes in the store 60 | with self.subTest(): 61 | r = self._store.count_bytes() 62 | expected = size_of_user * 2 63 | self.assertEqual(expected, r) 64 | 65 | def test_count_top_bytes_method(self): 66 | size_of_user = len(paradict.pack(USER_CARD)) 67 | # set data 68 | self._store.push(USER_CARD) 69 | self._store.push(USER_CARD) 70 | # count bytes of the item on top 71 | with self.subTest(): 72 | r = self._store.count_top_bytes() 73 | expected = size_of_user 74 | self.assertEqual(expected, r) 75 | 76 | def test_is_empty(self): 77 | # --- 78 | with self.subTest("Test that new store is empty"): 79 | self.assertTrue(self._store.is_empty()) 80 | # --- 81 | with self.subTest("Test that new store is not empty"): 82 | self._store.push(USER_CARD) 83 | self.assertFalse(self._store.is_empty()) 84 | 85 | def test_push_method(self): 86 | with self.subTest("Test empty stack store"): 87 | self.assertEqual(0, self._store.count_records()) 88 | with self.subTest("Test stack store after populating it"): 89 | self._store.push(USER_CARD) 90 | self.assertEqual(1, self._store.count_records()) 91 | self._store.push(EMPTY_USER_CARD) 92 | self.assertEqual(2, self._store.count_records()) 93 | 94 | def test_push_many_method(self): 95 | r = self._store.push_many((10, 11, 12, 13)) 96 | expected = (1, 2, 3, 4) 97 | self.assertEqual(expected, r) 98 | self.assertEqual(4, self._store.count_records()) 99 | 100 | def test_pop_method(self): 101 | with self.subTest("Test empty stack store"): 102 | self.assertIsNone(self._store.pop()) 103 | with self.subTest("Test empty stack store with default value on"): 104 | self.assertEqual(USER_CARD, self._store.pop(default=USER_CARD)) 105 | with self.subTest("Test stack store after populating it"): 106 | self._store.push(EMPTY_USER_CARD) 107 | self._store.push(USER_CARD) 108 | self.assertEqual(2, self._store.count_records()) 109 | self.assertEqual(USER_CARD, self._store.pop()) 110 | self.assertEqual(1, self._store.count_records()) 111 | self.assertEqual(EMPTY_USER_CARD, self._store.pop()) 112 | self.assertEqual(0, self._store.count_records()) 113 | 114 | def test_peek_method(self): 115 | with self.subTest("Test empty stack store"): 116 | self.assertIsNone(self._store.peek()) 117 | with self.subTest("Test empty stack store with default value on"): 118 | self.assertEqual(USER_CARD, self._store.peek(default=USER_CARD)) 119 | with self.subTest("Test stack store after populating it"): 120 | self._store.push(EMPTY_USER_CARD) 121 | self._store.push(USER_CARD) 122 | self.assertEqual(USER_CARD, self._store.peek()) 123 | self._store.pop() 124 | self.assertEqual(EMPTY_USER_CARD, self._store.peek()) 125 | 126 | def test_get_top_rowid(self): 127 | rowid1 = self._store.push(USER_CARD) 128 | rowid2 = self._store.push(USER_CARD) 129 | self.assertEqual(rowid2, self._store.top_uid()) 130 | 131 | 132 | class TestSmallestChunkSize(unittest.TestCase): 133 | 134 | def setUp(self): 135 | self._tempdir = tempfile.TemporaryDirectory() 136 | self._filename = os.path.join(self._tempdir.name, "my.db") 137 | smallest_chunk_size = 1 138 | self._jinbase = Jinbase(self._filename, 139 | chunk_size=smallest_chunk_size) 140 | self._store = self._jinbase.stack 141 | 142 | def tearDown(self): 143 | self._jinbase.close() 144 | try: 145 | self._tempdir.cleanup() 146 | except Exception as e: 147 | pass 148 | 149 | def test(self): 150 | with self.subTest("Test empty stack store"): 151 | self.assertEqual(0, self._store.count_records()) 152 | with self.subTest("Test stack store after populating it"): 153 | self._store.push(USER_CARD) 154 | self.assertEqual(1, self._store.count_records()) 155 | self._store.push(EMPTY_USER_CARD) 156 | self.assertEqual(2, self._store.count_records()) 157 | with self.subTest("Test pop"): 158 | r = self._store.pop() 159 | self.assertEqual(EMPTY_USER_CARD, r) 160 | self.assertEqual(1, self._store.count_records()) 161 | r = self._store.pop() 162 | self.assertEqual(USER_CARD, r) 163 | self.assertEqual(0, self._store.count_records()) 164 | 165 | def test_count_top_chunks_method(self): 166 | self._store.push(EMPTY_USER_CARD) 167 | self._store.push(USER_CARD) 168 | size_user_card = len(paradict.pack(USER_CARD)) # n bytes 169 | size_empty_user_card = len(paradict.pack(EMPTY_USER_CARD)) # n bytes 170 | # count total chunks 171 | with self.subTest("Count total chunks"): 172 | n_chunks = self._store.count_chunks() 173 | expected_n_chunks = size_user_card + size_empty_user_card 174 | self.assertEqual(expected_n_chunks, n_chunks) 175 | # count front chunks 176 | with self.subTest("Count chunks at top"): 177 | n_chunks = self._store.count_top_chunks() 178 | expected_n_chunks = size_user_card 179 | self.assertEqual(expected_n_chunks, n_chunks) 180 | # pop then count total chunks 181 | with self.subTest("Pop then count total chunks"): 182 | self._store.pop() 183 | n_chunks = self._store.count_chunks() 184 | expected_n_chunks = size_empty_user_card 185 | self.assertEqual(expected_n_chunks, n_chunks) 186 | 187 | 188 | class TestDefaultValue(unittest.TestCase): 189 | 190 | def setUp(self): 191 | self._tempdir = tempfile.TemporaryDirectory() 192 | self._filename = os.path.join(self._tempdir.name, "my.db") 193 | smallest_chunk_size = 1 # 1 byte 194 | self._jinbase = Jinbase(self._filename, 195 | chunk_size=smallest_chunk_size) 196 | self._store = self._jinbase.stack 197 | 198 | def tearDown(self): 199 | self._jinbase.close() 200 | try: 201 | self._tempdir.cleanup() 202 | except Exception as e: 203 | pass 204 | 205 | def test(self): 206 | self.assertEqual(USER_CARD, self._store.pop(default=USER_CARD)) 207 | self.assertEqual(USER_CARD, self._store.peek(default=USER_CARD)) 208 | 209 | 210 | class TestTransactionContext(unittest.TestCase): 211 | 212 | def setUp(self): 213 | self._tempdir = tempfile.TemporaryDirectory() 214 | self._filename = os.path.join(self._tempdir.name, "my.db") 215 | self._jinbase = Jinbase(self._filename) 216 | self._store = self._jinbase.stack 217 | 218 | def tearDown(self): 219 | self._jinbase.close() 220 | try: 221 | self._tempdir.cleanup() 222 | except Exception as e: 223 | pass 224 | 225 | def test(self): 226 | with self._store.transaction(): # TransactionMode.IMMEDIATE by default 227 | self._store.push(USER_CARD) 228 | self._store.push(USER_CARD) 229 | self._store.pop() 230 | 231 | 232 | class TestLargeBinaryData(unittest.TestCase): 233 | 234 | def setUp(self): 235 | self._tempdir = tempfile.TemporaryDirectory() 236 | self._filename = os.path.join(self._tempdir.name, "my.db") 237 | self._jinbase = Jinbase(self._filename) 238 | self._store = self._jinbase.stack 239 | 240 | def tearDown(self): 241 | self._jinbase.close() 242 | try: 243 | self._tempdir.cleanup() 244 | except Exception as e: 245 | pass 246 | 247 | def test(self): 248 | data = b'\x00' * (const.CHUNK_SIZE * 2) 249 | self._store.push(data) 250 | self.assertEqual(data, self._store.pop()) 251 | 252 | 253 | if __name__ == "__main__": 254 | unittest.main() 255 | --------------------------------------------------------------------------------