Skip to content

Commit e801210

Browse files
landerliniLucio Anderlini
andauthored
Added UpdateDBConnection to refresh DB connection for python clients
* First attempt of adding UpdateDBConnection * Fixed several bugs due to caching of sqlite3 objects --------- Co-authored-by: Lucio Anderlini <Lucio.Anderlini@fi.infn.it>
1 parent a332686 commit e801210

17 files changed

Lines changed: 311 additions & 20 deletions

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,7 @@
44
/.idea/
55
*.swp
66
/docs/
7+
/wheelhouse/
8+
/dist/
9+
**.egg-info
10+
**/__pycache__/

docs.md/Creating_the_wheel.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ older Linux distributions.
77
Indeed, PyPI forbids uploading wheel that do not specify a compatibility tag
88
used to choose the right wheel when running `pip install SQLamarr`.
99

10+
## Using docker
1011
To compile the wheel in compatibility mode, we are using the following recipe,
1112
which assumes the working directory is the root of the git repository
1213
```bash
@@ -15,7 +16,22 @@ docker run -it -v $PWD:/mylib quay.io/pypa/manylinux2014_x86_64:latest \
1516
python3 -m twine upload wheelhouse/*.whl
1617
```
1718

18-
Additional information:
19+
## Using Apptainer
20+
In some environments, docker is not available and apptainer should be used instead.
21+
22+
First convert the docker image to an SIF image (this is only required once).
23+
```bash
24+
apptainer build /tmp/pypa.sif docker://quay.io/pypa/manylinux2014_x86_64:latest
25+
```
26+
27+
Then execute the following script (as for the docker case, it is assumed
28+
the working directory is the root of the git repository).
29+
30+
```build
31+
apptainer exec --bind $PWD:/mylib --writable-tmpfs /tmp/pypa.sif /bin/bash make_wheel.sh
32+
```
33+
34+
## Additional information:
1935
* Distributing binaries in compatibility mode: https://github.com/pypa/manylinux
2036
* Example using travis for CI/CD: https://github.com/pypa/python-manylinux-demo
2137

include/SQLamarr/BaseSqlInterface.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#include <string>
1414
#include <unordered_map>
1515

16-
#include "SQLamarr/BaseSqlInterface.h"
1716
#include "SQLamarr/db_functions.h"
1817

1918
namespace SQLamarr
@@ -39,12 +38,21 @@ namespace SQLamarr
3938
BaseSqlInterface(SQLite3DB& db);
4039
virtual ~BaseSqlInterface();
4140

41+
void sync_database(const std::string& db_uri)
42+
{update_db_connection(m_database, db_uri);}
43+
44+
/// Invalidate the cache of the queries.
45+
/// Especially useful to allow refreshing the connection when running
46+
/// from Python.
47+
void invalidate_cache(void);
48+
4249
protected: // members
4350
SQLite3DB& m_database; ///< Reference to the SQLite database (not owned).
4451

4552

4653
private: //members
4754
std::unordered_map<std::string, sqlite3_stmt*> m_queries;
55+
sqlite3* m_cached_raw_ptr;
4856

4957
protected: // methods
5058
/// Creates or retrieve from cache a statement
@@ -60,7 +68,7 @@ namespace SQLamarr
6068
void begin_transaction () { sqlite3_exec(m_database.get(), "BEGIN", 0, 0, 0); }
6169

6270
/// End an SQL transaction re-enabling disk updates
63-
void end_transaction () { sqlite3_exec(m_database.get(), "END", 0, 0, 0); }
71+
void end_transaction () { sqlite3_exec(m_database.get(), "COMMIT", 0, 0, 0); }
6472

6573
/// Return the index of the last rows inserted in any table
6674
int last_insert_row () { return sqlite3_last_insert_rowid(m_database.get()); }
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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+
#pragma once
11+
12+
// STL
13+
#include <string>
14+
15+
// SQLamarr
16+
#include "SQLamarr/db_functions.h"
17+
#include "SQLamarr/Transformer.h"
18+
19+
namespace SQLamarr
20+
{
21+
/** Reset the database connection forcing flushing the db status.
22+
*
23+
* In the interaction with Python or other frameworks it is sometimes
24+
* necessary to ensure db synchronization with disk or shared memory.
25+
* This can be achieved refreshing the connection to the database,
26+
* by closing it and reopening.
27+
*
28+
* WARNING! Executing UpdateDBConnection drops TEMPORARY tables and views.
29+
*/
30+
class UpdateDBConnection: public Transformer
31+
{
32+
public:
33+
/// Constructor
34+
UpdateDBConnection (
35+
SQLite3DB& db,
36+
///< Reference to the database
37+
std::string filename,
38+
///< Filename or URI of the (possibly new) connection to the database
39+
int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_URI
40+
///< Flags
41+
);
42+
43+
44+
/// Execute the algorithm, cleaning the database
45+
void execute () override;
46+
47+
private: // members
48+
SQLite3DB& m_database; ///< Reference to the SQLite database (not owned).
49+
const std::string m_filename; ///< Filename or URI of the database
50+
const int m_flags; ///< SQLite flags to open to database (see sqlite_open_v3)
51+
};
52+
}
53+
54+

include/SQLamarr/db_functions.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ namespace SQLamarr
3636

3737
/// Ensure a token is alphanumeric
3838
void validate_token(const std::string& token);
39+
40+
/// Force synchronization to disk by closing and opening the connection
41+
void update_db_connection(
42+
SQLite3DB& old_db,
43+
const std::string& db_uri,
44+
int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_URI
45+
);
3946
}
4047

4148

make_wheel.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ cd /mylib;
77
rm -f wheelhouse/*.whl | echo "Ok";
88
rm -f dist/*.whl | echo "Ok";
99

10-
for PYVERSION in cp311-cp311 cp310-cp310 cp37-cp37m cp38-cp38 cp39-cp39;
10+
for PYVERSION in cp312-cp312 cp311-cp311 cp310-cp310 cp37-cp37m cp38-cp38 cp39-cp39;
1111
do
1212
export PYBIN=/opt/python/$PYVERSION/bin/python3
1313
echo "Preparing binary distribution with $PYBIN";

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ classifiers = [
4444
]
4545

4646

47-
version = "0.0c5"
47+
version = "0.0c7"
4848

4949
dependencies = ["hepmc3"]
5050

python/SQLamarr/HepMC2DataLoader.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,19 +54,17 @@ class HepMC2DataLoader:
5454
"""
5555
def __init__(self, db: SQLite3DB):
5656
"""Acquires the reference to an open connection to the DB"""
57-
self._self = clib.new_HepMC2DataLoader(db.get())
57+
self._db = db
5858

59-
def __del__ (self):
60-
"""@private: Release the bound class instance"""
61-
clib.del_HepMC2DataLoader(self._self)
62-
6359
def load(self, filename: str, runNumber: int, evtNumber: int):
6460
"""Loads an ASCII file with
6561
[HepMC3::ReaderAsciiHepMC2](http://hepmc.web.cern.ch/hepmc/classHepMC3_1_1ReaderAsciiHepMC2.html).
6662
"""
6763
if not os.path.exists(filename):
6864
raise FileNotFoundError(filename)
6965

66+
_self = clib.new_HepMC2DataLoader(self._db.get())
7067
clib.HepMC2DataLoader_load(
71-
self._self, filename.encode('ascii'), runNumber, evtNumber
68+
_self, filename.encode('ascii'), runNumber, evtNumber, self._db.path.encode('ascii')
7269
)
70+
clib.del_HepMC2DataLoader(_self)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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+
import ctypes
10+
from ctypes import POINTER
11+
from SQLamarr import clib, c_TransformerPtr
12+
13+
from SQLamarr.db_functions import SQLite3DB
14+
15+
clib.new_UpdateDBConnection.argtypes = (ctypes.c_void_p,)
16+
clib.new_UpdateDBConnection.restype = c_TransformerPtr
17+
18+
class UpdateDBConnection:
19+
"""
20+
Update the reference to the DB Connection, to ensure synchronization with disk.
21+
22+
Refer to SQLamarr::UpdateDBConnection for implementation details.
23+
"""
24+
def __init__ (self, db: SQLite3DB):
25+
"""
26+
Configure a Transformer to update the connection to the DB.
27+
28+
@param db: An open database connection.
29+
"""
30+
self._self = clib.new_UpdateDBConnection(db.get(), db.path.encode('ascii'))
31+
32+
def __del__(self):
33+
"""@private: Release the bound class instance"""
34+
clib.del_Transformer(self._self)
35+
36+
@property
37+
def raw_pointer(self):
38+
"""@private: Return the raw pointer to the algorithm."""
39+
return self._self
40+
41+
42+
43+

python/SQLamarr/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class c_TransformerPtr (ctypes.Structure):
4040
from SQLamarr.TemporaryTable import TemporaryTable
4141
from SQLamarr.CleanEventStore import CleanEventStore
4242
from SQLamarr.EditEventStore import EditEventStore
43+
from SQLamarr.UpdateDBConnection import UpdateDBConnection
4344

4445
## Python Transfomer
4546
from SQLamarr.PyTransformer import PyTransformer

0 commit comments

Comments
 (0)