SQLamarr
The stand-alone ultra-fast simulation option for the LHCb experiment
TemporaryTable.cpp
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 
11 // STL
12 #include <sstream>
13 
14 // SQLite
15 #include "sqlite3.h"
16 
17 // SQLamarr
18 #include "SQLamarr/TemporaryTable.h"
19 
20 namespace SQLamarr
21 {
22  //============================================================================
23  // Constructor (from list of statements)
24  //============================================================================
25  TemporaryTable::TemporaryTable (
26  SQLite3DB& db,
27  const std::string& output_table,
28  const std::vector<std::string>& columns,
29  const std::vector<std::string>& select_statements,
30  bool make_persistent
31  )
32  : BaseSqlInterface (db)
33  , m_output_table (output_table)
34  , m_columns (columns)
35  , m_select_statements (select_statements)
36  , m_make_persistent (make_persistent)
37  {
38  validate_token (output_table);
39  for (auto& column_name: m_columns)
40  validate_token (column_name);
41  }
42 
43  //============================================================================
44  // Constructor (from a single statement)
45  //============================================================================
46  TemporaryTable::TemporaryTable (
47  SQLite3DB& db,
48  const std::string& output_table,
49  const std::vector<std::string>& columns,
50  const std::string& select_statement,
51  bool make_persistent
52  )
53  : BaseSqlInterface (db)
54  , m_output_table (output_table)
55  , m_columns (columns)
56  , m_select_statements ({select_statement})
57  , m_make_persistent (make_persistent)
58  {
59  validate_token (output_table);
60  for (auto& column_name: m_columns)
61  validate_token (column_name);
62  }
63 
64  //============================================================================
65  // compose_create_query. Internal
66  //============================================================================
67  std::string TemporaryTable::compose_create_query() const
68  {
69  std::stringstream s;
70  s << "CREATE ";
71 
72  if (!m_make_persistent)
73  s << "TEMPORARY ";
74 
75  s << "TABLE IF NOT EXISTS "
76  << m_output_table << "(";
77 
78  for (auto c: m_columns)
79  s << c << (c != m_columns.back() ? ", ": "");
80 
81  s << ");";
82 
83  return s.str();
84  }
85 
86  //============================================================================
87  // compose_delete_query. Internal.
88  //============================================================================
89  std::string TemporaryTable::compose_delete_query() const
90  {
91  std::stringstream s;
92  s << "DELETE FROM " << m_output_table << ";";
93  return s.str();
94  }
95 
96  //============================================================================
97  // compose_create_query. Internal.
98  //============================================================================
99  std::string TemporaryTable::compose_insert_query(const std::string& st) const
100  {
101  std::stringstream s;
102  s << "INSERT INTO " << m_output_table << " (";
103 
104  for (auto c: m_columns)
105  s << c << (c != m_columns.back() ? ", ": "");
106  s << ") ";
107 
108  s << st;
109 
110  return s.str();
111  }
112 
113  //============================================================================
114  // Execute
115  //============================================================================
116  void TemporaryTable::execute ()
117  {
118  // Prepare the queries and initialize the database
119  // CREATE TEMPORARY TABLE IF NOT EXISTS
120  sqlite3_stmt* create_output_table = get_statement(
121  "create_output_table", compose_create_query().c_str()
122  );
123  exec_stmt(create_output_table);
124 
125  // DELETE FROM table
126  sqlite3_stmt* delete_output_table = get_statement(
127  "delete_output_table", compose_delete_query().c_str()
128  );
129  exec_stmt(delete_output_table);
130 
131  // INSERT INTO TABLE
132  int c = 0;
133  char buffer[128];
134  for (auto& stmt: m_select_statements)
135  {
136  sprintf(buffer, "insert_in_output_table_%d", c++);
137  exec_stmt(get_statement(buffer, compose_insert_query(stmt).c_str()));
138  }
139  }
140 }
void validate_token(const std::string &token)
Ensure a token is alphanumeric.
std::unique_ptr< sqlite3, void(*)(sqlite3 *)> SQLite3DB
Unique pointer to the sqlite3 connection.
Definition: db_functions.h:19