view C++/Driver.cpp @ 189:cc1e5fe1ee2c

Update drivers to style and using instead of typedefs
author David Demelier <markand@malikania.fr>
date Tue, 26 Nov 2013 20:36:59 +0100
parents 4c746050969a
children 6c49e5e3ecc8
line wrap: on
line source

/*
 * Driver.cpp -- generic SQL driver access
 *
 * Copyright (c) 2013, David Demelier <markand@malikania.fr>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <map>
#include <string>
#include <sstream>

#include "Driver.h"

/* ---------------------------------------------------------
 * Query::Error class
 * --------------------------------------------------------- */

Query::Error::Error(const std::string &error)
	: m_error(error)
{
}

const char *Query::Error::Error::what() const throw()
{
	return m_error.c_str();
}

/* ---------------------------------------------------------
 * Query class
 * ---------------------------------------------------------*/

void Query::assertRequest(int row, const std::string &column, ColumnType wanted)
{
	std::ostringstream oss;

	// Out of bounds?
	if (row < 0 || row >= countRows()) {
		oss << "Invalid row index " << row;
		oss << ", expected [0.." << countRows() << "]";

		throw Error(oss.str());
	}

	// Not found or bad column?
	if (type(column) != wanted) {
		oss << "Invalid or not found column `" << column << "'";

		throw Error(oss.str());
	}
}

Query::~Query()
{
}

template <>
bool Query::get(int row, const std::string &column)
{
	assertRequest(row, column, ColumnType::Boolean);

	return getBoolean(row, column);
}

template <>
Date Query::get(int row, const std::string &column)
{
	assertRequest(row, column, ColumnType::Date);

	return getDate(row, column);
}

template <>
double Query::get(int row, const std::string &column)
{
	assertRequest(row, column, ColumnType::Double);

	return getDouble(row, column);
}

template <>
int Query::get(int row, const std::string &column)
{
	assertRequest(row, column, ColumnType::Integer);

	return getInt(row, column);
}

template <>
std::string Query::get(int row, const std::string &column)
{
	assertRequest(row, column, ColumnType::String);

	return getString(row, column);
}

/* --------------------------------------------------------
 * Request class
 * -------------------------------------------------------- */

Request::Request(const std::string &command)
	: m_pos(0)
	, m_params(0)
	, m_command(command)
{
	int i = -1;

	while ((i = command.find('#', i + 1)) != std::string::npos)
		++ m_params;
}

Request::~Request()
{
}

void Request::assertCorrect()
{
	if (m_params <= 0)
		throw std::runtime_error("no more arguments to set");
}

void Request::setValue(const std::string &value)
{
	assertCorrect();

	m_pos = m_command.find('#', m_pos);
	m_command.replace(m_pos, 1, value);
	m_pos += value.length();
	m_params --;
}

template <>
void Request::bind(bool value)
{
	setValue(bindBoolean(value));
}

template <>
void Request::bind(Date value)
{
	setValue(bindDate(value));
}

template <>
void Request::bind(double value)
{
	setValue(bindDouble(value));
}

template <>
void Request::bind(int value)
{
	setValue(bindInt(value));
}

template <>
void Request::bind(std::string value)
{
	setValue(bindString(value));
}

template <>
void Request::bind(const char *value)
{
	setValue(bindString(value));
}

Request::operator std::string()
{
	return m_command;
}

/* --------------------------------------------------------
 * Driver class
 * -------------------------------------------------------- */

Driver::Driver()
{
}

Driver::~Driver()
{
}

const std::string &Driver::getError() const
{
	return m_error;
}

Query::Ptr Driver::query(Request::Ptr request)
{
	return query(static_cast<std::string>(*request));
}