From b59634ba544ebc9e11eb4d0d20540368b8bda52d Mon Sep 17 00:00:00 2001 From: Pavel Medvedev Date: Tue, 18 Sep 2012 22:24:31 +0400 Subject: [PATCH] Updated examples and documentation --- doc/sqlitepp.html | 238 +++++++++++++++++++++++++--------------------- doc/sqlitepp.rst | 76 ++++++++++----- examples/ex2.cpp | 3 +- 3 files changed, 182 insertions(+), 135 deletions(-) diff --git a/doc/sqlitepp.html b/doc/sqlitepp.html index 39a0d19..1059923 100644 --- a/doc/sqlitepp.html +++ b/doc/sqlitepp.html @@ -3,11 +3,10 @@ - + SQLite++ - - + @@ -21,67 +20,63 @@

C++ wrapper to SQLite libr Author: Pavel Medvedev Contact: -pmedvedev@gmail.com -Date: -2008-01-24 -Revision: -65 +pmedvedev@gmail.com Copyright: -Copyright (c) 2004-2008 Pavel Medvedev +Copyright (c) 2004-2012 Pavel Medvedev -
-

Table of Contents

+ -
-

1   Overview

-

SQLite++ is an object-oriented wrapper library of SQLite version 3. -The latest sources are available from Subversion repository

+
+

1   Overview

+

SQLite++ is an object-oriented wrapper library of SQLite version 3. +The latest sources are available from Subversion repository

The main idea is to use simple variable binding with SQL statements:

 int count;
 db << "select count(*) from employee", into(count);
 

The library is distributed under Boost Software License (see accompanying -file LICENSE_1_0.txt in the project root). Additional information about -Boost Software License is available at Boost site

+file LICENSE_1_0.txt in the project root). Additional information about +Boost Software License is available at Boost site

Approaches with binding variables to SQL queries were inspired by -Maciej Sobczak' SOCI wrapper.

+Maciej Sobczak' SOCI wrapper.

-
-

2   Installation

+
+

2   Installation

This section describes how to build and install SQLitepp from released source distribution.

-

SQLite++ uses Boost Build v2. Refer to the documentation how to install +

SQLite++ uses Boost Build v2. Refer to the documentation how to install Boost Build v2.

To build SQLite++ change working dir to the root of this distribution and invoke

-bjam [build-variant]
+bjam [build-variant]

Where build-variant is an optional predefined build variant name. There are several predefined variants:

@@ -91,16 +86,16 @@

2&n

- + - + - + - + @@ -108,23 +103,23 @@

2&n

After successful building two subdirectories will be created:

    -
  • lib - with binary library files.
  • -
  • include - with header files.
  • +
  • lib - with binary library files.
  • +
  • include - with header files.

Make them available for a compiler in your favorite way and have fun ;-)

-
-

2.1   Testing

+
+

2.1   Testing

You might want to run unit-tests of SQLite++. It's simple with bjam:

-bjam test [build-variant]
-

Test application uses excellent unit-testing library TUT

+bjam test [build-variant] +

Test application uses excellent unit-testing library TUT

-
-

3   Short Tutorial

+
+

3   Short Tutorial

Let's make simple database application. It creates database with table -employee and adds a record.

+employee and adds a record.

 #include <iostream>
 #include <stdexcept>
@@ -178,7 +173,7 @@ 

operator<<).

+stream shifting (i.e. custom classes with operator<<).

Ok, while it seems like just yet another object-oriented database library. Next example.

@@ -226,7 +221,8 @@ 

(1.1) + st.reset(true); // (1.1) + st.exec(); // (1.2) } // (2) @@ -247,21 +243,23 @@

Again usual things happen - we create session and table. Then we create -statement object st. It is executing in context of database db. In the +statement object st. It is executing in context of database db. In the code block marked as (1) we prepare SQL query and bind variable e members to SQL values(:name, :age, :salary) of the same name. Next, in loop we ask user -to enter employee data. In line marked (1.1) the statement is executed and -data of members``e`` are inserted into the table employee.

-

But let's check contents of the employee. The code block marked as (2) -demonstrates it. Statement st is preparing with new SQL select query. Note -the members of e are bound to SQL result columns again. Loop counts until +to enter employee data. At line (1.1) the statement is reset after previous +execution step and use values for e are rebound. At the next line (1.2) +the statement is executed and data of members``e`` are inserted into +the table employee.

+

But let's check contents of the employee. The code block marked as (2) +demonstrates it. Statement st is preparing with new SQL select query. Note +the members of e are bound to SQL result columns again. Loop counts until statement select has data.

-
-

4   Reference

+
+

4   Reference

This section provides the information how to use SQLite++.

-
-

4.1   String. Aha, Yet Another One

+
+

4.1   String. Aha, Yet Another One

Internationalization, code pages, all these things may cause a big headache. Fortunately, SQLite stores text fields in UTF-8 or UTF-16 encoded. So, actually SQLite++ has to support either one or another. There are 3 types @@ -273,13 +271,13 @@

- + - + - + @@ -320,9 +318,9 @@

SQLITEPP_UTF16. Otherwise UTF-8 will be used. The common way to abstract +SQLITEPP_UTF16. Otherwise UTF-8 will be used. The common way to abstract from encoding used is to define generalized character type. In SQLite++ is a -char_t:

+char_t:

 #ifdef SQLITEPP_UTF16
     typedef utf16_char   char_t;
@@ -343,13 +341,13 @@ 

Note

-

utf8_char is the C++ char type, therefore it's possible don't +

utf8_char is the C++ char type, therefore it's possible don't use UTF-8 encoding at all. SQLite and SQLite++ make no checks and interpret a string as a raw byte sequence.

-
-

4.2   Exceptions

+
+

4.2   Exceptions

All SQLite errors mapped to SQLite++ exceptions. Base class is a sqlitepp::exception:

@@ -366,7 +364,7 @@ 

4.2&nbs

There are some custom SQLite++ exceptions:

utf8
utf8 UTF-8 encoding support. Defaul variant.
utf8d
utf8d UTF-8 encoding support, debug version.
utf16
utf16 UTF-16 encoding support.
utf16d
utf16d UTF-16 encoding support, debug version.
utf8_char
utf8_char 1 byte
utf16_char
utf16_char 2 byte
utf32_char
utf32_char 4 byte
@@ -375,7 +373,7 @@

4.2&nbs

- + - + - + - +
nested_txn_not_supported
nested_txn_not_supported

This exception is thrown when the user tries to run nested transaction. This is a SQLite limitation - lack of @@ -392,7 +390,7 @@

4.2&nbs

no_such_column
no_such_column

This exception is thrown when the user tries to get statement column by name (see statement::column_index):

@@ -402,7 +400,7 @@

4.2&nbs

session_not_open
session_not_open

This exception is thrown when the user tries to excecute SQL statement in not opened session:

@@ -412,7 +410,7 @@

4.2&nbs

multi_stmt_not_supported
multi_stmt_not_supported

This excpetion is thrown when the user tries to excecute multiple SQL queries in the one statement:

@@ -425,8 +423,8 @@

4.2&nbs

-
-

4.3   Session

+ -
-

4.4   Statement

+ - -
-

4.6   BLOB

+
+

4.6   BLOB

SQLite tables can contain BLOB columns. BLOB is a simple struct:

 struct blob
@@ -615,8 +636,8 @@ 

4.6  &nb

SQLite++ supports conversion between template std::vector<T> and blob value. See "Data Conversion" section below.

-
-

4.7   Binders

+
+

4.7   Binders

Binders are used to bind value into the statement query. There are two types of binders:

@@ -625,11 +646,11 @@

4.7 &nb
  • use binders
  • -
    -

    4.7.1   Into binders

    +
    +

    4.7.1   Into binders

    Into binders are used for binding result set values into variables. In the -following example selected value of column name from table employees -will be stored in variable name:

    +following example selected value of column name from table employees +will be stored in variable name:

     session db("test.db");
     statement st(db);
    @@ -675,10 +696,10 @@ 

    4. inline into_binder_ptr into(T& t, string_t const& name);

    -
    -

    4.7.2   Use binders

    +
    +

    4.7.2   Use binders

    This binders use variables as parameters for SQL queries. Following code -uses variable id to select column name from table employees:

    +uses variable id to select column name from table employees:

     session db("test.db");
     statement st(db);
    @@ -719,8 +740,8 @@ 

    4.7. inline use_binder_ptr use(T& t, string_t const& name);

    - -
    -

    4.8   Query

    +
    +

    4.8   Query

    Query is a noncopyable collection of SQL text and variable binders:

     // Query class. Noncopyable
    @@ -848,8 +869,9 @@ 

    4.8  &

    diff --git a/doc/sqlitepp.rst b/doc/sqlitepp.rst index 17a45b4..42250b9 100644 --- a/doc/sqlitepp.rst +++ b/doc/sqlitepp.rst @@ -7,9 +7,7 @@ C++ wrapper to SQLite library :Author: Pavel Medvedev :Contact: pmedvedev@gmail.com -:date: $Date$ -:revision: $Rev$ -:copyright: Copyright (c) 2004-2008 Pavel Medvedev +:copyright: Copyright (c) 2004-2012 Pavel Medvedev .. contents:: Table of Contents .. section-numbering:: @@ -202,7 +200,8 @@ Next example. use(e.name), use(e.age), use(e.salary); while ( std::cin >> e ) { - st.exec(); // **(1.1)** + st.reset(true); // **(1.1)** + st.exec(); // **(1.2)** } // **(2)** @@ -226,8 +225,10 @@ Again usual things happen - we create session and table. Then we create statement object ``st``. It is executing in context of database ``db``. In the code block marked as (1) we prepare SQL query and bind variable e members to SQL values(:name, :age, :salary) of the same name. Next, in loop we ask user -to enter employee data. In line marked (1.1) the statement is executed and -data of members``e`` are inserted into the table ``employee``. +to enter employee data. At line (1.1) the statement is reset after previous +execution step and use values for ``e`` are rebound. At the next line (1.2) +the statement is executed and data of members``e`` are inserted into +the table ``employee``. But let's check contents of the ``employee``. The code block marked as (2) demonstrates it. Statement ``st`` is preparing with new SQL select query. Note @@ -387,13 +388,17 @@ Session is a SQLite database abstraction:: session(); // Create and open session. - explicit session(string_t const& file_name); - + // Optional parameter flags for file open operations + // (see SQLite reference at http://sqlite.org/c3ref/c_open_autoproxy.html) + explicit session(string_t const& file_name, int flags = 0); + // Close session on destroy. ~session(); // Open database session. Previous one will be closed. - void open(string_t const& file_name); + // Optional parameter flags for file open operations + // (see SQLite reference at http://sqlite.org/c3ref/c_open_autoproxy.html) + void open(string_t const& file_name, int flags = 0); // Close database session. void close(); @@ -407,17 +412,30 @@ Session is a SQLite database abstraction:: // If we have the transaction, we get it or null otherwise. transaction* active_txn() const; // throw() - // Last insert row ID + /// SQLite implementation for native sqlite3 functions. + sqlite3* impl() const; + + /// Check error code. If code is not ok, throws exception. + void check_error(int code) const; + void check_last_error() const; + + // Last session error + int last_error() const; + + // Last statement::exec result + bool last_exec() const; + + // Last insert row ID long long last_insert_rowid() const; - // The number of rows that were changed (or inserted or deleted) - // by the most recent SQL statement - size_t last_changes() const; - - // The number of rows that were changed (or inserted or deleted) - // since the database was opened - size_t total_changes() const; - + // The number of rows that were changed (or inserted or deleted) + // by the most recent SQL statement + size_t last_changes() const; + + // The number of rows that were changed (or inserted or deleted) + // since the database was opened + size_t total_changes() const; + // Execute SQL query immediately. // It might be useful for resultless statements like INSERT, UPDATE etc. // T is any output-stream-shiftable type. @@ -425,7 +443,7 @@ Session is a SQLite database abstraction:: once_query operator<<(T const& t); // Swap session instances - friend void swap(session& lhs, session& rhs); + friend void swap(session& lhs, session& rhs); }; Statement @@ -455,6 +473,9 @@ Database statement:: // Finalize statement. void finalize(); + /// SQLite statement implementation for sqlite3 functions + sqlite3_stmt* impl() const; + // Is statement prepared. bool is_prepared() const; // throw() @@ -537,8 +558,11 @@ You should call ``transaction::commit`` to explicitly make a commit. :: class transaction { public: - // Begin transaction in context of the session s. - transaction(session& s); + // Transaction type + enum type { deferred, immediate, exclusive }; + + // Begin transaction in context of session. + transaction(session& s, type t = deferred); // End transaction with rollback if it is not commited. ~transaction(); @@ -554,11 +578,11 @@ BLOB SQLite tables can contain BLOB columns. BLOB is a simple struct:: - struct blob - { - void const* data; // raw data pointer - size_t size; // data size in bytes - }; + struct blob + { + void const* data; // raw data pointer + size_t size; // data size in bytes + }; SQLite++ supports conversion between template ``std::vector`` and blob value. See "Data Conversion" section below. diff --git a/examples/ex2.cpp b/examples/ex2.cpp index f41b666..37591cc 100644 --- a/examples/ex2.cpp +++ b/examples/ex2.cpp @@ -40,7 +40,8 @@ int main() , use(e.name), use(e.age), use(e.salary); while ( std::cin >> e ) { - st.exec(); // (1.1) + st.reset(true); // (1.1) + st.exec(); // (1.2) } // (2)