xbmc
dataset.h
1 /*
2  * Copyright (C) 2002, Leo Seib, Hannover
3  *
4  * Project:Dataset C++ Dynamic Library
5  * Module: Dataset abstraction layer header file
6  * Author: Leo Seib E-Mail: leoseib@web.de
7  * Begin: 5/04/2002
8  *
9  * SPDX-License-Identifier: MIT
10  * See LICENSES/README.md for more information.
11  */
12 
13 #pragma once
14 
15 #include "qry_dat.h"
16 
17 #include <cstdio>
18 #include <list>
19 #include <map>
20 #include <stdarg.h>
21 #include <string>
22 #include <unordered_map>
23 
24 namespace dbiplus
25 {
26 class Dataset; // forward declaration of class Dataset
27 
28 #define S_NO_CONNECTION "No active connection";
29 
30 #define DB_BUFF_MAX 8 * 1024 // Maximum buffer's capacity
31 
32 #define DB_CONNECTION_NONE 0
33 #define DB_CONNECTION_OK 1
34 #define DB_CONNECTION_BAD 2
35 
36 #define DB_COMMAND_OK 0 // OK - command executed
37 #define DB_EMPTY_QUERY 1 // Query didn't return tuples
38 #define DB_TUPLES_OK 2 // Query returned tuples
39 #define DB_ERROR 5
40 #define DB_BAD_RESPONSE 6
41 #define DB_UNEXPECTED 7 // This shouldn't ever happen
42 #define DB_UNEXPECTED_RESULT -1 //For integer functions
43 
44 /******************* Class Database definition ********************
45 
46  represents connection with database server;
47 
48 ******************************************************************/
49 class Database
50 {
51 protected:
52  bool active;
53  bool compression;
54  std::string error, // Error description
55  host, port, db, login, passwd, //Login info
56  sequence_table, //Sequence table for nextid
57  default_charset, //Default character set
58  key, cert, ca, capath, ciphers; //SSL - Encryption info
59 
60 public:
61  /* constructor */
62  Database();
63  /* destructor */
64  virtual ~Database();
65  virtual Dataset* CreateDataset() const = 0;
66  /* sets a new host name */
67  virtual void setHostName(const char* newHost) { host = newHost; }
68  /* gets a host name */
69  const char* getHostName(void) const { return host.c_str(); }
70  /* sets a new port */
71  void setPort(const char* newPort) { port = newPort; }
72  /* gets a port */
73  const char* getPort(void) const { return port.c_str(); }
74  /* sets a new database name */
75  virtual void setDatabase(const char* newDb) { db = newDb; }
76  /* gets a database name */
77  const char* getDatabase(void) const { return db.c_str(); }
78  /* sets a new login to database */
79  void setLogin(const char* newLogin) { login = newLogin; }
80  /* gets a login */
81  const char* getLogin(void) const { return login.c_str(); }
82  /* sets a password */
83  void setPasswd(const char* newPasswd) { passwd = newPasswd; }
84  /* gets a password */
85  const char* getPasswd(void) const { return passwd.c_str(); }
86  /* active status is OK state */
87  virtual bool isActive(void) const { return active; }
88  /* Set new name of sequence table */
89  void setSequenceTable(const char* new_seq_table) { sequence_table = new_seq_table; }
90  /* Get name of sequence table */
91  const char* getSequenceTable(void) { return sequence_table.c_str(); }
92  /* Get the default character set */
93  const char* getDefaultCharset(void) { return default_charset.c_str(); }
94  /* Sets configuration */
95  virtual void setConfig(const char* newKey,
96  const char* newCert,
97  const char* newCA,
98  const char* newCApath,
99  const char* newCiphers,
100  bool newCompression)
101  {
102  key = newKey;
103  cert = newCert;
104  ca = newCA;
105  capath = newCApath;
106  ciphers = newCiphers;
107  compression = newCompression;
108  }
109 
110  /* virtual methods that must be overloaded in derived classes */
111 
112  virtual int init(void) { return DB_COMMAND_OK; }
113  virtual int status(void) { return DB_CONNECTION_NONE; }
114  virtual int setErr(int err_code, const char* qry) = 0;
115  virtual const char* getErrorMsg(void) { return error.c_str(); }
116 
117  virtual int connect(bool create) { return DB_COMMAND_OK; }
118  virtual int connectFull(const char* newDb,
119  const char* newHost = NULL,
120  const char* newLogin = NULL,
121  const char* newPasswd = NULL,
122  const char* newPort = NULL,
123  const char* newKey = NULL,
124  const char* newCert = NULL,
125  const char* newCA = NULL,
126  const char* newCApath = NULL,
127  const char* newCiphers = NULL,
128  bool newCompression = false);
129  virtual void disconnect(void) { active = false; }
130  virtual int reset(void) { return DB_COMMAND_OK; }
131  virtual int create(void) { return DB_COMMAND_OK; }
132  virtual int drop(void) { return DB_COMMAND_OK; }
133  virtual long nextid(const char* seq_name) = 0;
134 
135  /* \brief copy database */
136  virtual int copy(const char* new_name) { return -1; }
137 
138  /* \brief drop all extra analytics from database */
139  virtual int drop_analytics(void) { return -1; }
140 
141  virtual bool exists(void) { return false; }
142 
143  /* virtual methods for transaction */
144 
145  virtual void start_transaction() {}
146  virtual void commit_transaction() {}
147  virtual void rollback_transaction() {}
148 
149  /* virtual methods for formatting */
150 
156  virtual std::string prepare(const char* format, ...);
157 
163  virtual std::string vprepare(const char* format, va_list args) = 0;
164 
165  virtual bool in_transaction() { return false; }
166 };
167 
168 /******************* Class Dataset definition *********************
169 
170  global abstraction for using Databases
171 
172 ******************************************************************/
173 
174 // define Dataset States type
175 enum dsStates
176 {
177  dsSelect,
178  dsInsert,
179  dsEdit,
180  dsUpdate,
181  dsDelete,
182  dsInactive
183 };
184 enum sqlType
185 {
186  sqlSelect,
187  sqlUpdate,
188  sqlInsert,
189  sqlDelete,
190  sqlExec
191 };
192 
193 typedef std::list<std::string> StringList;
194 typedef std::map<std::string, field_value> ParamList;
195 
196 class Dataset
197 {
198 protected:
199  /* char *Host = ""; //WORK_HOST;
200  char *Database = ""; //WORK_DATABASE;
201  char *User = ""; //WORK_USER;
202  char *Password = ""; //WORK_PASSWORD;
203 */
204 
205  Database* db; // info about db connection
206  dsStates ds_state; // current state
207  Fields *fields_object, *edit_object;
208  std::unordered_map<std::string, unsigned int>
209  name2indexMap; // Lower case field name -> database index
210 
211  /* query results*/
212  result_set result;
213  result_set exec_res;
214  bool autorefresh;
215 
216  bool active; // Is Query Opened?
217  bool haveError;
218  int frecno; // number of current row bei bewegung
219  std::string sql;
220 
221  ParamList plist; // Paramlist for locate
222  bool fbof, feof;
223  bool autocommit; // for transactions
224 
225  /* Variables to store SQL statements */
226  std::string empty_sql; // Executed when result set is empty
227  std::string select_sql; // May be only single string variable
228 
229  StringList update_sql; // May be an array in complex queries
230  /* Field values for updating must has prefix :NEW_ and :OLD_ and field name
231  Example:
232  update wt_story set idobject set idobject=:NEW_idobject,body=:NEW_body
233  where idobject=:OLD_idobject
234  Essentially fields idobject and body must present in the
235  result set (select_sql statement) */
236 
237  StringList insert_sql; // May be an array in complex queries
238  /* Field values for inserting must has prefix :NEW_ and field name
239  Example:
240  insert into wt_story (idobject, body) values (:NEW_idobject, :NEW_body)
241  Essentially fields idobject and body must present in the
242  result set (select_sql statement) */
243 
244  StringList delete_sql; // May be an array in complex queries
245  /* Field values for deleing must has prefix :OLD_ and field name
246  Example:
247  delete from wt_story where idobject=:OLD_idobject
248  Essentially field idobject must present in the
249  result set (select_sql statement) */
250 
251  /* Arrays for searching */
252  // StringList names, values;
253 
254  /* Makes direct inserts into database via mysql_query function */
255  virtual void make_insert() = 0;
256  /* Edit SQL */
257  virtual void make_edit() = 0;
258  /* Delete SQL */
259  virtual void make_deletion() = 0;
260 
261  /* This function works only with MySQL database
262  Filling the fields information from select statement */
263  virtual void fill_fields(void) = 0;
264 
265  /* Parse Sql - replacing fields with prefixes :OLD_ and :NEW_ with current values of OLD or NEW field. */
266  void parse_sql(std::string& sql);
267 
268  /* Returns old field value (for :OLD) */
269  virtual field_value f_old(const char* f);
270 
271  /* fast string tolower helper */
272  char* str_toLower(char* s);
273 
274 public:
275  /* constructor */
276  Dataset();
277  explicit Dataset(Database* newDb);
278 
279  /* destructor */
280  virtual ~Dataset();
281 
282  /* sets a new value of connection to database */
283  void setDatabase(Database* newDb) { db = newDb; }
284  /* retrieves a database which connected */
285  Database* getDatabase(void) { return db; }
286 
287  /* sets a new query string to database server */
288  void setExecSql(const char* newSql) { sql = newSql; }
289  /* retrieves a query string */
290  const char* getExecSql(void) { return sql.c_str(); }
291 
292  /* status active is OK query */
293  virtual bool isActive(void) { return active; }
294 
295  virtual void setSqlParams(sqlType t, const char* sqlFrmt, ...);
296 
297  /* error handling */
298  // virtual void halt(const char *msg);
299 
300  /* last inserted id */
301  virtual int64_t lastinsertid() = 0;
302  /* sequence numbers */
303  virtual long nextid(const char* seq_name) = 0;
304  /* sequence numbers */
305  virtual int num_rows() = 0;
306 
307  /* Open SQL query */
308  virtual void open(const std::string& sql) = 0;
309  virtual void open() = 0;
310  /* func. executes a query without results to return */
311  virtual int exec(const std::string& sql) = 0;
312  virtual int exec() = 0;
313  virtual const void* getExecRes() = 0;
314  /* as open, but with our query exec Sql */
315  virtual bool query(const std::string& sql) = 0;
316  /* Close SQL Query*/
317  virtual void close();
318  /* This function looks for field Field_name with value equal Field_value
319  Returns true if found (position of dataset is set to founded position)
320  and false another way (position is not changed). */
321  // virtual bool lookup(char *field_name, char*field_value);
322  /* Refresh dataset (reopen it and set the same cursor position) */
323  virtual void refresh();
324 
330  virtual bool dropIndex(const char* table, const char* index) { return false; }
331 
332  /* Go to record No (starting with 0) */
333  virtual bool seek(int pos = 0);
334  /* Go to record No (starting with 1) */
335  virtual bool goto_rec(int pos = 1);
336  /* Go to the first record in dataset */
337  virtual void first();
338  /* Go to next record in dataset */
339  virtual void next();
340  /* Go to previous record */
341  virtual void prev();
342  /* Go to last record in dataset */
343  virtual void last();
344 
345  /* Check for Ending dataset */
346  virtual bool eof(void) { return feof; }
347  /* Check for Beginning dataset */
348  virtual bool bof(void) { return fbof; }
349 
350  /* Start the insert mode */
351  virtual void insert();
352  /* Start the insert mode (alias for insert() function) */
353  virtual void append() { insert(); }
354  /* Start the edit mode */
355  virtual void edit();
356  /* Start the delete mode */
357  virtual void del();
358 
359  /* Add changes, that were made during insert or edit states of dataset into the database */
360  virtual void post();
361  /* Delete statements from database */
362  virtual void deletion();
363  /* Cancel changes, made in insert or edit states of dataset */
364  virtual void cancel() {}
365  /* interrupt any pending database operation */
366  virtual void interrupt() {}
367 
368  virtual void setParamList(const ParamList& params);
369  virtual bool locate();
370  virtual bool locate(const ParamList& params);
371  virtual bool findNext();
372 
373  /* func. retrieves a number of fields */
374  /* Number of fields in a record */
375  virtual int field_count();
376  virtual int fieldCount();
377  /* func. retrieves a field name with 'n' index */
378  virtual const char* fieldName(int n);
379  /* func. retrieves a field index with 'fn' field name,return -1 when field name not found */
380  virtual int fieldIndex(const char* fn);
381 
382  /* Set field value */
383  virtual bool set_field_value(const char* f_name, const field_value& value);
384  /* alias for set_field_value */
385  virtual bool sf(const char* f, const field_value& v) { return set_field_value(f, v); }
386 
387  /* Return field name by it index */
388  // virtual char *field_name(int f_index) { return field_by_index(f_index)->get_field_name(); }
389 
390  /* Getting value of field for current record */
391  virtual const field_value& get_field_value(const char* f_name);
392  virtual const field_value& get_field_value(int index);
393  /* Alias to get_field_value */
394  const field_value& fv(const char* f) { return get_field_value(f); }
395  const field_value& fv(int index) { return get_field_value(index); }
396 
397  /* ------------ for transaction ------------------- */
398  void set_autocommit(bool v) { autocommit = v; }
399  bool get_autocommit() { return autocommit; }
400 
401  /* ----------------- for debug -------------------- */
402  Fields* get_fields_object() { return fields_object; }
403  Fields* get_edit_object() { return edit_object; }
404 
405  /* --------------- for fast access ---------------- */
406  const result_set& get_result_set() { return result; }
407  const sql_record* get_sql_record();
408 
409 private:
410  Dataset(const Dataset&) = delete;
411  Dataset& operator=(const Dataset&) = delete;
412 
413  /* Get the column index from a string field_value request */
414  bool get_index_map_entry(const char* f_name);
415 
416  void set_ds_state(dsStates new_state) { ds_state = new_state; }
417 
418 public:
419  /* return ds_state value */
420  dsStates get_state() { return ds_state; }
421 
422  /*add a new value to select_sql*/
423  void set_select_sql(const char* sel_sql);
424  void set_select_sql(const std::string& select_sql);
425  /*add a new value to update_sql*/
426  void add_update_sql(const char* upd_sql);
427  void add_update_sql(const std::string& upd_sql);
428  /*add a new value to insert_sql*/
429  void add_insert_sql(const char* ins_sql);
430  void add_insert_sql(const std::string& ins_sql);
431  /*add a new value to delete_sql*/
432  void add_delete_sql(const char* del_sql);
433  void add_delete_sql(const std::string& del_sql);
434 
435  /*clear update_sql*/
436  void clear_update_sql();
437  /*clear insert_sql*/
438  void clear_insert_sql();
439  /*clear delete_sql*/
440  void clear_delete_sql();
441 
442  /* size of insert_sql*/
443  size_t insert_sql_count();
444  /* size of delete_sql*/
445  size_t delete_sql_count();
446 
447  /*get value of select_sql*/
448  const char* get_select_sql();
449 };
450 
451 /******************** Class DbErrors definition *********************
452 
453  error handling
454 
455 ******************************************************************/
456 class DbErrors
457 {
458 
459 public:
460  /* constructor */
461  DbErrors();
462  DbErrors(const char* msg, ...);
463 
464  const char* getMsg();
465 
466 private:
467  std::string msg_;
468 };
469 
470 } // namespace dbiplus
virtual bool dropIndex(const char *table, const char *index)
Drop an index from the database table, provided it exists.
Definition: dataset.h:330
Definition: Database.h:11
virtual std::string prepare(const char *format,...)
Prepare a SQL statement for execution or querying using C printf nomenclature.
Definition: dataset.cpp:73
Definition: LibInputPointer.h:13
Definition: qry_dat.h:46
Definition: dataset.h:456
virtual std::string vprepare(const char *format, va_list args)=0
Prepare a SQL statement for execution or querying using C printf nomenclature.
Definition: qry_dat.h:255
Definition: dataset.h:196
Definition: dataset.h:49