mysqlxx: development.

This commit is contained in:
Alexey Milovidov 2011-03-10 20:31:02 +00:00
parent acbab22bb2
commit c7b18f8972
7 changed files with 305 additions and 107 deletions

View File

@ -13,56 +13,68 @@ namespace mysqlxx
class Date class Date
{ {
private: private:
unsigned char m_day;
unsigned char m_month;
unsigned short m_year; unsigned short m_year;
unsigned char m_month;
unsigned char m_day;
public: void init(time_t time)
Date(time_t time)
{ {
Yandex::DateLUTSingleton & date_lut = Yandex::DateLUTSingleton::instance(); Yandex::DateLUTSingleton & date_lut = Yandex::DateLUTSingleton::instance();
const Yandex::DateLUT::Values & values = date_lut.getValues(time); const Yandex::DateLUT::Values & values = date_lut.getValues(time);
m_day = values.day_of_month;
m_month = values.month;
m_year = values.year; m_year = values.year;
m_month = values.month;
m_day = values.day_of_month;
} }
/// Для совместимости void init(const char * s, size_t length)
Date(unsigned short year_, unsigned char month_, unsigned char day_)
: m_day(day_), m_month(month_), m_year(year_)
{ {
} if (length < 10)
throw Exception("Cannot parse Date: " + std::string(s, length));
/// Для совместимости
Date(const std::string & s)
{
if (s.size() < 10)
throw Exception("Cannot parse Date: " + s);
m_year = s[0] * 1000 + s[1] * 100 + s[2] * 10 + s[3]; m_year = s[0] * 1000 + s[1] * 100 + s[2] * 10 + s[3];
m_month = s[5] * 10 + s[6]; m_month = s[5] * 10 + s[6];
m_day = s[8] * 10 + s[9]; m_day = s[8] * 10 + s[9];
} }
/// Для совместимости public:
Date() : m_day(1), m_month(1), m_year(2000) Date(time_t time)
{
init(time);
}
Date(unsigned short year_, unsigned char month_, unsigned char day_)
: m_year(year_), m_month(month_), m_day(day_)
{ {
} }
/// Для совместимости Date(const std::string & s)
{
init(s.data(), s.size());
}
Date(const char * data, size_t length)
{
init(data, length);
}
Date()
{
init(time(0));
}
operator time_t() const operator time_t() const
{ {
return Yandex::DateLUTSingleton::instance().makeDate(m_year, m_month, m_day); return Yandex::DateLUTSingleton::instance().makeDate(m_year, m_month, m_day);
} }
unsigned char day() const { return m_day; }
unsigned char month() const { return m_month; }
unsigned short year() const { return m_year; } unsigned short year() const { return m_year; }
unsigned char month() const { return m_month; }
unsigned char day() const { return m_day; }
void day(unsigned char x) { m_day = x; }
void month(unsigned char x) { m_month = x; }
void year(unsigned short x) { m_year = x; } void year(unsigned short x) { m_year = x; }
void month(unsigned char x) { m_month = x; }
void day(unsigned char x) { m_day = x; }
bool operator< (const Date & other) const bool operator< (const Date & other) const
{ {
@ -85,8 +97,8 @@ public:
inline std::ostream & operator<< (std::ostream & ostr, const Date & date) inline std::ostream & operator<< (std::ostream & ostr, const Date & date)
{ {
return ostr << date.year() return ostr << date.year()
<< '-' << (date.month() < 10 ? "0" : "") << date.month() << '-' << (date.month() / 10) << (date.month() % 10)
<< '-' << (date.day() < 10 ? "0" : "") << date.day(); << '-' << (date.day() / 10) << (date.day() % 10);
} }
} }

View File

@ -0,0 +1,147 @@
#ifndef MYSQLXX_DATETIME_H
#define MYSQLXX_DATETIME_H
#include <string>
#include <Yandex/DateLUT.h>
#include <mysqlxx/Exception.h>
namespace mysqlxx
{
class DateTime
{
private:
unsigned short m_year;
unsigned char m_month;
unsigned char m_day;
unsigned char m_hour;
unsigned char m_minute;
unsigned char m_second;
void init(time_t time)
{
Yandex::DateLUTSingleton & date_lut = Yandex::DateLUTSingleton::instance();
const Yandex::DateLUT::Values & values = date_lut.getValues(time);
m_year = values.year;
m_month = values.month;
m_day = values.day_of_month;
m_hour = date_lut.toHourInaccurate(time);
m_minute = date_lut.toMinute(time);
m_second = date_lut.toSecond(time);
}
void init(const char * s, size_t length)
{
if (length < 19)
throw Exception("Cannot parse DateTime: " + std::string(s, length));
m_year = s[0] * 1000 + s[1] * 100 + s[2] * 10 + s[3];
m_month = s[5] * 10 + s[6];
m_day = s[8] * 10 + s[9];
m_hour = s[11] * 10 + s[12];
m_minute = s[14] * 10 + s[15];
m_second = s[17] * 10 + s[18];
}
public:
DateTime(time_t time)
{
init(time);
}
DateTime(unsigned short year_, unsigned char month_, unsigned char day_,
unsigned char hour_, unsigned char minute_, unsigned char second_)
: m_year(year_), m_month(month_), m_day(day_), m_hour(hour_), m_minute(minute_), m_second(second_)
{
}
DateTime(const std::string & s)
{
if (s.size() < 19)
throw Exception("Cannot parse DateTime: " + s);
m_year = s[0] * 1000 + s[1] * 100 + s[2] * 10 + s[3];
m_month = s[5] * 10 + s[6];
m_day = s[8] * 10 + s[9];
m_hour = s[11] * 10 + s[12];
m_minute = s[14] * 10 + s[15];
m_second = s[17] * 10 + s[18];
}
DateTime()
{
init(time(0));
}
DateTime(const char * data, size_t length)
{
init(data, length);
}
operator time_t() const
{
return Yandex::DateLUTSingleton::instance().makeDateTime(m_year, m_month, m_day, m_hour, m_minute, m_second);
}
unsigned short year() const { return m_year; }
unsigned char month() const { return m_month; }
unsigned char day() const { return m_day; }
unsigned char hour() const { return m_hour; }
unsigned char minute() const { return m_minute; }
unsigned char second() const { return m_second; }
void year(unsigned short x) { m_year = x; }
void month(unsigned char x) { m_month = x; }
void day(unsigned char x) { m_day = x; }
void hour(unsigned char x) { m_hour = x; }
void minute(unsigned char x) { m_minute = x; }
void second(unsigned char x) { m_second = x; }
bool operator< (const DateTime & other) const
{
if (m_year < other.m_year)
return true;
else if (m_month < other.m_month)
return true;
else if (m_day < other.m_day)
return true;
else if (m_hour < other.m_hour)
return true;
else if (m_minute < other.m_minute)
return true;
else if (m_second < other.m_second)
return true;
else
return false;
}
bool operator== (const DateTime & other) const
{
return m_year == other.m_year && m_month == other.m_month && m_day == other.m_day
&& m_hour == other.m_hour && m_minute == other.m_minute && m_second == other.m_second;
}
bool operator!= (const DateTime & other) const
{
return !(*this == other);
}
};
inline std::ostream & operator<< (std::ostream & ostr, const DateTime & datetime)
{
return ostr << datetime.year()
<< '-' << (datetime.month() / 10) << (datetime.month() % 10)
<< '-' << (datetime.day() / 10) << (datetime.day() % 10)
<< ' ' << (datetime.hour() / 10) << (datetime.hour() % 10)
<< ':' << (datetime.minute() / 10) << (datetime.minute() % 10)
<< ':' << (datetime.second() / 10) << (datetime.second() % 10);
}
}
#endif

View File

@ -1,7 +1,7 @@
#ifndef MYSQLXX_QUERY_H #ifndef MYSQLXX_QUERY_H
#define MYSQLXX_QUERY_H #define MYSQLXX_QUERY_H
#include <sstream> #include <ostream>
#include <mysqlxx/UseQueryResult.h> #include <mysqlxx/UseQueryResult.h>
#include <mysqlxx/StoreQueryResult.h> #include <mysqlxx/StoreQueryResult.h>
@ -10,7 +10,7 @@
namespace mysqlxx namespace mysqlxx
{ {
class Query class Query : public std::ostream
{ {
public: public:
Query(Connection * conn_, const std::string & query_string); Query(Connection * conn_, const std::string & query_string);
@ -29,24 +29,12 @@ public:
std::string str() std::string str()
{ {
return query_stream.str(); return query_buf.str();
}
std::ostream & ostr()
{
return query_stream;
}
template <typename T>
Query & operator<< (const T & x)
{
query_stream << x;
return *this;
} }
private: private:
Connection * conn; Connection * conn;
std::stringstream query_stream; std::stringbuf query_buf;
}; };

View File

@ -24,6 +24,7 @@ static void readIntText(T & x, const char * buf, size_t length)
{ {
bool negative = false; bool negative = false;
x = 0; x = 0;
const char * start = buf;
const char * end = buf + length; const char * end = buf + length;
while (buf != end) while (buf != end)
@ -49,7 +50,7 @@ static void readIntText(T & x, const char * buf, size_t length)
x += *buf - '0'; x += *buf - '0';
break; break;
default: default:
throw Exception("Cannot parse integer: " + std::string(buf, length)); throw Exception("Cannot parse integer: " + std::string(start, length));
} }
++buf; ++buf;
} }
@ -66,6 +67,7 @@ static void readFloatText(T & x, const char * buf, size_t length)
x = 0; x = 0;
bool after_point = false; bool after_point = false;
double power_of_ten = 1; double power_of_ten = 1;
const char * start = buf;
const char * end = buf + length; const char * end = buf + length;
while (buf != end) while (buf != end)
@ -141,7 +143,7 @@ static void readFloatText(T & x, const char * buf, size_t length)
x = std::numeric_limits<T>::quiet_NaN(); x = std::numeric_limits<T>::quiet_NaN();
return; return;
default: default:
throw Exception("Cannot parse floating point number: " + std::string(buf, length)); throw Exception("Cannot parse floating point number: " + std::string(start, length));
} }
++buf; ++buf;
} }
@ -177,12 +179,7 @@ public:
Int64 getInt() const Int64 getInt() const
{ {
if (unlikely(isNull())) return getIntOrDateTime();
throw Exception("Value is NULL");
Int64 res;
readIntText(res, m_data, m_length);
return res;
} }
double getDouble() const double getDouble() const
@ -195,54 +192,14 @@ public:
return res; return res;
} }
time_t getDateTime() const DateTime getDateTime() const
{ {
if (unlikely(isNull())) return DateTime(data(), size());
throw Exception("Value is NULL");
if (!checkDateTime())
return getUInt();
Yandex::DateLUTSingleton & date_lut = Yandex::DateLUTSingleton::instance();
if (m_length == 10)
{
return date_lut.makeDate(
m_data[0] * 1000 + m_data[1] * 100 + m_data[2] * 10 + m_data[3],
m_data[5] * 10 + m_data[6],
m_data[8] * 10 + m_data[9]);
}
else
{
return date_lut.makeDateTime(
m_data[0] * 1000 + m_data[1] * 100 + m_data[2] * 10 + m_data[3],
m_data[5] * 10 + m_data[6],
m_data[8] * 10 + m_data[9],
m_data[11] * 10 + m_data[12],
m_data[14] * 10 + m_data[15],
m_data[17] * 10 + m_data[18]);
}
} }
time_t getDate() const Date getDate() const
{ {
if (unlikely(isNull())) return Date(data(), size());
throw Exception("Value is NULL");
if (!checkDateTime())
return getUInt();
Yandex::DateLUTSingleton & date_lut = Yandex::DateLUTSingleton::instance();
if (m_length == 10 || m_length == 19)
{
return date_lut.makeDate(
m_data[0] * 1000 + m_data[1] * 100 + m_data[2] * 10 + m_data[3],
m_data[5] * 10 + m_data[6],
m_data[8] * 10 + m_data[9]);
}
else
throw Exception("Cannot parse Date: " + getString());
} }
std::string getString() const std::string getString() const
@ -270,6 +227,7 @@ public:
size_t length() const { return m_length; } size_t length() const { return m_length; }
size_t size() const { return m_length; } size_t size() const { return m_length; }
private: private:
const char * m_data; const char * m_data;
size_t m_length; size_t m_length;
@ -278,6 +236,76 @@ private:
{ {
return (m_length == 10 || m_length == 19) && m_data[4] == '-' && m_data[7] == '-'; return (m_length == 10 || m_length == 19) && m_data[4] == '-' && m_data[7] == '-';
} }
time_t getDateTimeImpl() const
{
Yandex::DateLUTSingleton & date_lut = Yandex::DateLUTSingleton::instance();
if (m_length == 10)
{
return date_lut.makeDate(
m_data[0] * 1000 + m_data[1] * 100 + m_data[2] * 10 + m_data[3],
m_data[5] * 10 + m_data[6],
m_data[8] * 10 + m_data[9]);
}
else
{
return date_lut.makeDateTime(
m_data[0] * 1000 + m_data[1] * 100 + m_data[2] * 10 + m_data[3],
m_data[5] * 10 + m_data[6],
m_data[8] * 10 + m_data[9],
m_data[11] * 10 + m_data[12],
m_data[14] * 10 + m_data[15],
m_data[17] * 10 + m_data[18]);
}
}
time_t getDateImpl() const
{
Yandex::DateLUTSingleton & date_lut = Yandex::DateLUTSingleton::instance();
if (m_length == 10 || m_length == 19)
{
return date_lut.makeDate(
m_data[0] * 1000 + m_data[1] * 100 + m_data[2] * 10 + m_data[3],
m_data[5] * 10 + m_data[6],
m_data[8] * 10 + m_data[9]);
}
else
throw Exception("Cannot parse Date: " + getString());
}
Int64 getIntImpl() const
{
Int64 res;
readIntText(res, m_data, m_length);
return res;
}
Int64 getIntOrDateTime() const
{
if (unlikely(isNull()))
throw Exception("Value is NULL");
if (checkDateTime())
return getDateTimeImpl();
else
return getIntImpl();
}
Int64 getIntOrDate() const
{
if (unlikely(isNull()))
throw Exception("Value is NULL");
if (checkDateTime())
return getDateImpl();
else
{
Yandex::DateLUTSingleton & date_lut = Yandex::DateLUTSingleton::instance();
return date_lut.toDate(getIntImpl());
}
}
}; };
@ -296,6 +324,8 @@ template <> inline unsigned long long String::get<unsigned long long >() const
template <> inline float String::get<float >() const { return getDouble(); } template <> inline float String::get<float >() const { return getDouble(); }
template <> inline double String::get<double >() const { return getDouble(); } template <> inline double String::get<double >() const { return getDouble(); }
template <> inline std::string String::get<std::string >() const { return getString(); } template <> inline std::string String::get<std::string >() const { return getString(); }
template <> inline Date String::get<Date >() const { return getDate(); }
template <> inline DateTime String::get<DateTime >() const { return getDateTime(); }
template <> inline Yandex::VisitID_t String::get<Yandex::VisitID_t >() const { return Yandex::VisitID_t(getUInt()); } template <> inline Yandex::VisitID_t String::get<Yandex::VisitID_t >() const { return Yandex::VisitID_t(getUInt()); }
//template <> inline Date String::get<Date >() const { return getString(); } //template <> inline Date String::get<Date >() const { return getString(); }

View File

@ -3,23 +3,27 @@
#include <string> #include <string>
#include <mysql/mysql.h> #include <mysql/mysql.h>
#include <Poco/Types.h>
#include <mysqlxx/Date.h>
#include <mysqlxx/DateTime.h>
namespace mysqlxx namespace mysqlxx
{ {
typedef unsigned long long UInt64; typedef Poco::UInt64 UInt64;
typedef long long Int64; typedef Poco::Int64 Int64;
typedef unsigned UInt32; typedef Poco::UInt32 UInt32;
typedef int Int32; typedef Poco::Int32 Int32;
typedef unsigned long * MYSQL_LENGTHS; typedef unsigned long * MYSQL_LENGTHS;
typedef MYSQL_FIELD * MYSQL_FIELDS; typedef MYSQL_FIELD * MYSQL_FIELDS;
/// Для совместимости с mysql++ /// Для совместимости с mysql++
typedef time_t sql_datetime; typedef DateTime sql_datetime;
typedef time_t sql_timestamp; typedef DateTime sql_timestamp;
typedef time_t sql_date; typedef Date sql_date;
typedef std::string sql_char; typedef std::string sql_char;
} }

View File

@ -6,6 +6,7 @@
#include <mysqlxx/Manip.h> #include <mysqlxx/Manip.h>
#include <mysqlxx/Pool.h> #include <mysqlxx/Pool.h>
#include <mysqlxx/Date.h> #include <mysqlxx/Date.h>
#include <mysqlxx/DateTime.h>
#include <mysqlxx/Null.h> #include <mysqlxx/Null.h>
/** mysqlxx - чрезвычайно простая библиотека для замены библиотеки mysql++. /** mysqlxx - чрезвычайно простая библиотека для замены библиотеки mysql++.

View File

@ -5,30 +5,46 @@
namespace mysqlxx namespace mysqlxx
{ {
Query::Query(Connection * conn_, const std::string & query_string) : conn(conn_) Query::Query(Connection * conn_, const std::string & query_string) : std::ostream(0), conn(conn_)
{ {
query_stream << query_string; init(&query_buf);
if (!query_string.empty())
{
query_buf.str(query_string);
seekp(0, std::ios::end);
}
imbue(std::locale::classic());
} }
Query::Query(const Query & other) : conn(other.conn) Query::Query(const Query & other)
{ {
query_stream << other.query_stream.rdbuf(); *this = other;
} }
Query & Query::operator= (const Query & other) Query & Query::operator= (const Query & other)
{ {
query_stream << other.query_stream.rdbuf(); conn = other.conn;
seekp(0);
clear();
query_buf.str(other.query_buf.str());
seekp(0, std::ios::end);
return *this; return *this;
} }
void Query::reset() void Query::reset()
{ {
query_stream.str(""); seekp(0);
clear();
query_buf.str("");
} }
void Query::execute() void Query::execute()
{ {
std::string query_string = query_stream.str(); std::string query_string = query_buf.str();
if (mysql_real_query(conn->getDriver(), query_string.data(), query_string.size())) if (mysql_real_query(conn->getDriver(), query_string.data(), query_string.size()))
throw BadQuery(mysql_error(conn->getDriver()), mysql_errno(conn->getDriver())); throw BadQuery(mysql_error(conn->getDriver()), mysql_errno(conn->getDriver()));
} }