Trading System API  3.0
Library for Simulating and Deploying Trading and Investment Strategies
TSASQLite.h
1 /*
2 Copyright (C) 2013 Nick Ogden <nick@nickogden.org>
3 copyright (C) Peter Ritter (2015)
4 
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8 
9 http://www.apache.org/licenses/LICENSE-2.0
10 
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 
17 // =============================================
18 // NOTE: This code has been heavily modified!
19 // =============================================
20 
21 */
22 
23 #ifndef TSA_SQLITE__INCLUDED
24 #define TSA_SQLITE__INCLUDED
25 
26 #include <cstddef>
27 #include <memory>
28 #include <string>
29 #include <exception>
30 
31 #include "TSATime.h"
32 #include "TSAOS.h"
33 #include "TSADataDef.h"
34 #include "TSADBBase.h"
35 
36 struct sqlite3;
37 struct sqlite3_stmt;
38 
39 namespace std {
40  template<typename T> class function;
41 }
42 
43 namespace tsa {
44  class out_stream_adaptor;
45  class in_stream_adaptor;
46 
51  namespace sqlite {
53  class database;
54 
55  /*
56  ** ====================================================
57  ** >>> class error <<<
58  ** ====================================================
59  */
60  class error : public std::runtime_error {
61  public:
62  error(const int error_code, const std::string& msg = std::string());
63  error(const std::string& msg);
64  error(
65  const std::shared_ptr<sqlite3_stmt>& stmt,
66  const std::string& msg = std::string()
67  );
68 
69  const int sqlite_error_code() const /*noexcept*/ { return code; }
70 
71  private:
72  const int code = 0;
73  };
74 
75  // Fundamental sqlite data type
76  enum type {
77  sq_integer8 = 1,
78  sq_float8 = 2,
79  sq_text = 3,
80  sq_blob = 4,
81  sq_null = 5
82  };
83 
84  /*
85  ** ====================================================
86  ** >>> class field <<<
87  ** ====================================================
88  */
89  class field {
90  public:
91  field(const std::shared_ptr<sqlite3_stmt>& statement,
92  const std::size_t& parameter_index
93  );
94  bool is_null() const;
95  explicit operator bool() const;
96  type column_type(void)const;
97  std::string column_name(void) const;
98  template<typename T> T as() const;
99  void get_variant(tsa::variant&, const tsa::type_t& target_type);
100  private:
101  std::shared_ptr<sqlite3_stmt> m_stmt_ptr;
102  const std::size_t m_index;
103  };
104 
105  /*
106  ** ====================================================
107  ** >>> class row <<<
108  ** ====================================================
109  */
110  class row {
111  public:
112  row(const std::shared_ptr<sqlite3_stmt>& statement);
113  row(const row& other) = default;
114  //row(row&& other);// = default;
115  row& operator=(const row& other) = default;
116  //row& operator=(row&& other) = default;
117  std::size_t column_count() const;
118  field operator[](const std::string& column_name) const;
119  field operator[](std::size_t column_index) const;
120  field at(const std::string& column_name) const;
121  field at(std::size_t column_index) const;
122  void print_row(std::ostream&)const;
123  void print_row_v(std::ostream&)const;
124  private:
125  bool is_valid_index(const std::size_t& index) const;
126  private:
127  std::shared_ptr<sqlite3_stmt> m_stmt_ptr;
128  };
129 
130  class transaction_failed : public error {
131  public:
132  transaction_failed(const int status) : error(status) {}
133  };
134 
135  /*
136  ** ====================================================
137  ** >>> class result <<<
138  ** ====================================================
139  */
140  class result {
141  public:
142  class const_iterator {
143  public:
144  const_iterator(const std::shared_ptr<sqlite3_stmt>& statement, bool& at_end);
145  const_iterator(const const_iterator& other) = delete;
146  const_iterator(const const_iterator&& other);
147  const_iterator(const_iterator&& other);// = default;
148  const_iterator& operator=(const const_iterator& other) = delete;
149  //const_iterator& operator=(const_iterator&& other);// = default;
150  bool operator==(const const_iterator& other) const;
151  bool operator!=(const const_iterator& other) const;
152  const_iterator& operator++();
153  const row& operator*() const;
154  const row* operator->() const;
155  private:
156  std::shared_ptr<sqlite3_stmt> stmt;
157  bool& end_reached;
158  row current_row;
159  };
160  public:
161  bool is_valid(void)const;
162  result(void);//only for use by stream delegates
163  public:
164  result(const std::shared_ptr<sqlite3_stmt>& statement);
165  result(const result& other) = delete;
166  result(result&& other);
167 
168  result& operator=(const result& other) = delete;
169  result& operator=(result&& other);
170 
171  size_t calculate_row_count()const;
172  std::size_t row_modification_count() const;
173  const_iterator begin() const;
174  const_iterator end() const;
175  public:
176  void print_rows(std::ostream&)const;
177  void print_rows_v(std::ostream&)const;
178  private:
179  std::shared_ptr<sqlite3_stmt> m_stmt_ptr;
180  mutable bool m_end_reached = false;
181  };
182 
183  class blob;
184  class statement;
185 
186  enum class null_t {
187  null
188  };
189  static const null_t null = null_t::null;
190 
191  /*
192  ** ====================================================
193  ** >>> class statement <<<
194  ** ====================================================
195  */
196  class statement {
197  public:
198  statement(const std::shared_ptr<sqlite3_stmt>& statement);
199  statement(const statement& other) = delete;
200  statement(statement&& other);// = default;
201  statement& operator=(const statement& other) = delete;
202  statement& operator=(statement&& other);// = default;
203  std::size_t parameter_count() const;
204 
205  template<typename T>
206  void bind(const std::string& parameter, const T& value);
207  void bind(const std::string& parameter, const char* value);
208  void clear_bindings();
209  friend std::ostream& operator<<(std::ostream& os, const statement& statement);
210  private:
211  void throw_on_bind_error(const int status, const std::string& parameter) const;
212  friend result make_result(const statement& statement);
213  private:
214  std::shared_ptr<sqlite3_stmt> m_stmt_ptr;
215  };
216 
217  static char const* temporary = "";
218 
219  enum class special_t {
220  in_memory
221  };
222  static const special_t in_memory = special_t::in_memory;
223 
224  enum access_mode {
225  read_only = 0x01,
226  read_write = 0x02,
227  read_write_create = 0x06
228  };
229 
230  enum cache_type {
231  shared_cache = 0x00020000,
232  private_cache = 0x00040000
233  };
234 
235  /*
236  ** ====================================================
237  ** >>> class transaction <<<
238  ** ====================================================
239  */
240  class transaction {
241  friend class database;
242  database* m_db_ptr = nullptr;
243  bool m_is_open = true;
244  public:
245  transaction(database* db_ptr);
246  transaction(const transaction&);
247  ~transaction(void);
248  void commit(void);
249  void rollback(void);
250  };
251 
252  /*
253  ** ====================================================
254  ** >>> table and field info <<<
255  ** ====================================================
256  */
257  struct field_info_t {
258  int cid;
259  std::string name;
260  std::string type;
261  size_t length; //only for strings
262  tsa::type_t tsa_type;
263  bool not_null;
264  std::string default_value;
265  bool is_primary_key;
266  };
267 
268  class table_info_t {
269  friend class sqlite::database;
270  std::string m_table_name;
271  std::vector <field_info_t> m_fields;
272  public:
273  table_info_t(void) = default;
274  table_info_t(const std::string& table_name) { m_table_name = table_name; }
275  table_info_t(table_info_t&) = default;
276  table_info_t(table_info_t&&);
277  const std::string& name(void)const { return m_table_name; }
278  const field_info_t& operator[](size_t pos);
279  size_t size(void)const;
280  void print(std::ostream&);
281  };
282 
283  /*
284  ** ====================================================
285  ** >>> class database <<<
286  ** ====================================================
287  */
288 
293  class dll_export database : public tsa::data_base {
294  private:
295  void close() /*noexcept*/;
296  std::shared_ptr<sqlite3_stmt> create_statement(const std::string& sql) const;
297  private:
298  sqlite3* m_db_ptr = nullptr;
299  public:
300  virtual std::string type(void)const override;
301  public:
303  database(
304  const tsa::os::path& path,
305  const access_mode& permissions = sqlite::read_write_create,
306  const cache_type& visibility = private_cache
307  );
309  database(
310  const special_t& in_memory,
311  const access_mode& permissions = sqlite::read_write_create,
312  const cache_type& visibility = private_cache
313  );
314  database(const database& other) = delete;
315  database(database&& other) = delete;//= default;
316  virtual ~database();
317  public:
318  virtual out_stream_adaptor* make_output_stream_adaptor(void) override;
319  in_stream_adaptor* database::make_input_stream_adaptor(const std::string& stream)override;
320  public:
321  virtual bool table_exists(const std::string&)const override;
322  void drop_table(const std::string&, bool throw_on_error = false);
323  virtual bool drop_series_table(const std::string&)override;
324  virtual void create_series_table(const std::string& table_name, const tsa::column_defs&)override;
325  virtual tsa::column_defs series_table_column_defs(const std::string& table_name)override;
326  void series_insert(const std::string& table_name, const tsa::mem_table& data);
327  virtual void series_append(const std::string& table_name, const tsa::mem_table& data)override;
328  virtual void series_load(const std::string& table_name, tsa::mem_table& data,
329  const date_time& from_timestamp, size_t num_records)override;
330  void series_load(const std::string& table_name, tsa::mem_table& data);
331  void clear_table(const std::string& table_name, bool throw_on_error = false);
332  virtual date_time series_table_first_timestamp(const std::string& table_name)override;
333  virtual date_time series_table_last_timestamp(const std::string& table_name)override;
334  virtual int64_t table_record_count(const std::string& table_name);
335  virtual bool table_has_data(const std::string& table_name)override;
336  virtual date_time series_table_closest_timestamp_LOE(const date_time& ts, const std::string& table_name)override;
337  virtual void truncate_series_table(const std::string& table_name, const date_time& new_max_timestamp = date_time::min);
338  virtual bool table_record_count_is_known(void)const;
339 
340  public:
341  database& operator=(const database& other) = delete;
342  database& operator=(database&& other);// = default;
343  statement prepare_statement(const std::string& sql) const;
344  public:
345  transaction begin(void);
346  bool in_transaction(void)const;
347  public:
348  friend class transaction;
349  void rollback(void);
350  void commit(void);
351  public:
352  result select_all_from(const std::string& table_name);
353  result execute(const std::string& sql)const;
354  result execute(const statement& statement);
355  template<typename T> T execute_scalar(const std::string& sql) const {
356  result r = execute(sql);
357  if (r.begin() == r.end()){
358  throw tsa::exception("sqlite::result", "Scalar query returned no results: " + sql, SLOC);
359  }
360  return (*r.begin())[0].as<T>();
361  }
362  template<typename T> T execute_scalar(const statement& statement)const {
363  result results = make_result(statement);
364  if (results.begin() == results.end()){
365  throw tsa::exception("sqlite::result", "Scalar query returned no results.", SLOC);
366  }
367  return (*results.begin())[0].as<T>();
368  }
369  std::size_t size_on_disk()const;
370  friend std::ostream& operator<<(std::ostream& stream, const database& db);
371  public:
372  table_info_t table_info(const std::string& table_name);
373  public:
374  void rand_ohlcv(const std::string& table_name, const tsa::date_time& start = "1970-01-01",
375  const tsa::duration& ival = tsa::duration::minutes(1));
376  public:
377  void print_table(std::ostream&, const std::string& table_name);
378  void print_table_v(std::ostream&, const std::string& table_name);
379  };
380  } // namespace sqlite
381 
383 }//tsa
384 
385 #endif
Class for generating pseudo random price series (o,h,l,c,v).
Utility class to manipulate file system paths. This class is intended to fulfil the requirements of t...
Definition: TSAOS.h:36
Namespace for the &#39;Trading System API&#39; library.
Definition: original1.TSA3Core.cpp:20
Base class for all other database classes such as:
Definition: TSADBBase.h:47
sref< double > operator*(numeric_series_cref a, numeric_series_cref b)
Multiplies a by b.
Definition: TSADSLBase.cpp:42
Definition: database.cpp:26
Defines the columnar structure of a table. Each column has a name, data type and field size...
Definition: TSADataDef.h:88
Definition: TSASQLite.h:39
#define SLOC
Macro to be passed as argument to Exception constructors. Contains information about the source locat...
Definition: TSAError.h:92
Parent class for &#39;in-stream adaptors&#39;. in_stream object rely on adaptors for access to underlying dat...
Definition: TSAStreams.h:52
Abstract base class for delegates of class out_stream.
Definition: TSAStreams.h:553
variant objects can represent values of different types.
Definition: TSAVariant.h:140
Represents a duration - the difference between two date_time values.
Definition: TSATime.h:945
std::ostream & operator<<(std::ostream &s, const transaction &t)
Writes human readable transaction information to stream.
Definition: TSAOrder.cpp:779
_value_types_type
Data type enumeration used throughout the library. Intended to be used via type_t.
Definition: TSATypeDef.h:166
Class tsa::exception used by most classes of the Trading System API library. The class inherits from ...
Definition: TSAError.h:37
SQLite database object. Object of this class allow ts-api to read and write time series tables in an ...
Definition: TSASQLite.h:293
double min(const series< double > &series, size_t period)
Returns the smallest value found in series over given .
Definition: TSAFunctionsScalar.cpp:218
sref< bool > operator==(numeric_series_cref a, numeric_series_cref b)
comparison.
Definition: TSADSLBase.cpp:130
Class representing a gregorian-date and time-of-day combination. The time component has microsecond r...
Definition: TSATime.h:428
Class mem_table represents a memory based table. mem_table objects can be used in strategies both for...
Definition: TSAMemTable.h:48
static duration minutes(uint64_t)
Returns a duration equivalent to a given number of minutes.
Definition: TSATime.cpp:1412