Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

A C++ Embedded Web Server

, 23 Jun 2014 BSD
Give a C++ application its own web page
webem_demo.zip
code_project
examples
webemCalendar
calendar.dat
sqlite3.dll
webemCalendar.vcproj.CORVIS.james.user
webemHello
webemHello.vcproj.CORVIS.james.user
webemHelloForm
webemHelloForm.vcproj.CORVIS.james.user
webemMT
webemMT.vcproj.CORVIS.james.user
src
sqlite
sqlite3.lib
webem
server
Jamfile
Jamfile.v2
webem_src.zip
manifest
manifest.uuid
webem.fossil
_FOSSIL_
doc
DoxyFile
html
doxygen.png
tab_b.gif
tab_l.gif
tab_r.gif
examples
webemButton
webemCalendar
calendar.dat
sqlite3.dll
sqlite3.lib
WebemHello
webemHelloForm
server
/*
  SQLiteDatabase.cpp - CSQLiteDatabase implementation, a wrapper for the SQLite database
*/

#include "StdAfx.h"
#include ".\sqlitedatabase.h"

///
///  Access a SQLite database.
///
/// \param[in] dbfname database filename, null terminated char string

CSQLiteDatabase::CSQLiteDatabase(const wchar_t * dbfname )
{
	// remember the dtabase filename
	myDBFName = dbfname;
	// open the database
	Open();
	// allocate room for pointers to 10,000 values returned from a query
//	myRows = new string[ 10000 ];
	// clear the error
	myError = 0;
}
/*****************************************************************
  CSQLiteDatabase destructor.
*/
CSQLiteDatabase::~CSQLiteDatabase(void)
{
	Close();
//	delete[] myRows;
	myRows.clear();
}
/*****************************************************************
  Open.

  This opens, creating if neccessary, a UTF-16 database

*/
void CSQLiteDatabase::Open()
{
	int rc = sqlite3_open16(myDBFName.c_str(), &db);
	if( rc ) {
		printf("Cannot open database %s",myDBFName);
		exit(1);
	}
}
/*****************************************************************
  Close.
*/
void CSQLiteDatabase::Close()
{
	sqlite3_close(db);

}
/*****************************************************************
  callback - called by sqlite for each row returned by a query

  In:
  myRows - pointer to CString array to store the results
  argc - number of columns
  argv - pointer to string array containing results
  azColName - pointer to array of column names

  Notes:
  Assumes that the column count is always constant for each query
  Will not store more than 1000 values
  RowCount must be zeroed before each query

*/
int CSQLiteDatabase::RowCount;
int CSQLiteDatabase::callback(void *myRows, int argc, char **argv, char **azColName)
{
	for(int kcol=0; kcol<argc; kcol++){
		if( ! argv[kcol] ) {
			// a "null" value - we will just return an empty string
			((vector<string> *) myRows)->push_back(string(""));
		} else {
			((vector<string> *) myRows)->push_back(string( argv[kcol] ));
		}

	}
	RowCount++;

	return 0;
}
/**
  Apply SQL query to database.

 \param[in] sQ SQL query string

 \return 
  the number of rows returned by the query.  
  -1 indicates an error
  -2 too many rows

  The data returned by the query, if any, will be in myRows
  To access the second column in the third row
  myRows[ 2 * cols + 1 ]

*/
int CSQLiteDatabase::Query( string & sQ )
{
	RowCount = 0;
	myRows.clear();
	int rc = sqlite3_exec(db, sQ.c_str(), callback, &myRows, &myError);
	if( rc!=SQLITE_OK ){
		if( rc==SQLITE_ABORT ) {
			myError = "Too many rows returned";
			return -2;
		}
		return -1;
	}
	myLastID = (int)sqlite3_last_insert_rowid( db );

	myRowCount = RowCount;
	return myRowCount;

}
/** ***************************************************************
	Enable speed optimization.

When synchronous is FULL (2), the SQLite database engine will pause at critical moments to make sure that data has actually been written to the disk surface before continuing. 
This ensures that if the operating system crashes or if there is a power failure, the database will be uncorrupted after rebooting. 
FULL synchronous is very safe, but it is also slow. When synchronous is NORMAL, the SQLite database engine will still pause at the most critical moments, 
but less often than in FULL mode. There is a very small (though non-zero) chance that a power failure at just the wrong time could corrupt the database in NORMAL mode. 
But in practice, you are more likely to suffer a catastrophic disk failure or some other unrecoverable hardware fault. 
With synchronous OFF (0), SQLite continues without pausing as soon as it has handed data off to the operating system. 
If the application running SQLite crashes, the data will be safe,
but the database might become corrupted if the operating system crashes or the computer loses power before that data has been written to the disk surface. 
On the other hand, some operations are as much as 50 or more times faster with synchronous OFF.

In SQLite version 2, the default value is NORMAL. For version 3, the default was changed to FULL.



*/
void CSQLiteDatabase::setFast()
{
	Query("PRAGMA synchronous = OFF;");
}

/**

  Submit unicode query, retrieve unicode data.

  @param[in] q  unicode query
  @return  number of rows retrieved, -1 for error

  the row data is stored in CSQLiteDatabase::myRows16

*/
int CSQLiteDatabase::Query16( wstring const & q )
{
	myError = 0;
	// submit query - just one
	void const * tail = 0;
	sqlite3_stmt * st = 0;
	if( sqlite3_prepare16_v2( db, q.c_str(), -1, &st, &tail ) != SQLITE_OK ) {
		// error in query - provide human readable msg
		int nErrMsg = 1 + (int)strlen(sqlite3_errmsg(db));
		myError = (char*)sqlite3_malloc(nErrMsg);
		if( myError ){
			memcpy((void*)myError, sqlite3_errmsg(db), nErrMsg);
		} else {
			myError = "out of memory";
		}
		return -1;
	}
	int col_count = sqlite3_column_count( st );

	// loop over rows returned
	myRowCount = 0;
	myRows16.clear();
	while( sqlite3_step( st ) == SQLITE_ROW ) {
		myRowCount++;
		// loop over columns
		for( int kcol = 0; kcol < col_count; kcol++ ) {
			if( sqlite3_column_type( st, kcol ) == SQLITE_NULL )
				myRows16.push_back( wstring(L""));
			else
				myRows16.push_back( wstring( ( wchar_t * )sqlite3_column_text16(st, kcol)) );
		}
	}

	// clean up
	sqlite3_finalize( st );
	myLastID = (int)sqlite3_last_insert_rowid( db );
	return myRowCount;
}


/**************************************************************************

//   Designed and coded by James Bremner, Raven's Point Consulting,
//   james@ravenspoint.com

  This file is under cvs version control

  If it has been released, the release name will be here: $Name: tip $

  Below is more detailed information describing the precise version

  $Header: C:\Documents and Settings\james\My Documents\code\webem\kenai/src/sqlite/SQLiteDatabase.cpp,v 380e7e273298 2008/09/09 21:28:57 james $

*/



By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The BSD License

Share

About the Author

ravenspoint
Founder Raven's Point Consulting
Canada Canada
No Biography provided

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.1411023.1 | Last Updated 23 Jun 2014
Article Copyright 2008 by ravenspoint
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid