NCBI C++ ToolKit
sqlitewrapp.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef DB_SQLITE_SQLITEWRAPP__HPP
2 #define DB_SQLITE_SQLITEWRAPP__HPP
3 /* $Id: sqlitewrapp.hpp 84779 2018-12-11 15:51:54Z grichenk $
4  * ===========================================================================
5  *
6  * PUBLIC DOMAIN NOTICE
7  * National Center for Biotechnology Information
8  *
9  * This software/database is a "United States Government Work" under the
10  * terms of the United States Copyright Act. It was written as part of
11  * the author's official duties as a United States Government employee and
12  * thus cannot be copyrighted. This software/database is freely available
13  * to the public for use. The National Library of Medicine and the U.S.
14  * Government have not placed any restriction on its use or reproduction.
15  *
16  * Although all reasonable efforts have been taken to ensure the accuracy
17  * and reliability of the software and data, the NLM and the U.S.
18  * Government do not and cannot warrant the performance or results that
19  * may be obtained by using this software or data. The NLM and the U.S.
20  * Government disclaim all warranties, express or implied, including
21  * warranties of performance, merchantability or fitness for any particular
22  * purpose.
23  *
24  * Please cite the author in any work or product based on this material.
25  *
26  * ===========================================================================
27  *
28  * Authors: Pavel Ivanov
29  *
30  * File Description:
31  * Convenient wrappers for SQLite-related objects and most commonly used
32  * functions. Wrappers require SQLite 3.6.14 or higher with async vfs
33  * extension. All wrappers are written in assumption that no one else calls
34  * any sqlite3* functions except the wrapper itself.
35  */
36 
37 #include <corelib/ncbiexpt.hpp>
38 #include <corelib/ncbimisc.hpp>
39 #include <corelib/ncbistr.hpp>
40 #include <corelib/ncbimtx.hpp>
41 #include <corelib/ncbi_system.hpp>
42 #include <corelib/obj_pool.hpp>
43 
44 #include <sqlite3.h>
45 #ifdef HAVE_SQLITE3ASYNC_H
46 # include <sqlite3async.h>
47 #endif
48 
49 #include <deque>
50 
51 
53 
54 
55 class CSQLITE_Exception;
56 class CSQLITE_Connection;
57 class CSQLITE_Statement;
58 class CSQLITE_Blob;
59 
60 
61 /// Utility class for some global-purpose functions tuning SQLite as a whole
62 /// as opposed to tuning connection-by-connection.
64 {
65 public:
66  /// Install non-default cache for all SQLite databases. Can be useful
67  /// if default policy of working with cache is inappropriate for your
68  /// application. For more details on sqlite3_pcache_methods look into
69  /// comments before it in sqlite3.h.
70  /// Method can be called only before SQLite is initialized with
71  /// Initialize() method.
72  static void SetCustomPageCache(sqlite3_pcache_methods* methods);
73 
74  /// Initialization of SQLite and tuning some default parameters.
75  /// For these SQLite wrappers to work properly this method should be
76  /// called before any work with other classes.
77  static void Initialize(void);
78  /// Finish all SQLite operations. Method should be called at the end of
79  /// application execution. After it has been called any further attempts
80  /// to use wrapper classes will likely cause application crash.
81  static void Finalize(void);
82 
83  /// Enable use of the same cache by different connections to the same
84  /// database file. Setting can be changed at any time and will affect all
85  /// connections opened after changing.
86  static void EnableSharedCache(bool enable = true);
87  /// Get default virtual file system installed in SQLite.
88  /// Method can be called only after SQLite is initialized with
89  /// Initialize() method.
90  static sqlite3_vfs* GetDefaultVFS(void);
91  /// Register new virtual file system in SQLite.
92  /// If set_default is TRUE then all connections that will be opened after
93  /// call to this method will use this virtual file system. When
94  /// set_default is FALSE then connections will have to state explicitly
95  /// if they want to use this new vfs (although for now this functionality
96  /// is not yet implemented in CSQLITE_Connection).
97  /// Method can be called only after SQLite is initialized with
98  /// Initialize() method.
99  static void RegisterCustomVFS(sqlite3_vfs* vfs, bool set_default = true);
100 
101 #ifdef HAVE_SQLITE3ASYNC_H
102  /// Setup the option for asynchronous file system to do the actual locking
103  /// of database files on disk. If lock_files is TRUE then files will be
104  /// actually locked on hard disk, if it is FALSE files will not be locked
105  /// and so consistency of access to databases opened with asynchronous
106  /// writing flag set will be maintained only inside current process.
107  /// Method should be called only when there's no connections opened.
108  static void SetAsyncWritesFileLocking(bool lock_files);
109  /// Launch background thread doing all asynchronous writes to databases.
110  /// Method is no-op if background thread has already launched.
111  static void RunAsyncWritesThread(void);
112 #endif // HAVE_SQLITE3ASYNC_H
113 
114 private:
118 };
119 
120 
121 /// Object factory creating sqlite3* handles.
122 /// For internal use in CSQLITE_Connection's internal pool.
124 {
125 public:
127 
128  /// Create new database handle
129  sqlite3* CreateObject(void);
130 
131  /// Destroy database handle
132  void DeleteObject(sqlite3* handle);
133 
134 private:
135  /// Connection object this factory is bound to
137 };
138 
139 
140 /// Connection to SQLite database.
142 {
143 public:
144  /// Flags controlling specifics of database connection operation.
145  /// Only one flag can be used in each group of flags (separated by
146  /// comments).
148  // Mode of operation in multi-threaded environment
149  fInternalMT = 0x00, ///< Object and all statements and blobs created
150  ///< on top of it should support internal
151  ///< synchronization between different threads
152  fExternalMT = 0x01, ///< Object and all statements and blobs created
153  ///< on top of it will not be used from different
154  ///< threads simultaneously, thus performance is
155  ///< optimized, object creates only one low-level
156  ///< SQLite connection
157  /// Default value for multi-threading group of flags
160 
161  // Mode of vacuuming and shrinking file size
162  fVacuumOn = 0x00, ///< Vacuuming is on, database file has always
163  ///< the minimum size possible
164  fVacuumOff = 0x02, ///< Vacuuming is off, database file can only
165  ///< grow
166  fVacuumManual = 0x04, ///< Vacuuming is only by request
167  /// Default value for vacuuming group of flags
170 
171  // Mode of journaling of all transactions
172  fJournalDelete = 0x00, ///< Journal on disk, journal file is
173  ///< deleted after each transaction
174  fJournalTruncate = 0x08, ///< Journal on disk, size of journal file
175  ///< is nullified after each transaction
176  fJournalPersist = 0x10, ///< Journal on disk, journal file can only
177  ///< grow, never shrinks
178  fJournalMemory = 0x20, ///< Journaling is entirely in-memory
179  fJournalOff = 0x40, ///< Journaling is completely off (not
180  ///< recommended - transactions cannot be
181  ///< rollbacked unless they consist of just
182  ///< one simple operation)
183  /// Default value for journaling group of flags
187 
188  // Mode of reliable synchronization with disk database file
189  fSyncFull = 0x000, ///< Full synchronization, database cannot be
190  ///< corrupted
191  fSyncOn = 0x080, ///< Synchronization is on, there is a slight
192  ///< chance of database corruption when
193  ///< OS crashes
194  fSyncOff = 0x100, ///< Synchronization is off, database can be
195  ///< corrupted on OS crash or power outage
196  /// Default value for synchronization group of flags
199 
200  /// Mode of storing temporary data
201  fTempToMemory = 0x000, ///< Store all temporary tables in memory
202  fTempToFile = 0x200, ///< Use actual disk file for temporary
203  ///< storage
204  /// Default value for "temporary" group of flags
207 
208  /// Mode of doing all writes to the database
209  fWritesSync = 0x000, ///< All writes are synchronous - when update
210  ///< has executed data is already in file
211  ///< (though @sa fSyncOff)
212 #ifdef HAVE_SQLITE3ASYNC_H
213  fWritesAsync = 0x400, ///< All writes are asynchronous - updates
214  ///< return as quick as they can, actual
215  ///< writes to database happen in background
216  ///< thread (@sa
217  ///< CSQLITE_Global::RunAsyncWritesThread)
218 #endif
219  /// Default value for writes mode group of flags
222 #ifdef HAVE_SQLITE3ASYNC_H
223  + fWritesAsync
224 #endif
225  ,
226 
227  fReadOnly = 0x8000, ///< The DB is read-only. Also forces fVacuumOff flag.
228 
229  /// Default value of all flags
232  };
233  /// Bit mask of EOperationFlags
234  typedef int TOperationFlags;
235 
236  /// Connect to SQLite database.
237  /// NOTE: Vacuuming flags have any value here only when new database is
238  /// created. When old database is opened with some data in it
239  /// then vacuuming flags are no-op, flags used at creation are in
240  /// effect.
241  /// NOTE: Connection should be destroyed after all statements or blobs
242  /// created on top of it. destroying statements after connection
243  /// was destroyed will result in segmentation fault.
244  ///
245  /// @param file_name
246  /// File name of SQLite database. If it doesn't exist it will be
247  /// created. If directory for file doesn't exist exception will be
248  /// thrown. If file name is empty connection to temporary file will be
249  /// open. This file will be deleted after connection is closed. If file
250  /// name is ":memory:" then connection to in-memory database will be
251  /// open. In both cases (temporary file and in-memory database) flag
252  /// fExternalMT should be set (it is not checked but you will get
253  /// malfunctioning otherwise).
254  /// @param flags
255  /// Flags for object operations
258  ~CSQLITE_Connection(void);
259 
260  /// Get database file name for the connection
261  const string& GetFileName(void) const;
262  /// Get flags controlling database connection operation
263  TOperationFlags GetFlags (void) const;
264  /// Change flags controlling database connection operation.
265  /// NOTE: Vacuuming flags cannot be changed here. New flags will be
266  /// applied only to newly created low-level SQLite connections.
267  /// Thus in fInternalMT mode it is recommended to destroy all
268  /// CSQLITE_Statement and CSQLITE_Blob objects before changing
269  /// flags. In fExternalMT mode this cleaning of statements is
270  /// mandatory - you will get memory and other resources leak
271  /// otherwise.
273  /// Set page size for the database (in bytes). Setting has any value only
274  /// if database is empty (has no tables) and no statements are created
275  /// yet. Page size should be power of 2 and be less than or equal to
276  /// 32768. If page size is not set default value is used.
277  void SetPageSize(unsigned int size);
278  /// Get page size used in the database (in bytes)
279  unsigned int GetPageSize(void);
280  /// Set recommended size of the database cache (number of pages). If value
281  /// is not set or set to 0 then default SQLite value is used.
282  void SetCacheSize(unsigned int size);
283  /// Get recommended size of the database cache. If cache size was not set
284  /// by SetCacheSize() method then this method returns 0, though actually
285  /// SQLite uses some default value.
286  unsigned int GetCacheSize(void);
287 
288  /// Try to shrink database and free up to max_free_size bytes of disk
289  /// space. Method is no-op when vacuum mode is other than fVacuumManual.
290  ///
291  /// @sa EOperationFlags
292  void Vacuum(size_t max_free_size);
293  /// Create statement for executing manual vacuuming.
294  /// Caller is responsible for deleting returned statement object.
295  ///
296  /// @sa Vacuum
297  CSQLITE_Statement* CreateVacuumStmt(size_t max_free_size);
298 
299  /// Execute sql statement without returning any results.
300  void ExecuteSql(CTempString sql);
301  /// Delete database under this connection. Method makes sure that journal
302  /// file is deleted along with database file itself. All CSQLITE_Statement
303  /// and CSQLITE_Blob objects on this connection should be deleted before
304  /// call to this method. Any use of connection after call to this method
305  /// will cause the database file to be created again.
306  void DeleteDatabase(void);
307 
308  /// Create a read-only copy of the database in memory.
309  /// The in-memory database is never synchronized with the original file.
310  /// If 'shared' is true, a single copy of in-memory database is used.
311  /// Otherwise each call to the function creates a new database and
312  /// the returned connection is the only way to access it.
313  /// On error return NULL.
315  bool shared = false);
316 
317 public:
318  // For internal use only
319 
320  /// Lock and return low-level connection handle
321  sqlite3* LockHandle(void);
322  /// Unlock unused low-level connection handle. This handle will be used
323  /// later by some other statement. Essentially no-op in eExternalMT mode.
324  ///
325  /// @sa EMultiThreadMode
326  void UnlockHandle(sqlite3* handle);
327  /// Setup newly created low-level connection handle.
328  /// Executes all necessary pragmas according to operation flags set.
329  void SetupNewConnection(sqlite3* handle);
330 
331 private:
334 
335  /// Check that only one flag in specific group of flags is given
337  /// Execute sql statement on given low-level connection handle
338  void x_ExecuteSql(sqlite3* handle, CTempString sql);
339 
340 
342 
343  /// File name of SQLite database
344  string m_FileName;
345  /// Flags for object operation
347  /// Page size inside the database
348  unsigned int m_PageSize;
349  /// Recommended size of cache for the database
350  unsigned int m_CacheSize;
351  /// Pool of low-level database connections
353  // In-memory database can not use handle pool. The only handle
354  // is locked for the whole database life.
355  sqlite3* m_InMemory;
356 };
357 
358 
359 /// SQL statement executing on SQLite database
361 {
362 public:
363  /// Create and prepare statement for given database connection.
364  /// If sql is empty nothing is prepared in the constructor.
366  /// Create and prepare statement for particular low-level connection.
367  /// If sql is empty nothing is prepared in the constructor.
368  CSQLITE_Statement(sqlite3* conn_handle, CTempString sql = kEmptyStr);
370 
371  /// Change sql text for the object and prepare new statement
372  void SetSql(CTempString sql);
373 
374  /// Bind integer value to parameter index.
375  /// Parameters' numbers start from 1.
376  void Bind (int index, int val);
377  /// Bind unsigned integer value to parameter index.
378  /// Parameters' numbers start from 1.
379  void Bind (int index, unsigned int val);
380  /// Bind integer value to parameter index.
381  /// Parameters' numbers start from 1.
382  void Bind (int index, long val);
383  /// Bind unsigned integer value to parameter index.
384  /// Parameters' numbers start from 1.
385  void Bind (int index, unsigned long val);
386 #if !NCBI_INT8_IS_LONG
387  /// Bind 64-bit integer value to parameter index.
388  /// Parameters' numbers start from 1.
389  void Bind (int index, Int8 val);
390  /// Bind unsigned 64-bit integer value to parameter index.
391  /// Parameters' numbers start from 1.
392  void Bind (int index, Uint8 val);
393 #endif
394  /// Bind double value to parameter index.
395  /// Parameters' numbers start from 1.
396  void Bind (int index, double val);
397  /// Bind text value to parameter index.
398  /// Parameters' numbers start from 1. Value of parameter is copied inside
399  /// the method so it may disappear after call.
400  void Bind (int index, CTempString val);
401  /// Bind text value to parameter index.
402  /// Parameters' numbers start from 1. Value of parameter is not copied,
403  /// pointer is remembered instead. So given value should exist until
404  /// statement is executed.
405  void Bind (int index, const char* data, size_t size);
406  /// Bind blob value to parameter index.
407  /// Parameters' numbers start from 1. Value of parameter is not copied,
408  /// pointer is remembered instead. So given value should exist until
409  /// statement is executed.
410  void Bind (int index, const void* data, size_t size);
411  /// Bind blob value of given size containing only zeros to parameter
412  /// index. Parameters' numbers start from 1.
413  void BindZeroedBlob(int index, size_t size);
414  /// Bind null value to parameter index.
415  void BindNull (int index);
416 
417  /// Execute statement without returning any result
418  void Execute(void);
419  /// Step through results of the statement.
420  /// If statement wasn't executed yet it starts executing. If statement
421  /// already returned some rows then it moves to the next row. Be aware
422  /// that when statement begins executing until it returns all rows or
423  /// is reseted the database is locked so that nobody else can write to it.
424  /// So it's recommended to step through all results as quick as possible.
425  ///
426  /// @return
427  /// TRUE if new row is available in the result.
428  /// FALSE if no more rows are available and thus statement finished
429  /// executing and released all locks held.
430  bool Step(void);
431  /// Reset the statement to release all locks and to be ready to execute
432  /// again.
433  void Reset(void);
434  /// Reset all bindings to the statement to their initial NULL values
435  void ClearBindings(void);
436 
437  /// Get number of columns in result set. Method should be executed only
438  /// after Step() returned TRUE, otherwise returned value is undefined.
439  int GetColumnsCount(void) const;
440  /// Get name of column at index col_ind in result set. The leftmost column
441  /// of result set has the index 0. Method should be executed only after
442  /// Step() returned TRUE, otherwise returned value is undefined.
443  CStringUTF8 GetColumnName(int col_ind) const;
444 
445  /// Get integer value from column col_ind in current row. The leftmost
446  /// column of result set has index 0. Method should be executed only
447  /// after Step() returned TRUE, otherwise returned value is undefined.
448  int GetInt (int col_ind) const;
449  /// Get 64-bit integer value from column col_ind in current row.
450  /// The leftmost column of result set has the index 0. Method should be
451  /// executed only after Step() returned TRUE, otherwise returned value is
452  /// undefined.
453  Int8 GetInt8 (int col_ind) const;
454  /// Get double value from column col_ind in current row. The leftmost
455  /// column of result set has the index 0. Method should be executed only
456  /// after Step() returned TRUE, otherwise returned value is undefined.
457  double GetDouble(int col_ind) const;
458  /// Get text value from column col_ind in current row. The leftmost
459  /// column of result set has the index 0. Method should be executed only
460  /// after Step() returned TRUE, otherwise returned value is undefined.
461  string GetString(int col_ind) const;
462  /// Get size of blob value from column col_ind in current row. The leftmost
463  /// column of result set has the index 0. Method should be executed only
464  /// after Step() returned TRUE, otherwise returned value is undefined.
465  size_t GetBlobSize(int col_ind) const;
466  /// Read blob value from column col_ind in current row. The leftmost
467  /// column of result set has the index 0. Method should be executed only
468  /// after Step() returned TRUE, otherwise returned value is undefined.
469  ///
470  /// @param col_ind
471  /// Index of column to read (left-most is 0)
472  /// @param buffer
473  /// Pointer to buffer where to write the data
474  /// @param size
475  /// Size of buffer available for writing
476  /// @return
477  /// Number of bytes read from result set and put into buffer
478  size_t GetBlob (int col_ind, void* buffer, size_t size) const;
479 
480  /// Get rowid of the row inserted in last statement execution.
481  /// If connection is working in eExternalMT mode then method should be
482  /// called after statement execution and before execution of any other
483  /// statement in the same connection. If last executed statement was not
484  /// insert then 0 is returned.
485  Int8 GetLastInsertedRowid(void) const;
486  /// Get number of rows changed during last insert, delete or update
487  /// statement. Number does not include rows changed by triggers or by
488  /// any other indirect means. If called when no insert, update or delete
489  /// statement was executed result is undefined.
490  int GetChangedRowsCount (void) const;
491 
492 private:
495 
496  /// Prepare new statement if it's not empty
497  void x_Prepare(CTempString sql);
498  /// Finalize current statement
499  void x_Finalize(void);
500 
501 
502  /// Connection this statement belongs to
504  /// Low-level connection handle provided for this statement
505  sqlite3* m_ConnHandle;
506  /// Low-level statement handle
507  sqlite3_stmt* m_StmtHandle;
508 };
509 
510 
511 /// "Scoped" statement activity object.
512 /// Object binds to some statement and ensures that by the end of the scope
513 /// statement will be reseted and all database locks will be released. Besides
514 /// that object acts as smart pointer to the statement.
516 {
517 public:
518  /// Bind activity control to the given statement
520 
522 
523  /// Smart pointer's transformation
525 
526  /// Smart pointer's transformation
528 
529  /// Smart pointer's transformation
530  operator CSQLITE_Statement* (void);
531 
532 private:
535 
536  /// Statement this object is bound to
538 };
539 
540 
541 // Structures for internal use only
542 template <bool readwrite> struct SSQLITE_BlobOpen;
543 struct SSQLITE_BlobClose;
544 
545 /// Object reading and writing blob directly (mostly without executing select
546 /// or update statements), can read and write blob incrementally.
547 /// Class assumes that from the moment of its creation till deletion nobody
548 /// else writes to the blob and/or changes its size.
550 {
551 public:
552  /// Create object reading and writing blob
553  /// Identified row with blob should exist in database, exception is
554  /// thrown otherwise.
555  ///
556  /// @param conn
557  /// Connection which object will work over
558  /// @param table
559  /// Table name where blob is located
560  /// @param column
561  /// Column name where blob is located
562  /// @param rowid
563  /// Rowid of the row where blob is located
567  Int8 rowid);
568  /// Create object reading and writing blob
569  /// Identified row with blob should exist in database, exception is
570  /// thrown otherwise.
571  ///
572  /// @param conn
573  /// Connection which object will work over
574  /// @param db_name
575  /// Database name where blob is located
576  /// @param table
577  /// Table name where blob is located
578  /// @param column
579  /// Column name where blob is located
580  /// @param rowid
581  /// Rowid of the row where blob is located
583  CTempString db_name,
586  Int8 rowid);
587  ~CSQLITE_Blob(void);
588 
589  /// Set current position inside the blob to desired value
590  void ResetPosition(size_t position = 0);
591  /// Get current position inside the blob
592  size_t GetPosition (void);
593  /// Get size of the blob
594  size_t GetSize(void);
595 
596  /// Read from blob at current position
597  ///
598  /// @param buffer
599  /// Pointer to buffer where to write read data
600  /// @param size
601  /// Size of buffer available for writing
602  /// @return
603  /// Number of bytes read from blob. If current position is beyond end
604  /// of the blob then 0 is returned and buffer is unchanged.
605  size_t Read (void* buffer, size_t size);
606  /// Write to blob at current position
607  ///
608  /// @param data
609  /// Pointer to data to write
610  /// @param size
611  /// Number of bytes to write
612  void Write (const void* data, size_t size);
613  /// Set statement to use when appending to existing blob if necessary.
614  /// Statement should be of the form
615  /// "update ... set ... = ...||?2 where rowid=?1"
616  /// If not set object creates its own statement on the first append.
617  /// Created statement is destroyed together with this blob object.
618  /// Statement set by this method is not destroyed with blob object.
619  /// This method can be useful if one wants to cache statement between
620  /// different blob objects creation and deletion to not prepare it with
621  /// each blob object.
623 
624 private:
627 
628  /// Initialize the object
629  void x_Init (void);
630  /// Open low-level blob object
631  ///
632  /// @param readwrite
633  /// TRUE if there's need for write access, FALSE if read-only access is
634  /// sufficient
635  void x_OpenBlob (bool readwrite = false);
636  /// Close low-level blob object
637  void x_CloseBlob(void);
638 
639  template <bool readwrite> friend struct SSQLITE_BlobOpen;
640  friend struct SSQLITE_BlobClose;
641 
642 
643  /// Connection this blob object belongs to
645  /// Low-level connection handle provided for this blob object
646  sqlite3* m_ConnHandle;
647  /// Statement used for appending to existing blob value
649  /// Database name for blob
650  string m_Database;
651  /// Table name for blob
652  string m_Table;
653  /// Column name for blob
654  string m_Column;
655  /// Rowid for the row where blob is located
657  /// Low-level handle of the blob
658  sqlite3_blob* m_BlobHandle;
659  /// Size of the blob
660  size_t m_Size;
661  /// Current position inside the blob
662  size_t m_Position;
663 };
664 
665 
666 /// Exception thrown from all SQLite-related objects and functions
668 {
669 public:
670  enum EErrCode {
671  eUnknown, ///< Unknown error
672  eWrongFlags, ///< Incorrect set of flags in connection constructor
673  eDBOpen, ///< Error during database opening
674  eStmtPrepare, ///< Error preparing statement
675  eStmtFinalize, ///< Error finalizing statement
676  eStmtBind, ///< Error binding statement parameters
677  eStmtStep, ///< Error stepping through the statement
678  eStmtReset, ///< Error reseting statement
679  eBlobOpen, ///< Error opening blob object
680  eBlobClose, ///< Error closing blob object
681  eBlobRead, ///< Error reading directly from blob
682  eBlobWrite, ///< Error writing directly to blob
683  eConstraint, ///< Constraint violation during statement execution
684  eDeadLock, ///< SQLite detected possible deadlock between
685  ///< different threads
686  eBadCall ///< Method called when there's no enough capabilities
687  ///< to finish it successfully
688  };
689  virtual const char* GetErrCodeString(void) const override;
691 };
692 
693 
694 
695 //////////////////////////////////////////////////////////////////////////
696 // Inline functions
697 //////////////////////////////////////////////////////////////////////////
698 
699 inline
702  : m_Conn(conn),
703  m_ConnHandle(NULL),
704  m_StmtHandle(NULL)
705 {
706  x_Prepare(sql);
707 }
708 
709 inline
712  : m_Conn(NULL),
713  m_ConnHandle(conn_handle),
714  m_StmtHandle(NULL)
715 {
716  x_Prepare(sql);
717 }
718 
719 inline void
721 {
722  x_Finalize();
723  x_Prepare(sql);
724 }
725 
726 inline void
728 {
729  while (Step())
730  {}
731 }
732 
733 inline void
735 {
736  // SQLite doesn't understand unsigned types anyway
737  Bind(index, static_cast<Int8>(val));
738 }
739 
740 #if !NCBI_INT8_IS_LONG
741 
742 inline void
743 CSQLITE_Statement::Bind(int index, long val)
744 {
745  Bind(index, static_cast<Int8>(val));
746 }
747 
748 inline void
749 CSQLITE_Statement::Bind(int index, unsigned long val)
750 {
751  Bind(index, static_cast<Uint8>(val));
752 }
753 
754 #endif
755 
756 inline void
757 CSQLITE_Statement::Bind(int index, int val)
758 {
759  Bind(index, static_cast<long>(val));
760 }
761 
762 inline void
763 CSQLITE_Statement::Bind(int index, unsigned int val)
764 {
765  Bind(index, static_cast<unsigned long>(val));
766 }
767 
768 inline int
770 {
772  return sqlite3_column_count(m_StmtHandle);
773 }
774 
775 inline int
776 CSQLITE_Statement::GetInt(int col_ind) const
777 {
779  return sqlite3_column_int(m_StmtHandle, col_ind);
780 }
781 
782 inline Int8
783 CSQLITE_Statement::GetInt8(int col_ind) const
784 {
786  return sqlite3_column_int64(m_StmtHandle, col_ind);
787 }
788 
789 inline double
791 {
793  return sqlite3_column_double(m_StmtHandle, col_ind);
794 }
795 
796 inline Int8
798 {
800  return sqlite3_last_insert_rowid(m_ConnHandle);
801 }
802 
803 inline int
805 {
807  return sqlite3_changes(m_ConnHandle);
808 }
809 
810 
811 inline const string&
813 {
814  return m_FileName;
815 }
816 
819 {
820  return m_Flags;
821 }
822 
823 inline unsigned int
825 {
826  return m_PageSize;
827 }
828 
829 inline void
831 {
832  m_PageSize = size;
834 }
835 
836 inline unsigned int
838 {
839  return m_CacheSize == (unsigned int)(-1) ? 0 : m_CacheSize;
840 }
841 
842 inline void
844 {
845  m_CacheSize = size;
847 }
848 
849 inline sqlite3*
851 {
852  if ( m_InMemory ) {
853  return m_InMemory;
854  }
855  sqlite3* result = m_HandlePool.Get();
856  if ((m_Flags & eAllMT) == fExternalMT) {
858  }
859  return result;
860 }
861 
862 inline void
864 {
865  if (m_InMemory && handle == m_InMemory) {
866  return;
867  }
868  if ((m_Flags & eAllMT) == fInternalMT) {
869  m_HandlePool.Return(handle);
870  }
871 }
872 
873 inline void
875 {
876  CSQLITE_Statement stmt(this, sql);
877  stmt.Execute();
878 }
879 
880 inline void
881 CSQLITE_Connection::Vacuum(size_t max_free_size)
882 {
884  stmt->Execute();
885 }
886 
887 
888 inline
890  : m_Stmt(stmt)
891 {
892  _ASSERT(stmt);
893 }
894 
895 inline CSQLITE_Statement&
897 {
898  return *m_Stmt;
899 }
900 
901 inline CSQLITE_Statement*
903 {
904  return m_Stmt;
905 }
906 
907 inline
908 CSQLITE_StatementLock::operator CSQLITE_Statement* (void)
909 {
910  return m_Stmt;
911 }
912 
913 
914 inline
916 {
917  x_CloseBlob();
918  if (m_ConnHandle) {
920  }
921 }
922 
923 inline size_t
925 {
926  return m_Position;
927 }
928 
929 inline void
930 CSQLITE_Blob::ResetPosition(size_t position /* = 0 */)
931 {
932  m_Position = position;
933 }
934 
935 inline void
937 {
939 }
940 
942 
943 #endif /* DB_SQLITE_SQLITEWRAPP__HPP */
ncbi::TMaskedQueryRegions mask
Object reading and writing blob directly (mostly without executing select or update statements),...
size_t GetPosition(void)
Get current position inside the blob.
size_t m_Size
Size of the blob.
Int8 m_Rowid
Rowid for the row where blob is located.
size_t Read(void *buffer, size_t size)
Read from blob at current position.
void x_CloseBlob(void)
Close low-level blob object.
void x_Init(void)
Initialize the object.
CSQLITE_Blob(const CSQLITE_Blob &)
sqlite3 * m_ConnHandle
Low-level connection handle provided for this blob object.
void Write(const void *data, size_t size)
Write to blob at current position.
void x_OpenBlob(bool readwrite=false)
Open low-level blob object.
CSQLITE_Connection * m_Conn
Connection this blob object belongs to.
~CSQLITE_Blob(void)
CSQLITE_Blob(CSQLITE_Connection *conn, CTempString table, CTempString column, Int8 rowid)
Create object reading and writing blob Identified row with blob should exist in database,...
void SetAppendStatement(CSQLITE_Statement *stmt)
Set statement to use when appending to existing blob if necessary.
size_t GetSize(void)
Get size of the blob.
string m_Column
Column name for blob.
sqlite3_blob * m_BlobHandle
Low-level handle of the blob.
CSQLITE_Blob & operator=(const CSQLITE_Blob &)
void ResetPosition(size_t position=0)
Set current position inside the blob to desired value.
string m_Database
Database name for blob.
string m_Table
Table name for blob.
size_t m_Position
Current position inside the blob.
AutoPtr< CSQLITE_Statement > m_AppendStmt
Statement used for appending to existing blob value.
Connection to SQLite database.
TOperationFlags m_Flags
Flags for object operation.
TOperationFlags GetFlags(void) const
Get flags controlling database connection operation.
int TOperationFlags
Bit mask of EOperationFlags.
EOperationFlags
Flags controlling specifics of database connection operation.
@ fDefaultWrites
Default value for writes mode group of flags.
@ fWritesAsync
All writes are asynchronous - updates return as quick as they can, actual writes to database happen i...
@ fDefaultSync
Default value for synchronization group of flags.
@ fTempToFile
Use actual disk file for temporary storage.
@ fJournalTruncate
Journal on disk, size of journal file is nullified after each transaction.
@ fJournalPersist
Journal on disk, journal file can only grow, never shrinks.
@ fExternalMT
Object and all statements and blobs created on top of it will not be used from different threads simu...
@ fVacuumOn
Vacuuming is on, database file has always the minimum size possible.
@ fDefaultVacuum
Default value for vacuuming group of flags.
@ fJournalOff
Journaling is completely off (not recommended - transactions cannot be rollbacked unless they consist...
@ eDefaultFlags
Default value of all flags.
@ fInternalMT
Object and all statements and blobs created on top of it should support internal synchronization betw...
@ fSyncOff
Synchronization is off, database can be corrupted on OS crash or power outage.
@ fReadOnly
The DB is read-only. Also forces fVacuumOff flag.
@ fSyncFull
Full synchronization, database cannot be corrupted.
@ fVacuumManual
Vacuuming is only by request.
@ fDefaultTemp
Default value for "temporary" group of flags.
@ fDefaultJournal
Default value for journaling group of flags.
@ fDefaultMT
Default value for multi-threading group of flags.
@ fSyncOn
Synchronization is on, there is a slight chance of database corruption when OS crashes.
@ fJournalDelete
Journal on disk, journal file is deleted after each transaction.
@ fVacuumOff
Vacuuming is off, database file can only grow.
@ fWritesSync
Mode of doing all writes to the database.
@ fJournalMemory
Journaling is entirely in-memory.
@ fTempToMemory
Mode of storing temporary data.
unsigned int m_CacheSize
Recommended size of cache for the database.
CObjPool< sqlite3, CSQLITE_HandleFactory > THandlePool
CSQLITE_Connection(const CSQLITE_Connection &)
sqlite3 * LockHandle(void)
Lock and return low-level connection handle.
void x_CheckFlagsValidity(TOperationFlags flags, EOperationFlags mask)
Check that only one flag in specific group of flags is given.
CSQLITE_Statement * CreateVacuumStmt(size_t max_free_size)
Create statement for executing manual vacuuming.
void SetCacheSize(unsigned int size)
Set recommended size of the database cache (number of pages).
const string & GetFileName(void) const
Get database file name for the connection.
void Vacuum(size_t max_free_size)
Try to shrink database and free up to max_free_size bytes of disk space.
string m_FileName
File name of SQLite database.
unsigned int GetCacheSize(void)
Get recommended size of the database cache.
void SetPageSize(unsigned int size)
Set page size for the database (in bytes).
static CSQLITE_Connection * CreateInMemoryDatabase(CTempString file_name, bool shared=false)
Create a read-only copy of the database in memory.
CSQLITE_Connection(CTempString file_name, TOperationFlags flags=eDefaultFlags)
Connect to SQLite database.
void SetupNewConnection(sqlite3 *handle)
Setup newly created low-level connection handle.
void UnlockHandle(sqlite3 *handle)
Unlock unused low-level connection handle.
THandlePool m_HandlePool
Pool of low-level database connections.
unsigned int m_PageSize
Page size inside the database.
void DeleteDatabase(void)
Delete database under this connection.
CSQLITE_Connection & operator=(const CSQLITE_Connection &)
unsigned int GetPageSize(void)
Get page size used in the database (in bytes)
void x_ExecuteSql(sqlite3 *handle, CTempString sql)
Execute sql statement on given low-level connection handle.
void ExecuteSql(CTempString sql)
Execute sql statement without returning any results.
void SetFlags(TOperationFlags flags)
Change flags controlling database connection operation.
Exception thrown from all SQLite-related objects and functions.
virtual const char * GetErrCodeString(void) const override
Get error code interpreted as text.
NCBI_EXCEPTION_DEFAULT(CSQLITE_Exception, CException)
@ eBadCall
Method called when there's no enough capabilities to finish it successfully.
@ eDeadLock
SQLite detected possible deadlock between different threads.
@ eStmtStep
Error stepping through the statement.
@ eStmtBind
Error binding statement parameters.
@ eStmtPrepare
Error preparing statement.
@ eConstraint
Constraint violation during statement execution.
@ eUnknown
Unknown error.
@ eDBOpen
Error during database opening.
@ eBlobClose
Error closing blob object.
@ eBlobWrite
Error writing directly to blob.
@ eBlobOpen
Error opening blob object.
@ eBlobRead
Error reading directly from blob.
@ eStmtReset
Error reseting statement.
@ eWrongFlags
Incorrect set of flags in connection constructor.
@ eStmtFinalize
Error finalizing statement.
Utility class for some global-purpose functions tuning SQLite as a whole as opposed to tuning connect...
Definition: sqlitewrapp.hpp:64
static void Initialize(void)
Initialization of SQLite and tuning some default parameters.
static void RunAsyncWritesThread(void)
Launch background thread doing all asynchronous writes to databases.
static sqlite3_vfs * GetDefaultVFS(void)
Get default virtual file system installed in SQLite.
CSQLITE_Global & operator=(CSQLITE_Global &)
static void SetAsyncWritesFileLocking(bool lock_files)
Setup the option for asynchronous file system to do the actual locking of database files on disk.
static void Finalize(void)
Finish all SQLite operations.
static void RegisterCustomVFS(sqlite3_vfs *vfs, bool set_default=true)
Register new virtual file system in SQLite.
static void EnableSharedCache(bool enable=true)
Enable use of the same cache by different connections to the same database file.
static void SetCustomPageCache(sqlite3_pcache_methods *methods)
Install non-default cache for all SQLite databases.
CSQLITE_Global(CSQLITE_Global &)
CSQLITE_Global(void)
Object factory creating sqlite3* handles.
CSQLITE_HandleFactory(CSQLITE_Connection *conn)
CSQLITE_Connection * m_Conn
Connection object this factory is bound to.
void DeleteObject(sqlite3 *handle)
Destroy database handle.
sqlite3 * CreateObject(void)
Create new database handle.
"Scoped" statement activity object.
CSQLITE_Statement * m_Stmt
Statement this object is bound to.
CSQLITE_StatementLock(const CSQLITE_StatementLock &)
CSQLITE_StatementLock(CSQLITE_Statement *stmt)
Bind activity control to the given statement.
CSQLITE_Statement & operator*(void)
Smart pointer's transformation.
CSQLITE_StatementLock & operator=(const CSQLITE_StatementLock &)
CSQLITE_Statement * operator->(void)
Smart pointer's transformation.
SQL statement executing on SQLite database.
CSQLITE_Statement(const CSQLITE_Statement &)
void x_Prepare(CTempString sql)
Prepare new statement if it's not empty.
double GetDouble(int col_ind) const
Get double value from column col_ind in current row.
Int8 GetInt8(int col_ind) const
Get 64-bit integer value from column col_ind in current row.
void Bind(int index, int val)
Bind integer value to parameter index.
int GetColumnsCount(void) const
Get number of columns in result set.
CSQLITE_Connection * m_Conn
Connection this statement belongs to.
size_t GetBlob(int col_ind, void *buffer, size_t size) const
Read blob value from column col_ind in current row.
void ClearBindings(void)
Reset all bindings to the statement to their initial NULL values.
CSQLITE_Statement & operator=(const CSQLITE_Statement &)
void Reset(void)
Reset the statement to release all locks and to be ready to execute again.
bool Step(void)
Step through results of the statement.
sqlite3 * m_ConnHandle
Low-level connection handle provided for this statement.
CStringUTF8 GetColumnName(int col_ind) const
Get name of column at index col_ind in result set.
Int8 GetLastInsertedRowid(void) const
Get rowid of the row inserted in last statement execution.
int GetInt(int col_ind) const
Get integer value from column col_ind in current row.
int GetChangedRowsCount(void) const
Get number of rows changed during last insert, delete or update statement.
void SetSql(CTempString sql)
Change sql text for the object and prepare new statement.
size_t GetBlobSize(int col_ind) const
Get size of blob value from column col_ind in current row.
sqlite3_stmt * m_StmtHandle
Low-level statement handle.
void BindNull(int index)
Bind null value to parameter index.
CSQLITE_Statement(CSQLITE_Connection *conn, CTempString sql=kEmptyStr)
Create and prepare statement for given database connection.
void Execute(void)
Execute statement without returning any result.
void BindZeroedBlob(int index, size_t size)
Bind blob value of given size containing only zeros to parameter index.
string GetString(int col_ind) const
Get text value from column col_ind in current row.
void x_Finalize(void)
Finalize current statement.
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
Definition: tempstr.hpp:65
The NCBI C++ standard methods for dealing with std::string.
static uch flags
const char * file_name[]
static CS_CONNECTION * conn
Definition: ct_dynamic.c:25
static char sql[1024]
Definition: putdata.c:19
static HSTMT stmt
Definition: rebindpar.c:12
static const char * column
Definition: stats.c:23
char data[12]
Definition: iconv.c:80
void reset(element_type *p=0, EOwnership ownership=eTakeOwnership)
Reset will delete the old pointer (if owned), set content to the new value, and assume the ownership ...
Definition: ncbimisc.hpp:480
@ eNoOwnership
No ownership is assumed.
Definition: ncbi_types.h:135
#define NULL
Definition: ncbistd.hpp:225
EErrCode
Error types that an application can generate.
Definition: ncbiexpt.hpp:884
int64_t Int8
8-byte (64-bit) signed integer
Definition: ncbitype.h:104
uint64_t Uint8
8-byte (64-bit) unsigned integer
Definition: ncbitype.h:105
void Return(TObjType *obj)
Return object to the pool for future use.
Definition: obj_pool.hpp:121
TObjType * Get(void)
Get object from the pool, create if necessary.
Definition: obj_pool.hpp:101
void Clear(void)
Delete all objects returned to the pool so far and clean it.
Definition: obj_pool.hpp:138
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
std::string CStringUTF8
Definition: ncbistl.hpp:254
#define kEmptyStr
Definition: ncbistr.hpp:123
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
<!DOCTYPE HTML >< html > n< header > n< title > PubSeq Gateway Help Page</title > n< style > n table
const struct ncbi::grid::netcache::search::fields::SIZE size
Defines NCBI C++ exception handling.
Miscellaneous common-use basic types and functionality.
Multi-threading – mutexes; rw-locks; semaphore.
static uint8_t * buffer
Definition: pcre2test.c:1016
Helper structure for closing the blob from CGuard<>
Helper structure for opening the blob from CGuard<>
#define _ASSERT
else result
Definition: token2.c:20
Modified on Wed Sep 04 15:03:04 2024 by modify_doxy.py rev. 669887