* @brief This file is the implementation file of SQL connection
*/
#include <stddef.h>
+#include <dpl/log/wrt_log.h>
#include <dpl/db/sql_connection.h>
#include <dpl/db/naive_synchronization_object.h>
-#include <dpl/scoped_free.h>
+#include <dpl/free_deleter.h>
+#include <memory>
#include <dpl/noncopyable.h>
#include <dpl/assert.h>
#include <db-util.h>
return;
}
- LogPedantic("Notifying after successful synchronize");
+ WrtLogD("Notifying after successful synchronize");
m_synchronizationObject->NotifyAll();
}
};
&m_stmt, NULL);
if (ret == SQLITE_OK) {
- LogPedantic("Data command prepared successfuly");
+ WrtLogD("Data command prepared successfuly");
break;
} else if (ret == SQLITE_BUSY) {
- LogPedantic("Collision occurred while preparing SQL command");
+ WrtLogD("Collision occurred while preparing SQL command");
// Synchronize if synchronization object is available
if (connection->m_synchronizationObject) {
- LogPedantic("Performing synchronization");
+ WrtLogD("Performing synchronization");
connection->m_synchronizationObject->Synchronize();
continue;
}
// Fatal error
const char *error = sqlite3_errmsg(m_masterConnection->m_connection);
- LogPedantic("SQL prepare data command failed");
- LogPedantic(" Statement: " << buffer);
- LogPedantic(" Error: " << error);
+ WrtLogD("SQL prepare data command failed");
+ WrtLogD(" Statement: %s", buffer);
+ WrtLogD(" Error: %s", error);
ThrowMsg(Exception::SyntaxError, error);
}
- LogPedantic("Prepared data command: " << buffer);
+ WrtLogD("Prepared data command: %s", buffer);
// Increment stored data command count
++m_masterConnection->m_dataCommandsCount;
SqlConnection::DataCommand::~DataCommand()
{
- LogPedantic("SQL data command finalizing");
+ WrtLogD("SQL data command finalizing");
if (sqlite3_finalize(m_stmt) != SQLITE_OK) {
- LogPedantic("Failed to finalize data command");
+ WrtLogD("Failed to finalize data command");
}
// Decrement stored data command count
const char *error = sqlite3_errmsg(
m_masterConnection->m_connection);
- LogPedantic("Failed to bind SQL statement parameter");
- LogPedantic(" Error: " << error);
+ WrtLogD("Failed to bind SQL statement parameter");
+ WrtLogD(" Error: %s", error);
ThrowMsg(Exception::SyntaxError, error);
}
SqlConnection::ArgumentIndex position)
{
CheckBindResult(sqlite3_bind_null(m_stmt, position));
- LogPedantic("SQL data command bind null: ["
- << position << "]");
+ WrtLogD("SQL data command bind null: [%i]", position);
}
void SqlConnection::DataCommand::BindInteger(
int value)
{
CheckBindResult(sqlite3_bind_int(m_stmt, position, value));
- LogPedantic("SQL data command bind integer: ["
- << position << "] -> " << value);
+ WrtLogD("SQL data command bind integer: [%i] -> %i", position, value);
}
void SqlConnection::DataCommand::BindInt8(
{
CheckBindResult(sqlite3_bind_int(m_stmt, position,
static_cast<int>(value)));
- LogPedantic("SQL data command bind int8: ["
- << position << "] -> " << value);
+ WrtLogD("SQL data command bind int8: [%i] -> %i", position, value);
}
void SqlConnection::DataCommand::BindInt16(
{
CheckBindResult(sqlite3_bind_int(m_stmt, position,
static_cast<int>(value)));
- LogPedantic("SQL data command bind int16: ["
- << position << "] -> " << value);
+ WrtLogD("SQL data command bind int16: [%i] -> %i", position, value);
}
void SqlConnection::DataCommand::BindInt32(
{
CheckBindResult(sqlite3_bind_int(m_stmt, position,
static_cast<int>(value)));
- LogPedantic("SQL data command bind int32: ["
- << position << "] -> " << value);
+ WrtLogD("SQL data command bind int32: [%i] -> %i", position, value);
}
void SqlConnection::DataCommand::BindInt64(
{
CheckBindResult(sqlite3_bind_int64(m_stmt, position,
static_cast<sqlite3_int64>(value)));
- LogPedantic("SQL data command bind int64: ["
- << position << "] -> " << value);
+ WrtLogD("SQL data command bind int64: [%i] -> %lli", position, value);
}
void SqlConnection::DataCommand::BindFloat(
{
CheckBindResult(sqlite3_bind_double(m_stmt, position,
static_cast<double>(value)));
- LogPedantic("SQL data command bind float: ["
- << position << "] -> " << value);
+ WrtLogD("SQL data command bind float: [%i] -> %f", position, value);
}
void SqlConnection::DataCommand::BindDouble(
double value)
{
CheckBindResult(sqlite3_bind_double(m_stmt, position, value));
- LogPedantic("SQL data command bind double: ["
- << position << "] -> " << value);
+ WrtLogD("SQL data command bind double: [%i] -> %f", position, value);
}
void SqlConnection::DataCommand::BindString(
value, strlen(value),
SQLITE_TRANSIENT));
- LogPedantic("SQL data command bind string: ["
- << position << "] -> " << value);
+ WrtLogD("SQL data command bind string: [%i] -> %s", position, value);
}
void SqlConnection::DataCommand::BindString(
void SqlConnection::DataCommand::BindInteger(
SqlConnection::ArgumentIndex position,
- const Optional<int> &value)
+ const boost::optional<int> &value)
{
- if (value.IsNull()) {
+ if (!value) {
BindNull(position);
} else {
BindInteger(position, *value);
void SqlConnection::DataCommand::BindInt8(
SqlConnection::ArgumentIndex position,
- const Optional<int8_t> &value)
+ const boost::optional<int8_t> &value)
{
- if (value.IsNull()) {
+ if (!value) {
BindNull(position);
} else {
BindInt8(position, *value);
void SqlConnection::DataCommand::BindInt16(
SqlConnection::ArgumentIndex position,
- const Optional<int16_t> &value)
+ const boost::optional<int16_t> &value)
{
- if (value.IsNull()) {
+ if (!value) {
BindNull(position);
} else {
BindInt16(position, *value);
void SqlConnection::DataCommand::BindInt32(
SqlConnection::ArgumentIndex position,
- const Optional<int32_t> &value)
+ const boost::optional<int32_t> &value)
{
- if (value.IsNull()) {
+ if (!value) {
BindNull(position);
} else {
BindInt32(position, *value);
void SqlConnection::DataCommand::BindInt64(
SqlConnection::ArgumentIndex position,
- const Optional<int64_t> &value)
+ const boost::optional<int64_t> &value)
{
- if (value.IsNull()) {
+ if (!value) {
BindNull(position);
} else {
BindInt64(position, *value);
void SqlConnection::DataCommand::BindFloat(
SqlConnection::ArgumentIndex position,
- const Optional<float> &value)
+ const boost::optional<float> &value)
{
- if (value.IsNull()) {
+ if (!value) {
BindNull(position);
} else {
BindFloat(position, *value);
void SqlConnection::DataCommand::BindDouble(
SqlConnection::ArgumentIndex position,
- const Optional<double> &value)
+ const boost::optional<double> &value)
{
- if (value.IsNull()) {
+ if (!value) {
BindNull(position);
} else {
BindDouble(position, *value);
void SqlConnection::DataCommand::BindString(
SqlConnection::ArgumentIndex position,
- const Optional<String> &value)
+ const boost::optional<String> &value)
{
if (!!value) {
BindString(position, ToUTF8String(*value).c_str());
int ret = sqlite3_step(m_stmt);
if (ret == SQLITE_ROW) {
- LogPedantic("SQL data command step ROW");
+ WrtLogD("SQL data command step ROW");
return true;
} else if (ret == SQLITE_DONE) {
- LogPedantic("SQL data command step DONE");
+ WrtLogD("SQL data command step DONE");
return false;
} else if (ret == SQLITE_BUSY) {
- LogPedantic("Collision occurred while executing SQL command");
+ WrtLogD("Collision occurred while executing SQL command");
// Synchronize if synchronization object is available
if (m_masterConnection->m_synchronizationObject) {
- LogPedantic("Performing synchronization");
+ WrtLogD("Performing synchronization");
m_masterConnection->
m_synchronizationObject->Synchronize();
// Fatal error
const char *error = sqlite3_errmsg(m_masterConnection->m_connection);
- LogPedantic("SQL step data command failed");
- LogPedantic(" Error: " << error);
+ WrtLogD("SQL step data command failed");
+ WrtLogD(" Error: %s", error);
ThrowMsg(Exception::InternalError, error);
}
*/
sqlite3_reset(m_stmt);
- LogPedantic("SQL data command reset");
+ WrtLogD("SQL data command reset");
}
void SqlConnection::DataCommand::CheckColumnIndex(
bool SqlConnection::DataCommand::IsColumnNull(
SqlConnection::ColumnIndex column)
{
- LogPedantic("SQL data command get column type: [" << column << "]");
+ WrtLogD("SQL data command get column type: [%i]", column);
CheckColumnIndex(column);
return sqlite3_column_type(m_stmt, column) == SQLITE_NULL;
}
int SqlConnection::DataCommand::GetColumnInteger(
SqlConnection::ColumnIndex column)
{
- LogPedantic("SQL data command get column integer: [" << column << "]");
+ WrtLogD("SQL data command get column integer: [%i]", column);
CheckColumnIndex(column);
int value = sqlite3_column_int(m_stmt, column);
- LogPedantic(" Value: " << value);
+ WrtLogD(" Value: %i", value);
return value;
}
int8_t SqlConnection::DataCommand::GetColumnInt8(
SqlConnection::ColumnIndex column)
{
- LogPedantic("SQL data command get column int8: [" << column << "]");
+ WrtLogD("SQL data command get column int8: [%i]", column);
CheckColumnIndex(column);
int8_t value = static_cast<int8_t>(sqlite3_column_int(m_stmt, column));
- LogPedantic(" Value: " << value);
+ WrtLogD(" Value: %i", value);
return value;
}
int16_t SqlConnection::DataCommand::GetColumnInt16(
SqlConnection::ColumnIndex column)
{
- LogPedantic("SQL data command get column int16: [" << column << "]");
+ WrtLogD("SQL data command get column int16: [%i]", column);
CheckColumnIndex(column);
int16_t value = static_cast<int16_t>(sqlite3_column_int(m_stmt, column));
- LogPedantic(" Value: " << value);
+ WrtLogD(" Value: %i", value);
return value;
}
int32_t SqlConnection::DataCommand::GetColumnInt32(
SqlConnection::ColumnIndex column)
{
- LogPedantic("SQL data command get column int32: [" << column << "]");
+ WrtLogD("SQL data command get column int32: [%i]", column);
CheckColumnIndex(column);
int32_t value = static_cast<int32_t>(sqlite3_column_int(m_stmt, column));
- LogPedantic(" Value: " << value);
+ WrtLogD(" Value: %i", value);
return value;
}
int64_t SqlConnection::DataCommand::GetColumnInt64(
SqlConnection::ColumnIndex column)
{
- LogPedantic("SQL data command get column int64: [" << column << "]");
+ WrtLogD("SQL data command get column int64: [%i]", column);
CheckColumnIndex(column);
int64_t value = static_cast<int64_t>(sqlite3_column_int64(m_stmt, column));
- LogPedantic(" Value: " << value);
+ WrtLogD(" Value: %lli", value);
return value;
}
float SqlConnection::DataCommand::GetColumnFloat(
SqlConnection::ColumnIndex column)
{
- LogPedantic("SQL data command get column float: [" << column << "]");
+ WrtLogD("SQL data command get column float: [%i]", column);
CheckColumnIndex(column);
float value = static_cast<float>(sqlite3_column_double(m_stmt, column));
- LogPedantic(" Value: " << value);
+ WrtLogD(" Value: %f", value);
return value;
}
double SqlConnection::DataCommand::GetColumnDouble(
SqlConnection::ColumnIndex column)
{
- LogPedantic("SQL data command get column double: [" << column << "]");
+ WrtLogD("SQL data command get column double: [%i]", column);
CheckColumnIndex(column);
double value = sqlite3_column_double(m_stmt, column);
- LogPedantic(" Value: " << value);
+ WrtLogD(" Value: %f", value);
return value;
}
std::string SqlConnection::DataCommand::GetColumnString(
SqlConnection::ColumnIndex column)
{
- LogPedantic("SQL data command get column string: [" << column << "]");
+ WrtLogD("SQL data command get column string: [%i]", column);
CheckColumnIndex(column);
const char *value = reinterpret_cast<const char *>(
sqlite3_column_text(m_stmt, column));
- LogPedantic("Value: " << (value ? value : "NULL"));
+ WrtLogD(" Value: %s", value);
if (value == NULL) {
return std::string();
return std::string(value);
}
-Optional<int> SqlConnection::DataCommand::GetColumnOptionalInteger(
+boost::optional<int> SqlConnection::DataCommand::GetColumnOptionalInteger(
SqlConnection::ColumnIndex column)
{
- LogPedantic("SQL data command get column optional integer: ["
- << column << "]");
+ WrtLogD("SQL data command get column optional integer: [%i]", column);
CheckColumnIndex(column);
if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) {
- return Optional<int>::Null;
+ return boost::optional<int>();
}
int value = sqlite3_column_int(m_stmt, column);
- LogPedantic(" Value: " << value);
- return Optional<int>(value);
+ WrtLogD(" Value: %i", value);
+ return boost::optional<int>(value);
}
-Optional<int8_t> SqlConnection::DataCommand::GetColumnOptionalInt8(
+boost::optional<int8_t> SqlConnection::DataCommand::GetColumnOptionalInt8(
SqlConnection::ColumnIndex column)
{
- LogPedantic("SQL data command get column optional int8: ["
- << column << "]");
+ WrtLogD("SQL data command get column optional int8: [%i]", column);
CheckColumnIndex(column);
if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) {
- return Optional<int8_t>::Null;
+ return boost::optional<int8_t>();
}
int8_t value = static_cast<int8_t>(sqlite3_column_int(m_stmt, column));
- LogPedantic(" Value: " << value);
- return Optional<int8_t>(value);
+ WrtLogD(" Value: %i", value);
+ return boost::optional<int8_t>(value);
}
-Optional<int16_t> SqlConnection::DataCommand::GetColumnOptionalInt16(
+boost::optional<int16_t> SqlConnection::DataCommand::GetColumnOptionalInt16(
SqlConnection::ColumnIndex column)
{
- LogPedantic("SQL data command get column optional int16: ["
- << column << "]");
+ WrtLogD("SQL data command get column optional int16: [%i]", column);
CheckColumnIndex(column);
if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) {
- return Optional<int16_t>::Null;
+ return boost::optional<int16_t>();
}
int16_t value = static_cast<int16_t>(sqlite3_column_int(m_stmt, column));
- LogPedantic(" Value: " << value);
- return Optional<int16_t>(value);
+ WrtLogD(" Value: %i", value);
+ return boost::optional<int16_t>(value);
}
-Optional<int32_t> SqlConnection::DataCommand::GetColumnOptionalInt32(
+boost::optional<int32_t> SqlConnection::DataCommand::GetColumnOptionalInt32(
SqlConnection::ColumnIndex column)
{
- LogPedantic("SQL data command get column optional int32: ["
- << column << "]");
+ WrtLogD("SQL data command get column optional int32: [%i]", column);
CheckColumnIndex(column);
if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) {
- return Optional<int32_t>::Null;
+ return boost::optional<int32_t>();
}
int32_t value = static_cast<int32_t>(sqlite3_column_int(m_stmt, column));
- LogPedantic(" Value: " << value);
- return Optional<int32_t>(value);
+ WrtLogD(" Value: %i", value);
+ return boost::optional<int32_t>(value);
}
-Optional<int64_t> SqlConnection::DataCommand::GetColumnOptionalInt64(
+boost::optional<int64_t> SqlConnection::DataCommand::GetColumnOptionalInt64(
SqlConnection::ColumnIndex column)
{
- LogPedantic("SQL data command get column optional int64: ["
- << column << "]");
+ WrtLogD("SQL data command get column optional int64: [%i]", column);
CheckColumnIndex(column);
if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) {
- return Optional<int64_t>::Null;
+ return boost::optional<int64_t>();
}
int64_t value = static_cast<int64_t>(sqlite3_column_int64(m_stmt, column));
- LogPedantic(" Value: " << value);
- return Optional<int64_t>(value);
+ WrtLogD(" Value: %lli", value);
+ return boost::optional<int64_t>(value);
}
-Optional<float> SqlConnection::DataCommand::GetColumnOptionalFloat(
+boost::optional<float> SqlConnection::DataCommand::GetColumnOptionalFloat(
SqlConnection::ColumnIndex column)
{
- LogPedantic("SQL data command get column optional float: ["
- << column << "]");
+ WrtLogD("SQL data command get column optional float: [%i]", column);
CheckColumnIndex(column);
if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) {
- return Optional<float>::Null;
+ return boost::optional<float>();
}
float value = static_cast<float>(sqlite3_column_double(m_stmt, column));
- LogPedantic(" Value: " << value);
- return Optional<float>(value);
+ WrtLogD(" Value: %f", value);
+ return boost::optional<float>(value);
}
-Optional<double> SqlConnection::DataCommand::GetColumnOptionalDouble(
+boost::optional<double> SqlConnection::DataCommand::GetColumnOptionalDouble(
SqlConnection::ColumnIndex column)
{
- LogPedantic("SQL data command get column optional double: ["
- << column << "]");
+ WrtLogD("SQL data command get column optional double: [%i]", column);
CheckColumnIndex(column);
if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) {
- return Optional<double>::Null;
+ return boost::optional<double>();
}
double value = sqlite3_column_double(m_stmt, column);
- LogPedantic(" Value: " << value);
- return Optional<double>(value);
+ WrtLogD(" Value: %f", value);
+ return boost::optional<double>(value);
}
-Optional<String> SqlConnection::DataCommand::GetColumnOptionalString(
+boost::optional<String> SqlConnection::DataCommand::GetColumnOptionalString(
SqlConnection::ColumnIndex column)
{
- LogPedantic("SQL data command get column optional string: ["
- << column << "]");
+ WrtLogD("SQL data command get column optional string: [%i]", column);
CheckColumnIndex(column);
if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) {
- return Optional<String>::Null;
+ return boost::optional<String>();
}
const char *value = reinterpret_cast<const char *>(
sqlite3_column_text(m_stmt, column));
- LogPedantic("Value: " << value);
+
+ WrtLogD(" Value: %s", value);
+
+ if (value == NULL) {
+ return boost::optional<String>();
+ }
+
String s = FromUTF8String(value);
- return Optional<String>(s);
+ return boost::optional<String>(s);
}
void SqlConnection::Connect(const std::string &address,
Flag::Option flag)
{
if (m_connection != NULL) {
- LogPedantic("Already connected.");
+ WrtLogD("Already connected.");
return;
}
- LogPedantic("Connecting to DB: " << address << "...");
+ WrtLogD("Connecting to DB: %s...", address.c_str());
// Connect to database
int result = -1;
int retry = 5;
- while (result != SQLITE_OK) {
+ while( result != SQLITE_OK){
if (type & Flag::UseLucene) {
result = db_util_open_with_options(
address.c_str(),
NULL);
m_usingLucene = true;
- LogPedantic("Lucene index enabled");
+ WrtLogD("Lucene index enabled");
} else {
result = sqlite3_open_v2(
address.c_str(),
NULL);
m_usingLucene = false;
- LogPedantic("Lucene index disabled");
+ WrtLogD("Lucene index disabled");
}
if (result == SQLITE_OK) {
- LogPedantic("Connected to DB");
+ WrtLogD("Connected to DB");
} else {
- LogPedantic("Failed to connect to DB! ret="<<result);
- if (retry-- <= 0)
+ WrtLogD("Failed to connect to DB! ret=%d", result);
+ if( retry-- <= 0 )
ThrowMsg(Exception::ConnectionBroken, address);
}
}
void SqlConnection::Disconnect()
{
if (m_connection == NULL) {
- LogPedantic("Already disconnected.");
+ WrtLogD("Already disconnected.");
return;
}
- LogPedantic("Disconnecting from DB...");
+ WrtLogD("Disconnecting from DB...");
// All stored data commands must be deleted before disconnect
AssertMsg(m_dataCommandsCount == 0,
if (result != SQLITE_OK) {
const char *error = sqlite3_errmsg(m_connection);
- LogPedantic("SQL close failed");
- LogPedantic(" Error: " << error);
+ WrtLogD("SQL close failed");
+ WrtLogD(" Error: %s", error);
Throw(Exception::InternalError);
}
m_connection = NULL;
- LogPedantic("Disconnected from DB");
+ WrtLogD("Disconnected from DB");
}
bool SqlConnection::CheckTableExist(const char *tableName)
{
if (m_connection == NULL) {
- LogPedantic("Cannot execute command. Not connected to DB!");
+ WrtLogD("Cannot execute command. Not connected to DB!");
return false;
}
command->BindString(1, tableName);
if (!command->Step()) {
- LogPedantic("No matching records in table");
+ WrtLogD("No matching records in table");
return false;
}
m_dataCommandsCount(0),
m_synchronizationObject(synchronizationObject)
{
- LogPedantic("Opening database connection to: " << address);
+ WrtLogD("Opening database connection to: %s", address.c_str());
// Connect to DB
SqlConnection::Connect(address, flag, option);
if (!m_synchronizationObject) {
- LogPedantic("No synchronization object defined");
+ WrtLogD("No synchronization object defined");
}
}
SqlConnection::~SqlConnection()
{
- LogPedantic("Closing database connection");
+ WrtLogD("Closing database connection");
// Disconnect from DB
Try
}
Catch(Exception::Base)
{
- LogPedantic("Failed to disconnect from database");
+ WrtLogD("Failed to disconnect from database");
}
}
void SqlConnection::ExecCommand(const char *format, ...)
{
if (m_connection == NULL) {
- LogPedantic("Cannot execute command. Not connected to DB!");
+ WrtLogD("Cannot execute command. Not connected to DB!");
return;
}
if (format == NULL) {
- LogPedantic("Null query!");
+ WrtLogD("Null query!");
ThrowMsg(Exception::SyntaxError, "Null statement");
}
va_end(args);
- ScopedFree<char> buffer(rawBuffer);
+ std::unique_ptr<char[],free_deleter> buffer(rawBuffer);
if (!buffer) {
- LogPedantic("Failed to allocate statement string");
+ WrtLogD("Failed to allocate statement string");
return;
}
- LogPedantic("Executing SQL command: " << buffer.Get());
+ WrtLogD("Executing SQL command: %s", buffer.get());
// Notify all after potentially synchronized database connection access
ScopedNotifyAll notifyAll(m_synchronizationObject.get());
char *errorBuffer;
int ret = sqlite3_exec(m_connection,
- buffer.Get(),
+ buffer.get(),
NULL,
NULL,
&errorBuffer);
}
if (ret == SQLITE_BUSY) {
- LogPedantic("Collision occurred while executing SQL command");
+ WrtLogD("Collision occurred while executing SQL command");
// Synchronize if synchronization object is available
if (m_synchronizationObject) {
- LogPedantic("Performing synchronization");
+ WrtLogD("Performing synchronization");
m_synchronizationObject->Synchronize();
continue;
}
}
// Fatal error
- LogPedantic("Failed to execute SQL command. Error: " << errorMsg);
+ WrtLogD("Failed to execute SQL command. Error: %s", errorMsg.c_str());
ThrowMsg(Exception::SyntaxError, errorMsg);
}
}
...)
{
if (m_connection == NULL) {
- LogPedantic("Cannot execute data command. Not connected to DB!");
+ WrtLogD("Cannot execute data command. Not connected to DB!");
return DataCommandAutoPtr();
}
va_end(args);
- ScopedFree<char> buffer(rawBuffer);
+ std::unique_ptr<char[],free_deleter> buffer(rawBuffer);
if (!buffer) {
- LogPedantic("Failed to allocate statement string");
+ WrtLogD("Failed to allocate statement string");
return DataCommandAutoPtr();
}
- LogPedantic("Executing SQL data command: " << buffer.Get());
+ WrtLogD("Executing SQL data command: %s", buffer.get());
- return DataCommandAutoPtr(new DataCommand(this, buffer.Get()));
+ return DataCommandAutoPtr(new DataCommand(this, buffer.get()));
}
SqlConnection::RowID SqlConnection::GetLastInsertRowID() const