[Test] Added tests for CUtil::SplitParams
[xbmc.git] / xbmc / dbwrappers / dataset.h
blob03ced6394a346fc45b9ba03ddec5bf01ac67bd4a
1 /*
2 * Copyright (C) 2002, Leo Seib, Hannover
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
9 * SPDX-License-Identifier: MIT
10 * See LICENSES/README.md for more information.
13 #pragma once
15 #include "qry_dat.h"
17 #include <cstdio>
18 #include <list>
19 #include <map>
20 #include <stdarg.h>
21 #include <string>
22 #include <unordered_map>
24 namespace dbiplus
26 class Dataset; // forward declaration of class Dataset
28 #define S_NO_CONNECTION "No active connection";
30 #define DB_BUFF_MAX 8 * 1024 // Maximum buffer's capacity
32 #define DB_CONNECTION_NONE 0
33 #define DB_CONNECTION_OK 1
34 #define DB_CONNECTION_BAD 2
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
44 /******************* Class Database definition ********************
46 represents connection with database server;
48 ******************************************************************/
49 class Database
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
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)
102 key = newKey;
103 cert = newCert;
104 ca = newCA;
105 capath = newCApath;
106 ciphers = newCiphers;
107 compression = newCompression;
110 /* virtual methods that must be overloaded in derived classes */
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(); }
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;
135 /* \brief copy database */
136 virtual int copy(const char* new_name) { return -1; }
138 /* \brief drop all extra analytics from database */
139 virtual int drop_analytics(void) { return -1; }
141 virtual bool exists(void) { return false; }
143 /* virtual methods for transaction */
145 virtual void start_transaction() {}
146 virtual void commit_transaction() {}
147 virtual void rollback_transaction() {}
149 /* virtual methods for formatting */
151 /*! \brief Prepare a SQL statement for execution or querying using C printf nomenclature.
152 \param format - C printf compliant format string
153 \param ... - optional comma separated list of variables for substitution in format string placeholders.
154 \return escaped and formatted string.
156 virtual std::string prepare(const char* format, ...);
158 /*! \brief Prepare a SQL statement for execution or querying using C printf nomenclature
159 \param format - C printf compliant format string
160 \param args - va_list of variables for substitution in format string placeholders.
161 \return escaped and formatted string.
163 virtual std::string vprepare(const char* format, va_list args) = 0;
165 virtual bool in_transaction() { return false; }
168 /******************* Class Dataset definition *********************
170 global abstraction for using Databases
172 ******************************************************************/
174 // define Dataset States type
175 enum dsStates
177 dsSelect,
178 dsInsert,
179 dsEdit,
180 dsUpdate,
181 dsDelete,
182 dsInactive
184 enum sqlType
186 sqlSelect,
187 sqlUpdate,
188 sqlInsert,
189 sqlDelete,
190 sqlExec
193 typedef std::list<std::string> StringList;
194 typedef std::map<std::string, field_value> ParamList;
196 class Dataset
198 protected:
199 /* char *Host = ""; //WORK_HOST;
200 char *Database = ""; //WORK_DATABASE;
201 char *User = ""; //WORK_USER;
202 char *Password = ""; //WORK_PASSWORD;
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
211 /* query results*/
212 result_set result;
213 result_set exec_res;
214 bool autorefresh;
216 bool active; // Is Query Opened?
217 bool haveError;
218 int frecno; // number of current row bei bewegung
219 std::string sql;
221 ParamList plist; // Paramlist for locate
222 bool fbof, feof;
223 bool autocommit; // for transactions
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
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) */
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) */
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) */
251 /* Arrays for searching */
252 // StringList names, values;
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;
261 /* This function works only with MySQL database
262 Filling the fields information from select statement */
263 virtual void fill_fields(void) = 0;
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);
268 /* Returns old field value (for :OLD) */
269 virtual field_value f_old(const char* f);
271 /* fast string tolower helper */
272 char* str_toLower(char* s);
274 public:
275 /* constructor */
276 Dataset();
277 explicit Dataset(Database* newDb);
279 /* destructor */
280 virtual ~Dataset();
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; }
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(); }
292 /* status active is OK query */
293 virtual bool isActive(void) { return active; }
295 virtual void setSqlParams(sqlType t, const char* sqlFrmt, ...);
297 /* error handling */
298 // virtual void halt(const char *msg);
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;
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();
325 /*! \brief Drop an index from the database table, provided it exists.
326 \param table - name of the table the index to be dropped is associated with
327 \param index - name of the index to be dropped
328 \return true when the index is guaranteed to no longer exist in the database.
330 virtual bool dropIndex(const char* table, const char* index) { return false; }
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();
345 /* Check for Ending dataset */
346 virtual bool eof(void) { return feof; }
347 /* Check for Beginning dataset */
348 virtual bool bof(void) { return fbof; }
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();
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() {}
368 virtual void setParamList(const ParamList& params);
369 virtual bool locate();
370 virtual bool locate(const ParamList& params);
371 virtual bool findNext();
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);
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); }
387 /* Return field name by it index */
388 // virtual char *field_name(int f_index) { return field_by_index(f_index)->get_field_name(); }
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); }
397 /* ------------ for transaction ------------------- */
398 void set_autocommit(bool v) { autocommit = v; }
399 bool get_autocommit() { return autocommit; }
401 /* ----------------- for debug -------------------- */
402 Fields* get_fields_object() { return fields_object; }
403 Fields* get_edit_object() { return edit_object; }
405 /* --------------- for fast access ---------------- */
406 const result_set& get_result_set() { return result; }
407 const sql_record* get_sql_record();
409 private:
410 Dataset(const Dataset&) = delete;
411 Dataset& operator=(const Dataset&) = delete;
413 /* Get the column index from a string field_value request */
414 bool get_index_map_entry(const char* f_name);
416 void set_ds_state(dsStates new_state) { ds_state = new_state; }
418 public:
419 /* return ds_state value */
420 dsStates get_state() { return ds_state; }
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);
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();
442 /* size of insert_sql*/
443 size_t insert_sql_count();
444 /* size of delete_sql*/
445 size_t delete_sql_count();
447 /*get value of select_sql*/
448 const char* get_select_sql();
451 /******************** Class DbErrors definition *********************
453 error handling
455 ******************************************************************/
456 class DbErrors
459 public:
460 /* constructor */
461 DbErrors();
462 DbErrors(const char* msg, ...);
464 const char* getMsg();
466 private:
467 std::string msg_;
470 } // namespace dbiplus