SQLamarr
The stand-alone ultra-fast simulation option for the LHCb experiment
db_functions.py
1 # (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration.
2 #
3 # This software is distributed under the terms of the GNU General Public
4 # Licence version 3 (GPL Version 3), copied verbatim in the file "LICENCE".
5 #
6 # In applying this licence, CERN does not waive the privileges and immunities
7 # granted to it by virtue of its status as an Intergovernmental Organization
8 # or submit itself to any jurisdiction.
9 
10 import ctypes
11 from ctypes import POINTER
12 from SQLamarr import clib
13 import sqlite3
14 import contextlib
15 
16 clib.make_database.argtypes = (POINTER(ctypes.c_char),)
17 clib.make_database.restype = ctypes.c_void_p
18 
19 clib.del_database.argtypes = (ctypes.c_void_p,)
20 
21 clib.GlobalPRNG_get_or_create.argtypes = (ctypes.c_void_p, ctypes.c_int)
22 
23 
24 class SQLite3DB:
25  """
26  A database connection handler easying sharing the DB between C++ and Python.
27  """
28 
29  def __init__(self, path: str = "file::memory:?cache=shared"):
30  """
31  Open the connection for the C++ application, with shared cache to ease
32  access from Python to the same tables.
33 
34  @param path: path-like or URI identifying the target resource; by
35  default, an non-threadsafe connection to an in-memory database is opened.
36 
37  ### Examples
38  Connecting to an existing, prepared database stored on file `mydata.db`
39  ```python
40  db = SQLamarr.SQLite3DB("mydata.db")
41  ```
42 
43  Connecting to an empty, in-memory database for prototyping
44  ```python
45  db = SQLamarr.SQLite3DB()
46  ```
47 
48  Connecting to an empty, in-memory database in a multithreaded application
49  with each thread working on its own db.
50  ```python
51  db_wn1 = SQLamarr.SQLite3DB("file:wn1?mode=memory&cache=shared")
52  db_wn2 = SQLamarr.SQLite3DB("file:wn2?mode=memory&cache=shared")
53  ```
54  """
55  self._path_path = path if path.startswith(
56  "file:") else f"file:{path}?cache=shared"
57 
58  self._pointer_pointer = clib.make_database(path.encode('ascii'))
59 
60  def __del__(self):
61  """@private: Return the raw pointer to the algorithm."""
62  clib.del_database(self._pointer_pointer)
63 
64  @property
65  def path(self):
66  return self._path_path
67 
68  def get(self):
69  """@private: Return the raw pointer to the database."""
70  return self._pointer_pointer
71 
72  def seed(self, seed: int):
73  """
74  Define the seed for the random number generated from Transformers
75  interacting with the database through this connection.
76 
77  @param seed: integer seed for randomization
78 
79  @returns SQLite3DB (self) instance
80  """
81  clib.GlobalPRNG_get_or_create(self._pointer_pointer, seed)
82  return self
83 
84  @contextlib.contextmanager
85  def connect(self):
86  """
87  Python-like connection with a context-manager.
88 
89  Example.
90  ```python
91 
92  # Define the DB handler and seeds the random number generator
93  db = SQLamarr.SQLite3DB().seed(42)
94 
95  # Load some event from HepMC2 ASCII file
96  loader = SQLamarr.HepMC2DataLoader(db)
97  loader.load(<file_path>, <evtNumber>,<runNumber>)
98 
99  # Connect to the DB (while still open in C++ memory!)
100  with db.connect() as c:
101  # Loads in a pandas DataFrame the object
102  df = pandas.read_sql_query("SELECT * FROM GenParticles")
103 
104  ```
105 
106  """
107  if self._path_path == ":memory:":
108  raise NotImplementedError(
109  "Cannot connect to an in-memory database without cache sharing"
110  )
111 
112  with sqlite3.connect(self._path_path, uri=True) as db:
113  yield db
A database connection handler easying sharing the DB between C++ and Python.
Definition: db_functions.py:24
def seed(self, int seed)
Define the seed for the random number generated from Transformers interacting with the database throu...
Definition: db_functions.py:72
def __init__(self, str path="file::memory:?cache=shared")
Open the connection for the C++ application, with shared cache to ease access from Python to the same...
Definition: db_functions.py:29
def connect(self)
Python-like connection with a context-manager.
Definition: db_functions.py:85