Adding a test/example for blob methods, with a fix for bind(blob)

This commit is contained in:
Sébastien Rombauts 2013-03-09 22:50:53 +01:00
parent 66cf354a65
commit 65ad65b40c
7 changed files with 94 additions and 15 deletions

View File

@ -6,7 +6,6 @@ Update Doxygen Documentation, but remove it from the master branch
Publish the Doxygen Documentation in the Github Pages (gh-pages branch) Publish the Doxygen Documentation in the Github Pages (gh-pages branch)
Missing test/example in v0.5.0: Missing test/example in v0.5.0:
- BLOB : make an example with images stored in a row
- :memory: table - :memory: table
Missing features in v0.5.0: Missing features in v0.5.0:

View File

@ -48,7 +48,7 @@
<ClCompile> <ClCompile>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>src/sqlite3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>src/sqlite3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild> <MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@ -69,7 +69,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>src/sqlite3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>src/sqlite3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader> <PrecompiledHeader>

BIN
logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -90,7 +90,7 @@ public:
} }
/** /**
* @brief Return the number of bytes used by the text value of the column * @brief Return the number of bytes used by the text (or blob) value of the column
* *
* Return either : * Return either :
* - size in bytes (not in characters) of the string returned by getText() without the '\0' terminator * - size in bytes (not in characters) of the string returned by getText() without the '\0' terminator
@ -100,6 +100,12 @@ public:
*/ */
int getBytes(void) const throw(); int getBytes(void) const throw();
/// Alias returning the number of bytes used by the text (or blob) value of the column
inline int size(void) const throw()
{
return getBytes ();
}
/// Inline cast operator to int /// Inline cast operator to int
inline operator int() const inline operator int() const
{ {

View File

@ -79,7 +79,7 @@ void Statement::bind(const int aIndex, const char* apValue) // throw(SQLite::Exc
// Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement // Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const int aIndex, const void* apValue, const int aSize) // throw(SQLite::Exception) void Statement::bind(const int aIndex, const void* apValue, const int aSize) // throw(SQLite::Exception)
{ {
int ret = sqlite3_bind_blob(mStmtPtr, aIndex, apValue, -1, SQLITE_TRANSIENT); int ret = sqlite3_bind_blob(mStmtPtr, aIndex, apValue, aSize, SQLITE_TRANSIENT);
check(ret); check(ret);
} }

View File

@ -163,9 +163,14 @@ public:
/** /**
* @brief Execute a one-step query with no expected result. * @brief Execute a one-step query with no expected result.
* *
* This exec() method is for use with precompiled statement that does not fetch results (INSERT, UPDATE, DELETE...). * This method is useful for any kind of statements other than the Data Query Language (DQL) "SELECT" :
* It is intended for similar usage as Database::exec(), but it add the ability to bind() arguments to it. * - Data Definition Language (DDL) statements "CREATE", "ALTER" and "DROP"
* Combined with reusing the underlying precompiled SQLite statement, it allows better performances. * - Data Manipulation Language (DML) statements "INSERT", "UPDATE" and "DELETE"
* - Data Control Language (DCL) statements "GRANT", "REVOKE", "COMMIT" and "ROLLBACK"
*
* It is similar to Database::exec(), but using a precompiled statement, it adds :
* - the ability to bind() arguments to it (best way to insert data),
* - reusing it allows for better performances (efficent for multiple insersion).
* *
* @see executeStep() execute a step of the prepared query to fetch one row of results * @see executeStep() execute a step of the prepared query to fetch one row of results
* @see Database::exec() is a shortcut to execute one or multiple statements without results * @see Database::exec() is a shortcut to execute one or multiple statements without results

View File

@ -60,7 +60,7 @@ private:
int main (void) int main (void)
{ {
// Basic example (1/5) : // Basic example (1/6) :
try try
{ {
// Open a database file in readonly mode // Open a database file in readonly mode
@ -115,7 +115,7 @@ int main (void)
} }
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Object Oriented Basic example (2/5) : // Object Oriented Basic example (2/6) :
try try
{ {
// Open the database and compile the query // Open the database and compile the query
@ -132,7 +132,7 @@ int main (void)
abort(); // unexpected error : abort the example program abort(); // unexpected error : abort the example program
} }
// The execAndGet wrapper example (3/5) : // The execAndGet wrapper example (3/6) :
try try
{ {
// Open a database file in readonly mode // Open a database file in readonly mode
@ -152,7 +152,7 @@ int main (void)
} }
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Simple batch queries example (4/5) : // Simple batch queries example (4/6) :
try try
{ {
// Open a database file in create/write mode // Open a database file in create/write mode
@ -193,7 +193,7 @@ int main (void)
remove("test.db3"); remove("test.db3");
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// RAII transaction example (5/5) : // RAII transaction example (5/6) :
try try
{ {
// Open a database file in create/write mode // Open a database file in create/write mode
@ -260,7 +260,76 @@ int main (void)
} }
remove("transaction.db3"); remove("transaction.db3");
std::cout << "everything ok, quitting" << std::endl; ////////////////////////////////////////////////////////////////////////////
// Binary blob example (6/6) :
try
{
// Open a database file in create/write mode
SQLite::Database db("blob.db3", SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
std::cout << "SQLite database file '" << db.getFilename().c_str() << "' opened successfully\n";
db.exec("DROP TABLE IF EXISTS test");
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value BLOB)");
FILE* fp = fopen("logo.png", "rb");
if (NULL != fp)
{
char buffer[16*1024];
void* blob = &buffer;
size_t size = fread(blob, 1, 16*1024, fp);
buffer[size] = '\0';
fclose (fp);
std::cout << "blob size=" << size << " :\n";
// Insert query
SQLite::Statement query(db, "INSERT INTO test VALUES (NULL, ?)");
// Bind the blob value to the first parameter of the SQL query
query.bind(1, blob, size);
std::cout << "blob binded successfully\n";
// Execute the one-step query to insert the blob
int nb = query.exec ();
std::cout << "INSERT INTO test VALUES (NULL, ?)\", returned " << nb << std::endl;
}
else
{
std::cout << "file logo.png not found !\n";
abort(); // unexpected error : abort the example program
}
fp = fopen("out.png", "wb");
if (NULL != fp)
{
const void* blob = NULL;
size_t size;
SQLite::Statement query(db, "SELECT * FROM test");
std::cout << "SELECT * FROM test :\n";
if (query.executeStep())
{
SQLite::Column colBlob = query.getColumn(1);
blob = colBlob.getBlob ();
size = colBlob.getBytes ();
std::cout << "row : (" << query.getColumn(0) << ", size=" << size << ")\n";
size_t sizew = fwrite(blob, 1, size, fp);
fclose (fp);
}
}
else
{
std::cout << "file out.png not created !\n";
abort(); // unexpected error : abort the example program
}
}
catch (std::exception& e)
{
std::cout << "SQLite exception: " << e.what() << std::endl;
abort(); // unexpected error : abort the example program
}
remove("blob.db3");
remove("out.png");
std::cout << "everything ok, quitting\n";
return 0; return 0;
} }