From b9161e6e332cb0279ef8616dbbce4c90b60bce15 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 3 Aug 2010 14:12:48 +0200 Subject: New tests --- mysql/makefile | 21 +++ mysql/template/driver.cxx | 46 ++++++ mysql/template/makefile | 88 ++++++++++++ mysql/template/test.hxx | 27 ++++ mysql/template/test.std | 1 + mysql/truncation/driver.cxx | 102 ++++++++++++++ mysql/truncation/makefile | 88 ++++++++++++ mysql/truncation/test.hxx | 48 +++++++ mysql/truncation/test.std | 0 mysql/types/driver.cxx | 108 ++++++++++++++ mysql/types/makefile | 89 ++++++++++++ mysql/types/test.hxx | 335 ++++++++++++++++++++++++++++++++++++++++++++ mysql/types/test.std | 0 mysql/types/traits.hxx | 231 ++++++++++++++++++++++++++++++ 14 files changed, 1184 insertions(+) create mode 100644 mysql/makefile create mode 100644 mysql/template/driver.cxx create mode 100644 mysql/template/makefile create mode 100644 mysql/template/test.hxx create mode 100644 mysql/template/test.std create mode 100644 mysql/truncation/driver.cxx create mode 100644 mysql/truncation/makefile create mode 100644 mysql/truncation/test.hxx create mode 100644 mysql/truncation/test.std create mode 100644 mysql/types/driver.cxx create mode 100644 mysql/types/makefile create mode 100644 mysql/types/test.hxx create mode 100644 mysql/types/test.std create mode 100644 mysql/types/traits.hxx (limited to 'mysql') diff --git a/mysql/makefile b/mysql/makefile new file mode 100644 index 0000000..ae1b83f --- /dev/null +++ b/mysql/makefile @@ -0,0 +1,21 @@ +# file : mysql/makefile +# author : Boris Kolpackov +# copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +# license : GNU GPL; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make + +tests := \ +truncation \ +types \ +template + +default := $(out_base)/ +test := $(out_base)/.test +clean := $(out_base)/.clean + +$(default): $(addprefix $(out_base)/,$(addsuffix /,$(tests))) +$(test): $(addprefix $(out_base)/,$(addsuffix /.test,$(tests))) +$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(tests))) + +$(foreach t,$(tests),$(call import,$(src_base)/$t/makefile)) diff --git a/mysql/template/driver.cxx b/mysql/template/driver.cxx new file mode 100644 index 0000000..76a41bb --- /dev/null +++ b/mysql/template/driver.cxx @@ -0,0 +1,46 @@ +// file : mysql/template/driver.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +// PLACE TEST DESCRIPTION HERE +// + +#include // std::auto_ptr +#include +#include + +#include +#include + +#include + +#include "test.hxx" +#include "test-odb.hxx" + +using namespace std; +using namespace odb; + +using odb::shared_ptr; + +int +main (int argc, char* argv[]) +{ + try + { + auto_ptr db (create_database (argc, argv)); + + // + // + cout << "test 001" << endl; + { + transaction t (db->begin_transaction ()); + t.commit (); + } + } + catch (const odb::exception& e) + { + cerr << e.what () << endl; + return 1; + } +} diff --git a/mysql/template/makefile b/mysql/template/makefile new file mode 100644 index 0000000..a614597 --- /dev/null +++ b/mysql/template/makefile @@ -0,0 +1,88 @@ +# file : mysql/template/makefile +# author : Boris Kolpackov +# copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +# license : GNU GPL v2; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../build/bootstrap.make + +cxx_tun := driver.cxx +odb_hdr := test.hxx +cxx_obj := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o) $(odb_hdr:.hxx=-odb.o)) +cxx_od := $(cxx_obj:.o=.o.d) + +common.l := $(out_root)/libcommon/common.l +common.l.cpp-options := $(out_root)/libcommon/common.l.cpp-options + +driver := $(out_base)/driver +test := $(out_base)/.test +clean := $(out_base)/.clean + +ifdef db_id +ifneq ($(db_id),mysql) +$(error trying to build a MySQL-specific test with $(db_id)) +endif +endif + +# Import. +# +$(call import,\ + $(scf_root)/import/odb/stub.make,\ + odb: odb,odb-rules: odb_rules) + +# Build. +# +$(driver): $(cxx_obj) $(common.l) +$(cxx_obj) $(cxx_od): cpp_options := -I$(out_base) +$(cxx_obj) $(cxx_od): $(common.l.cpp-options) + +genf := $(addprefix $(odb_hdr:.hxx=-odb),.hxx .ixx .cxx) $(odb_hdr:.hxx=.sql) +gen := $(addprefix $(out_base)/,$(genf)) + +$(gen): $(odb) +$(gen): odb := $(odb) +$(gen): odb_options += --database $(db_id) --generate-schema +$(gen): cpp_options := -I$(out_base) +$(gen): $(common.l.cpp-options) + +$(call include-dep,$(cxx_od),$(cxx_obj),$(gen)) + +# Alias for default target. +# +$(out_base)/: $(driver) + +# Test. +# +$(test): $(driver) $(src_base)/test.std + $(call message,sql $$1,$(dcf_root)/db-driver $$1, $(src_base)/test.sql) + $(call message,test $<,$< --options-file $(dcf_root)/db.options \ +| diff -u $(src_base)/test.std -) + +# Clean. +# +$(clean): \ + $(driver).o.clean \ + $(addsuffix .cxx.clean,$(cxx_obj)) \ + $(addsuffix .cxx.clean,$(cxx_od)) \ + $(addprefix $(out_base)/,$(odb_hdr:.hxx=-odb.cxx.hxx.clean)) + +# Generated .gitignore. +# +ifeq ($(out_base),$(src_base)) +$(driver): | $(out_base)/.gitignore + +$(out_base)/.gitignore: files := driver $(genf) +$(clean): $(out_base)/.gitignore.clean + +$(call include,$(bld_root)/git/gitignore.make) +endif + +# How to. +# +$(call include,$(odb_rules)) +$(call include,$(bld_root)/cxx/cxx-d.make) +$(call include,$(bld_root)/cxx/cxx-o.make) +$(call include,$(bld_root)/cxx/o-e.make) + +# Dependencies. +# +$(call import,$(src_root)/libcommon/makefile) diff --git a/mysql/template/test.hxx b/mysql/template/test.hxx new file mode 100644 index 0000000..c71a962 --- /dev/null +++ b/mysql/template/test.hxx @@ -0,0 +1,27 @@ +// file : mysql/template/test.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef TEST_HXX +#define TEST_HXX + +#include + +#pragma odb object +struct object +{ + object (unsigned long id) + : id_ (id) + { + } + + object () + { + } + + #pragma odb id + unsigned long id_; +}; + +#endif // TEST_HXX diff --git a/mysql/template/test.std b/mysql/template/test.std new file mode 100644 index 0000000..af8d8e7 --- /dev/null +++ b/mysql/template/test.std @@ -0,0 +1 @@ +test 001 diff --git a/mysql/truncation/driver.cxx b/mysql/truncation/driver.cxx new file mode 100644 index 0000000..f94205e --- /dev/null +++ b/mysql/truncation/driver.cxx @@ -0,0 +1,102 @@ +// file : mysql/truncation/driver.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +// Test insufficient buffer/truncation handling. +// + +#include // std::auto_ptr +#include +#include + +#include +#include + +#include + +#include "test.hxx" +#include "test-odb.hxx" + +using namespace std; +using namespace odb; + +using odb::shared_ptr; + +int +main (int argc, char* argv[]) +{ + try + { + auto_ptr db (create_database (argc, argv)); + + // The default pre-allocated buffer is 512 bytes long. + // + string long_str (640, 'c'); // This will get the buffer to 1024 + string longer_str (1025, 'b'); + + // Run persist/load so that the initial bindings are established + // (version == 0). + // + { + object1 o (1); + o.str_ = "test string"; + + transaction t (db->begin_transaction ()); + db->persist (o); + db->load (1, o); + t.commit (); + } + + { + object2 o (2); + o.str_ = "test string"; + + transaction t (db->begin_transaction ()); + db->persist (o); + db->load (2, o); + t.commit (); + } + + // Store/load the long string which should trigger buffer growth. + // + { + object1 o (3); + o.str_ = long_str; + + transaction t (db->begin_transaction ()); + db->persist (o); + t.commit (); + } + + { + transaction t (db->begin_transaction ()); + auto_ptr o (db->load (3)); + assert (o->str_ == long_str); + t.commit (); + } + + // Store/load longer string. + // + { + object1 o (3); + o.str_ = longer_str; + + transaction t (db->begin_transaction ()); + db->store (o); + t.commit (); + } + + { + transaction t (db->begin_transaction ()); + auto_ptr o (db->load (3)); + assert (o->str_ == longer_str); + t.commit (); + } + } + catch (const odb::exception& e) + { + cerr << e.what () << endl; + return 1; + } +} diff --git a/mysql/truncation/makefile b/mysql/truncation/makefile new file mode 100644 index 0000000..84eb4f3 --- /dev/null +++ b/mysql/truncation/makefile @@ -0,0 +1,88 @@ +# file : mysql/truncation/makefile +# author : Boris Kolpackov +# copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +# license : GNU GPL v2; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../build/bootstrap.make + +cxx_tun := driver.cxx +odb_hdr := test.hxx +cxx_obj := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o) $(odb_hdr:.hxx=-odb.o)) +cxx_od := $(cxx_obj:.o=.o.d) + +common.l := $(out_root)/libcommon/common.l +common.l.cpp-options := $(out_root)/libcommon/common.l.cpp-options + +driver := $(out_base)/driver +test := $(out_base)/.test +clean := $(out_base)/.clean + +ifdef db_id +ifneq ($(db_id),mysql) +$(error trying to build a MySQL-specific test with $(db_id)) +endif +endif + +# Import. +# +$(call import,\ + $(scf_root)/import/odb/stub.make,\ + odb: odb,odb-rules: odb_rules) + +# Build. +# +$(driver): $(cxx_obj) $(common.l) +$(cxx_obj) $(cxx_od): cpp_options := -I$(out_base) +$(cxx_obj) $(cxx_od): $(common.l.cpp-options) + +genf := $(addprefix $(odb_hdr:.hxx=-odb),.hxx .ixx .cxx) $(odb_hdr:.hxx=.sql) +gen := $(addprefix $(out_base)/,$(genf)) + +$(gen): $(odb) +$(gen): odb := $(odb) +$(gen): odb_options += --database $(db_id) --generate-schema +$(gen): cpp_options := -I$(out_base) +$(gen): $(common.l.cpp-options) + +$(call include-dep,$(cxx_od),$(cxx_obj),$(gen)) + +# Alias for default target. +# +$(out_base)/: $(driver) + +# Test. +# +$(test): $(driver) $(src_base)/test.std + $(call message,sql $$1,$(dcf_root)/db-driver $$1, $(src_base)/test.sql) + $(call message,test $<,$< --options-file $(dcf_root)/db.options \ +| diff -u $(src_base)/test.std -) + +# Clean. +# +$(clean): \ + $(driver).o.clean \ + $(addsuffix .cxx.clean,$(cxx_obj)) \ + $(addsuffix .cxx.clean,$(cxx_od)) \ + $(addprefix $(out_base)/,$(odb_hdr:.hxx=-odb.cxx.hxx.clean)) + +# Generated .gitignore. +# +ifeq ($(out_base),$(src_base)) +$(driver): | $(out_base)/.gitignore + +$(out_base)/.gitignore: files := driver $(genf) +$(clean): $(out_base)/.gitignore.clean + +$(call include,$(bld_root)/git/gitignore.make) +endif + +# How to. +# +$(call include,$(odb_rules)) +$(call include,$(bld_root)/cxx/cxx-d.make) +$(call include,$(bld_root)/cxx/cxx-o.make) +$(call include,$(bld_root)/cxx/o-e.make) + +# Dependencies. +# +$(call import,$(src_root)/libcommon/makefile) diff --git a/mysql/truncation/test.hxx b/mysql/truncation/test.hxx new file mode 100644 index 0000000..4e1c1bc --- /dev/null +++ b/mysql/truncation/test.hxx @@ -0,0 +1,48 @@ +// file : mysql/truncation/test.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef TEST_HXX +#define TEST_HXX + +#include +#include + +#pragma odb object table ("test") +struct object1 +{ + object1 (unsigned long id) + : id_ (id) + { + } + + object1 () + { + } + + #pragma odb id + unsigned long id_; + + std::string str_; +}; + +#pragma odb object table ("test") +struct object2 +{ + object2 (unsigned long id) + : id_ (id) + { + } + + object2 () + { + } + + #pragma odb id + unsigned long id_; + + std::string str_; +}; + +#endif // TEST_HXX diff --git a/mysql/truncation/test.std b/mysql/truncation/test.std new file mode 100644 index 0000000..e69de29 diff --git a/mysql/types/driver.cxx b/mysql/types/driver.cxx new file mode 100644 index 0000000..1221d5c --- /dev/null +++ b/mysql/types/driver.cxx @@ -0,0 +1,108 @@ +// file : mysql/types/driver.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +// Test MySQL type conversion. +// + +#include // std::auto_ptr +#include +#include + +#include +#include + +#include + +#include "test.hxx" +#include "test-odb.hxx" + +using namespace std; +using namespace odb; + +using odb::shared_ptr; + +int +main (int argc, char* argv[]) +{ + try + { + auto_ptr db (create_database (argc, argv)); + + object o (1); + + o.bool_ = true; + o.schar_ = -123; + o.uchar_ = 123; + o.short_ = -12345; + o.ushort_ = 12345; + o.mint_ = -123456; + o.umint_ = 123456; + o.int_ = -123456; + o.uint_ = 123456; + o.long_long_ = -123456; + o.ulong_long_ = 123456; + + o.float_ = 1.123; + o.double_ = 1.123; + o.decimal_ = "123.456"; + + o.date_ = date_time (false, 2010, 8, 29, 0, 0, 0); + o.time_ = date_time (true, 0, 0, 0, 12, 26, 59); + o.date_time_ = date_time (false, 2010, 8, 29, 12, 26, 59); + o.timestamp_ = date_time (false, 2010, 8, 29, 12, 26, 59); + o.year_ = 2010; + + string short_str (128, 's'); + ::buffer short_buf (short_str.c_str (), short_str.size ()); + string medium_str (250, 'm'); + ::buffer medium_buf (medium_str.c_str (), medium_str.size ()); + string long_str (2040, 'l'); + ::buffer long_buf (long_str.c_str (), long_str.size ()); + + o.char_ = short_str; + o.binary_ = short_buf; + o.varchar_ = medium_str; + o.varbinary_ = medium_buf; + o.tinytext_ = short_str; + o.tinyblob_ = short_buf; + o.text_ = long_str; + o.blob_ = long_buf; + o.mediumtext_ = long_str; + o.mediumblob_ = long_buf; + o.longtext_ = long_str; + o.longblob_ = long_buf; + + o.bit_.a = 1; + o.bit_.b = 0; + o.bit_.c = 0; + o.bit_.d = 1; + + o.enum_ = "green"; + o.set_.insert ("green"); + o.set_.insert ("red"); + o.set_.insert ("blue"); + + { + transaction t (db->begin_transaction ()); + db->persist (o); + t.commit (); + } + + // + // + { + transaction t (db->begin_transaction ()); + auto_ptr o1 (db->load (1)); + t.commit (); + + assert (o == *o1); + } + } + catch (const odb::exception& e) + { + cerr << e.what () << endl; + return 1; + } +} diff --git a/mysql/types/makefile b/mysql/types/makefile new file mode 100644 index 0000000..bf23a69 --- /dev/null +++ b/mysql/types/makefile @@ -0,0 +1,89 @@ +# file : mysql/types/makefile +# author : Boris Kolpackov +# copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +# license : GNU GPL v2; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../build/bootstrap.make + +cxx_tun := driver.cxx +odb_hdr := test.hxx +cxx_obj := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o) $(odb_hdr:.hxx=-odb.o)) +cxx_od := $(cxx_obj:.o=.o.d) + +common.l := $(out_root)/libcommon/common.l +common.l.cpp-options := $(out_root)/libcommon/common.l.cpp-options + +driver := $(out_base)/driver +test := $(out_base)/.test +clean := $(out_base)/.clean + +ifdef db_id +ifneq ($(db_id),mysql) +$(error trying to build a MySQL-specific test with $(db_id)) +endif +endif + +# Import. +# +$(call import,\ + $(scf_root)/import/odb/stub.make,\ + odb: odb,odb-rules: odb_rules) + +# Build. +# +$(driver): $(cxx_obj) $(common.l) +$(cxx_obj) $(cxx_od): cpp_options := -I$(out_base) +$(cxx_obj) $(cxx_od): $(common.l.cpp-options) + +genf := $(addprefix $(odb_hdr:.hxx=-odb),.hxx .ixx .cxx) $(odb_hdr:.hxx=.sql) +gen := $(addprefix $(out_base)/,$(genf)) + +$(gen): $(odb) +$(gen): odb := $(odb) +$(gen): odb_options += --database $(db_id) --generate-schema \ +--cxx-prologue '\\\#include "traits.hxx"' +$(gen): cpp_options := -I$(out_base) +$(gen): $(common.l.cpp-options) + +$(call include-dep,$(cxx_od),$(cxx_obj),$(gen)) + +# Alias for default target. +# +$(out_base)/: $(driver) + +# Test. +# +$(test): $(driver) $(src_base)/test.std + $(call message,sql $$1,$(dcf_root)/db-driver $$1, $(src_base)/test.sql) + $(call message,test $<,$< --options-file $(dcf_root)/db.options \ +| diff -u $(src_base)/test.std -) + +# Clean. +# +$(clean): \ + $(driver).o.clean \ + $(addsuffix .cxx.clean,$(cxx_obj)) \ + $(addsuffix .cxx.clean,$(cxx_od)) \ + $(addprefix $(out_base)/,$(odb_hdr:.hxx=-odb.cxx.hxx.clean)) + +# Generated .gitignore. +# +ifeq ($(out_base),$(src_base)) +$(driver): | $(out_base)/.gitignore + +$(out_base)/.gitignore: files := driver $(genf) +$(clean): $(out_base)/.gitignore.clean + +$(call include,$(bld_root)/git/gitignore.make) +endif + +# How to. +# +$(call include,$(odb_rules)) +$(call include,$(bld_root)/cxx/cxx-d.make) +$(call include,$(bld_root)/cxx/cxx-o.make) +$(call include,$(bld_root)/cxx/o-e.make) + +# Dependencies. +# +$(call import,$(src_root)/libcommon/makefile) diff --git a/mysql/types/test.hxx b/mysql/types/test.hxx new file mode 100644 index 0000000..7f2ce4d --- /dev/null +++ b/mysql/types/test.hxx @@ -0,0 +1,335 @@ +// file : mysql/types/test.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef TEST_HXX +#define TEST_HXX + +#include +#include +#include // std::auto_ptr +#include // std::size_t +#include // std::{memcmp,memcpy} + +#include + +struct date_time +{ + date_time () + { + } + + date_time (bool n, + unsigned int y, + unsigned int m, + unsigned int d, + unsigned int h, + unsigned int min, + unsigned int sec) + : negative (n), + year (y), + month (m), + day (d), + hour (h), + minute (min), + second (sec) + { + } + + bool + operator== (const date_time& y) + { + return + negative == y.negative && + year == y.year && + month == y.month && + day == y.day && + hour == y.hour && + minute == y.minute && + second == y.second; + } + + bool negative; + unsigned int year; + unsigned int month; + unsigned int day; + unsigned int hour; + unsigned int minute; + unsigned int second; +}; + +struct buffer +{ + ~buffer () + { + delete[] data_; + } + + buffer () + : data_ (0), size_ (0) + { + } + + buffer (const void* data, std::size_t size) + : data_ (0), size_ (size) + { + data_ = new char[size_]; + std::memcpy (data_, data, size_); + } + + buffer (const buffer& y) + : data_ (0), size_ (0) + { + assign (y.data_, y.size_); + } + + buffer& + operator= (const buffer& y) + { + if (this != &y) + assign (y.data_, y.size_); + + return *this; + } + + void + assign (const void* data, std::size_t size) + { + if (size_ < size) + { + char* p (new char[size]); + delete[] data_; + data_ = p; + } + + std::memcpy (data_, data, size); + size_ = size; + } + + char* + data () + { + return data_; + } + + const char* + data () const + { + return data_; + } + + std::size_t + size () const + { + return size_; + } + + bool + operator== (const buffer& y) + { + return size_ == y.size_ && std::memcmp (data_, y.data_, size_) == 0; + } + +private: + char* data_; + std::size_t size_; +}; + +struct bitfield +{ + unsigned int a: 1; + unsigned int b: 1; + unsigned int c: 1; + unsigned int d: 1; +}; + +inline bool +operator== (bitfield x, bitfield y) +{ + return + x.a == y.a && + x.b == y.b && + x.c == y.c && + x.d == y.d; +} + +typedef std::set set; +typedef std::auto_ptr string_ptr; + +#pragma odb object +struct object +{ + object (unsigned long id) + : id_ (id) + { + } + + object () + { + } + + #pragma odb id + unsigned long id_; + + // Integral types. + // + #pragma odb type ("BOOL NOT NULL") + bool bool_; + + #pragma odb type ("TINYINT NOT NULL") + signed char schar_; + + #pragma odb type ("TINYINT UNSIGNED NOT NULL") + unsigned char uchar_; + + #pragma odb type ("SMALLINT NOT NULL") + short short_; + + #pragma odb type ("SMALLINT UNSIGNED NOT NULL") + unsigned short ushort_; + + #pragma odb type ("MEDIUMINT NOT NULL") + int mint_; + + #pragma odb type ("MEDIUMINT UNSIGNED NOT NULL") + unsigned int umint_; + + #pragma odb type ("INT NOT NULL") + int int_; + + #pragma odb type ("INT UNSIGNED NOT NULL") + unsigned int uint_; + + #pragma odb type ("BIGINT NOT NULL") + long long long_long_; + + #pragma odb type ("BIGINT UNSIGNED NOT NULL") + unsigned long long ulong_long_; + + // Float types. + // + #pragma odb type ("FLOAT NOT NULL") + float float_; + + #pragma odb type ("DOUBLE NOT NULL") + double double_; + + #pragma odb type ("DECIMAL(6,3) NOT NULL") + std::string decimal_; + + // Data-time types. + // + #pragma odb type ("DATE NOT NULL") + date_time date_; + + #pragma odb type ("TIME NOT NULL") + date_time time_; + + #pragma odb type ("DATETIME NOT NULL") + date_time date_time_; + + #pragma odb type ("TIMESTAMP NOT NULL") + date_time timestamp_; + + #pragma odb type ("YEAR NOT NULL") + short year_; + + // String and binary types. + // + #pragma odb type ("CHAR(128) NOT NULL") + std::string char_; + + #pragma odb type ("BINARY(128) NOT NULL") + buffer binary_; + + #pragma odb type ("VARCHAR(256) NOT NULL") + std::string varchar_; + + #pragma odb type ("VARBINARY(256) NOT NULL") + buffer varbinary_; + + #pragma odb type ("TINYTEXT NOT NULL") + std::string tinytext_; + + #pragma odb type ("TINYBLOB NOT NULL") + buffer tinyblob_; + + #pragma odb type ("TEXT NOT NULL") + std::string text_; + + #pragma odb type ("BLOB NOT NULL") + buffer blob_; + + #pragma odb type ("MEDIUMTEXT NOT NULL") + std::string mediumtext_; + + #pragma odb type ("MEDIUMBLOB NOT NULL") + buffer mediumblob_; + + #pragma odb type ("LONGTEXT NOT NULL") + std::string longtext_; + + #pragma odb type ("LONGBLOB NOT NULL") + buffer longblob_; + + // Other types. + // + #pragma odb type ("BIT(4) NOT NULL") + bitfield bit_; + + #pragma odb type ("ENUM('red', 'green', 'blue') NOT NULL") + std::string enum_; + + #pragma odb type ("SET('red', 'green', 'blue') NOT NULL") + set set_; + + // Test NULL value. + // + #pragma odb type ("TEXT") + string_ptr null_; + + bool + operator== (const object& y) + { + return + id_ == y.id_ && + bool_ == y.bool_ && + schar_ == y.schar_ && + uchar_ == y.uchar_ && + short_ == y.short_ && + ushort_ == y.ushort_ && + mint_ == y.mint_ && + umint_ == y.umint_ && + int_ == y.int_ && + uint_ == y.uint_ && + long_long_ == y.long_long_ && + ulong_long_ == y.ulong_long_ && + float_ == y.float_ && + double_ == y.double_ && + decimal_ == y.decimal_ && + date_ == y.date_ && + time_ == y.time_ && + date_time_ == y.date_time_ && + timestamp_ == y.timestamp_ && + year_ == y.year_ && + char_ == y.char_ && + binary_ == y.binary_ && + varchar_ == y.varchar_ && + varbinary_ == y.varbinary_ && + tinytext_ == y.tinytext_ && + tinyblob_ == y.tinyblob_ && + text_ == y.text_ && + blob_ == y.blob_ && + mediumtext_ == y.mediumtext_ && + mediumblob_ == y.mediumblob_ && + longtext_ == y.longtext_ && + longblob_ == y.longblob_ && + bit_ == y.bit_ && + enum_ == y.enum_ && + set_ == y.set_ && + null_.get () == 0 && y.null_.get () == 0 || *null_ == *y.null_; + } +}; + +#endif // TEST_HXX diff --git a/mysql/types/test.std b/mysql/types/test.std new file mode 100644 index 0000000..e69de29 diff --git a/mysql/types/traits.hxx b/mysql/types/traits.hxx new file mode 100644 index 0000000..0db33aa --- /dev/null +++ b/mysql/types/traits.hxx @@ -0,0 +1,231 @@ +// file : mysql/types/traits.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef TRAITS_HXX +#define TRAITS_HXX + +#include // std::memcpy, std::memset + +#include + +#include "test.hxx" // date_time + +namespace odb +{ + namespace mysql + { + template <> + class value_traits + { + public: + typedef date_time value_type; + + static void + set_value (date_time& v, const MYSQL_TIME& i, bool is_null) + { + if (!is_null) + { + v.negative = i.neg; + v.year = i.year; + v.month = i.month; + v.day = i.day; + v.hour = i.hour; + v.minute = i.minute; + v.second = i.second; + } + else + v = date_time (); + } + + static void + set_image (MYSQL_TIME& i, bool& is_null, const date_time& v) + { + is_null = false; + i.neg = v.negative; + i.year = v.year; + i.month = v.month; + i.day = v.day; + i.hour = v.hour; + i.minute = v.minute; + i.second = v.second; + i.second_part = 0; + } + }; + + template <> + class value_traits< ::buffer > + { + public: + typedef ::buffer value_type; + + static void + set_value (value_type& v, const char* s, std::size_t n, bool is_null) + { + if (!is_null) + v.assign (s, n); + else + v.assign (0, 0); + } + + static void + set_image (char* s, + std::size_t c, + std::size_t& n, + bool& is_null, + const value_type& v) + { + is_null = false; + n = v.size (); + + if (n > c) + n = c; + + if (n != 0) + std::memcpy (s, v.data (), n); + } + + static void + set_image (odb::buffer& b, + std::size_t& n, + bool& is_null, + const value_type& v) + { + is_null = false; + n = v.size (); + + if (n > b.capacity ()) + b.capacity (n); + + if (n != 0) + std::memcpy (b.data (), v.data (), n); + } + }; + + template <> + class value_traits + { + public: + typedef bitfield value_type; + + static void + set_value (bitfield& v, + const unsigned char* s, + std::size_t n, + bool is_null) + { + if (!is_null) + std::memcpy (&v, s, 1); + else + std::memset (&v, 0, sizeof (bitfield)); + } + + static void + set_image (unsigned char* s, + std::size_t c, + std::size_t& n, + bool& is_null, + bitfield v) + { + is_null = false; + n = 1; + std::memcpy (s, &v, 1); + } + }; + + template <> + class value_traits + { + public: + typedef set value_type; + + static void + set_value (set& v, const char* s, std::size_t n, bool is_null) + { + v.clear (); + + if (!is_null) + { + const char* e (s + n); + + while (s < e) + { + const char* p (s); + + while (p < e && *p != ',') + ++p; + + v.insert (std::string (s, p - s)); + s = p; + + if (p != e) + ++s; + } + } + } + + static void + set_image (odb::buffer& buf, + std::size_t& n, + bool& is_null, + const value_type& v) + { + is_null = false; + n = 0; + + for (set::const_iterator b (v.begin ()), i (b); i != v.end (); ++i) + { + std::size_t m (i->size () + (i != b ? 1 : 0)); + + if (n + m > buf.capacity ()) + buf.capacity (n + m, n); + + if (i != b) + buf.data ()[n++] = ','; + + std::memcpy (buf.data () + n, i->c_str (), i->size ()); + n += i->size (); + } + } + }; + + template <> + class value_traits > + { + public: + typedef std::auto_ptr value_type; + + static void + set_value (std::auto_ptr& v, + const char* s, + std::size_t n, + bool is_null) + { + v.reset (is_null ? 0 : new std::string (s, n)); + } + + static void + set_image (odb::buffer& b, + std::size_t& n, + bool& is_null, + const std::auto_ptr& v) + { + is_null = v.get () == 0; + + if (!is_null) + { + n = v->size (); + + if (n > b.capacity ()) + b.capacity (n); + + if (n != 0) + std::memcpy (b.data (), v->c_str (), n); + } + } + }; + } +} + +#endif // TRAITS_HXX -- cgit v1.1