1 #ifndef ROSE_SqlDatabase_H
2 #define ROSE_SqlDatabase_H
7 #include <boost/enable_shared_from_this.hpp>
8 #include <boost/shared_ptr.hpp>
116 namespace SqlDatabase {
131 class ConnectionImpl;
133 class TransactionImpl;
159 explicit Exception(
const char *mesg): std::runtime_error(mesg) {}
160 explicit Exception(
const std::string &mesg): std::runtime_error(mesg) {}
169 virtual const char *
what()
const throw() ;
170 void print(std::ostream&) const;
190 friend class TransactionImpl;
192 friend class StatementImpl;
201 if (
NO_DRIVER==(driver = guess_driver(open_spec)))
202 throw Exception(
"no suitable driver for \""+open_spec+
"\"");
214 static Driver guess_driver(
const std::string &open_spec);
220 std::string openspec()
const;
225 void set_debug(FILE *f);
226 FILE *get_debug()
const;
230 void print(std::ostream&)
const;
241 void init(
const std::string &open_spec,
Driver driver);
257 class Transaction:
public boost::enable_shared_from_this<Transaction> {
258 friend class ConnectionImpl;
260 friend class StatementImpl;
279 bool is_terminated()
const;
287 void execute(
const std::string &sql);
292 void bulk_load(
const std::string &tablename, std::istream&);
304 void set_debug(FILE *f);
305 FILE *get_debug()
const;
309 void print(std::ostream&)
const;
338 class Statement:
public boost::enable_shared_from_this<Statement> {
354 : stmt(stmt), execution_seq(execution_seq), row_num(0) {
init(); }
355 template<
typename T> T
get(
size_t idx);
356 int32_t get_i32(
size_t idx);
357 int64_t get_i64(
size_t idx);
358 uint32_t get_u32(
size_t idx);
359 uint64_t get_u64(
size_t idx);
360 double get_dbl(
size_t idx);
361 std::string get_str(
size_t idx);
410 void set_debug(FILE *f);
411 FILE *get_debug()
const;
415 void print(std::ostream&)
const;
432 template<>
NoColumn Statement::iterator::get<NoColumn>(
size_t idx);
433 template<> int64_t Statement::iterator::get<int64_t>(
size_t idx);
434 template<> uint64_t Statement::iterator::get<uint64_t>(
size_t idx);
435 template<> int32_t Statement::iterator::get<int32_t>(
size_t idx);
436 template<> uint32_t Statement::iterator::get<uint32_t>(
size_t idx);
437 template<>
float Statement::iterator::get<float>(
size_t idx);
438 template<>
double Statement::iterator::get<double>(
size_t idx);
439 template<> std::string Statement::iterator::get<std::string>(
size_t idx);
446 std::vector<std::string>
split_sql(
const std::string &sql);
449 std::string
escape(
const std::string&,
Driver,
bool do_quote=
true);
455 template<
class Container>
456 std::string
in(
const Container &values)
458 std::ostringstream retval;
461 for (
typename Container::const_iterator vi=values.begin(); vi!=values.end(); ++vi, ++nvals)
462 retval <<(nvals?
", ":
"") <<*vi;
468 template<
class Container,
class Stringifier>
469 std::string
in_numbers(
const Container &values, Stringifier &stringifier)
476 template<
class Container>
479 std::vector<std::string> strings;
480 for (
typename Container::const_iterator vi=values.begin(); vi!=values.end(); ++vi)
481 strings.push_back(
escape(*vi, driver));
485 std::ostream&
operator<<(std::ostream&,
const NoColumn&);
487 std::ostream&
operator<<(std::ostream&,
const Connection&);
488 std::ostream&
operator<<(std::ostream&,
const Transaction&);
489 std::ostream&
operator<<(std::ostream&,
const Statement&);
498 enum { valid_column = 1 };
501 enum { valid_column = 0 };
512 virtual std::string
operator()(
const T &value,
size_t width)
const {
513 std::ostringstream ss;
525 virtual std::string
operator()(
const std::string &value,
size_t width)
const {
526 return value + std::string(width,
' ');
534 virtual std::string
operator()(
const uint64_t &value,
size_t width)
const {
548 explicit TimeRenderer(
const std::string &format,
bool local_tz=
true): local_tz(local_tz), format(format) {}
549 virtual std::string operator()(
const time_t &value,
size_t width)
const ;
556 template<
typename Table>
560 virtual void operator()(std::ostream &out,
const Table *table,
size_t rownum,
const std::vector<size_t> &widths) {}
567 void operator()(std::ostream &out,
const std::string &
prefix,
const std::string &hdr,
size_t width) {
569 out <<prefix <<std::setw(width) <<hdr;
575 void operator()(std::ostream &out,
const std::string &
prefix,
const std::string &hdr,
size_t width) {
577 out <<prefix <<std::setw(width) <<std::left <<hdr;
583 void operator()(std::ostream &out,
const std::string &
prefix,
const std::string &hdr,
size_t width) {}
591 out <<prefix <<std::string(width,
'-');
673 template<
typename T00,
typename T01=NoColumn,
typename T02=NoColumn,
typename T03=NoColumn,
674 typename T04=NoColumn,
typename T05=NoColumn,
typename T06=NoColumn,
typename T07=NoColumn,
675 typename T08=NoColumn,
typename T09=NoColumn,
typename T10=NoColumn,
typename T11=NoColumn,
676 typename T12=NoColumn,
typename T13=NoColumn,
typename T14=NoColumn,
typename T15=NoColumn>
685 explicit Tuple(
const T00 &v0,
const T01 &v1 =T01(),
const T02 &v2 =T02(),
const T03 &v3 =T03(),
686 const T04 &v4 =T04(),
const T05 &v5 =T05(),
const T06 &v6 =T06(),
const T07 &v7 =T07(),
687 const T08 &v8 =T08(),
const T09 &v9 =T09(),
const T10 &v10=T10(),
const T11 &v11=T11(),
688 const T12 &v12=T12(),
const T13 &v13=T13(),
const T14 &v14=T14(),
const T15 &v15=T15())
689 : v0(v0), v1(v1), v2(v2), v3(v3), v4(v4), v5(v5), v6(v6), v7(v7),
690 v8(v8), v9(v9), v10(v10), v11(v11), v12(v12), v13(v13), v14(v14), v15(v15) {}
691 T00 v0; T01 v1; T02 v2; T03 v3; T04 v4; T05 v5; T06 v6; T07
v7;
692 T08 v8; T09
v9; T10 v10; T11 v11; T12 v12; T13 v13; T14 v14; T15 v15;
705 : r0(r0), r1(r1), r2(r2), r3(r3), r4(r4), r5(r5), r6(r6), r7(r7),
706 r8(r8), r9(r9), r10(r10), r11(r11), r12(r12), r13(r13), r14(r14), r15(r15) {}
714 typedef std::vector<Tuple>
Rows;
717 Table(): headers_(MAXCOLS), colsep_(
" | "), pre_row_(NULL), post_row_(NULL), reprint_headers_(0) {}
721 : headers_(MAXCOLS), colsep_(
" | "), pre_row_(NULL), post_row_(NULL), reprint_headers_(0) {
727 void header(
int colnum,
const std::string &hdr) {
728 assert(colnum<headers_.size());
729 headers_[colnum] = hdr;
731 const std::string&
header(
int colnum)
const {
732 assert(colnum<headers_.size());
733 return headers_[colnum];
735 void headers(
const std::string &h0,
const std::string &h1=
"",
const std::string &h2=
"",
const std::string &h3=
"",
736 const std::string &h4=
"",
const std::string &h5=
"",
const std::string &h6=
"",
const std::string &h7=
"",
737 const std::string &h8=
"",
const std::string &h9=
"",
const std::string &h10=
"",
const std::string &h11=
"",
738 const std::string &h12=
"",
const std::string &h13=
"",
const std::string &h14=
"",
const std::string &h15=
"") {
739 headers_[ 0] = h0; headers_[ 1] = h1; headers_[ 2] = h2; headers_[ 3] = h3;
740 headers_[ 4] = h4; headers_[ 5] = h5; headers_[ 6] = h6; headers_[ 7] = h7;
741 headers_[ 8] = h8; headers_[ 9] = h9; headers_[10] = h10; headers_[11] = h11;
742 headers_[12] = h12; headers_[13] = h13; headers_[14] = h14; headers_[15] = h15;
779 return std::make_pair(pre_row_, post_row_);
784 size_t size()
const {
return rows_.size(); }
787 bool empty()
const {
return rows_.empty(); }
802 void insert(
const T00 &v00,
const T01 &v01=T01(),
const T02 &v02=T02(),
const T03 &v03=T03(),
803 const T04 &v04=T04(),
const T05 &v05=T05(),
const T06 &v06=T06(),
const T07 &v07=T07(),
804 const T08 &v08=T08(),
const T09 &v09=T09(),
const T10 &v10=T10(),
const T11 &v11=T11(),
805 const T12 &v12=T12(),
const T13 &v13=T13(),
const T14 &v14=T14(),
const T15 &v15=T15()) {
806 rows_.push_back(
Tuple(v00, v01, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12, v13, v14, v15));
813 rows_.push_back(
Tuple(row.get<T00>( 0), row.get<T01>( 1), row.get<T02>( 2), row.get<T03>( 3),
814 row.get<T04>( 4), row.get<T05>( 5), row.get<T06>( 6), row.get<T07>( 7),
815 row.get<T08>( 8), row.get<T09>( 9), row.get<T10>(10), row.get<T11>(11),
816 row.get<T12>(12), row.get<T13>(13), row.get<T14>(14), row.get<T15>(15)));
832 std::string s = (*r)(value, width);
834 s = s.substr(0, width);
841 std::vector<size_t> widths(MAXCOLS, 0);
842 for (
typename Rows::const_iterator ri=rows_.begin(); ri!=rows_.end(); ++ri) {
843 widths[ 0] =
std::max(widths[ 0], render(render_.r0, ri->v0 ).size());
844 widths[ 1] =
std::max(widths[ 1], render(render_.r1, ri->v1 ).size());
845 widths[ 2] =
std::max(widths[ 2], render(render_.r2, ri->v2 ).size());
846 widths[ 3] =
std::max(widths[ 3], render(render_.r3, ri->v3 ).size());
847 widths[ 4] =
std::max(widths[ 4], render(render_.r4, ri->v4 ).size());
848 widths[ 5] =
std::max(widths[ 5], render(render_.r5, ri->v5 ).size());
849 widths[ 6] =
std::max(widths[ 6], render(render_.r6, ri->v6 ).size());
850 widths[ 7] =
std::max(widths[ 7], render(render_.r7, ri->v7 ).size());
851 widths[ 8] =
std::max(widths[ 8], render(render_.r8, ri->v8 ).size());
852 widths[ 9] =
std::max(widths[ 9], render(render_.r9, ri->v9 ).size());
853 widths[10] =
std::max(widths[10], render(render_.r10, ri->v10).size());
854 widths[11] =
std::max(widths[11], render(render_.r11, ri->v11).size());
855 widths[12] =
std::max(widths[12], render(render_.r12, ri->v12).size());
856 widths[13] =
std::max(widths[13], render(render_.r13, ri->v13).size());
857 widths[14] =
std::max(widths[14], render(render_.r14, ri->v14).size());
858 widths[15] =
std::max(widths[15], render(render_.r15, ri->v15).size());
864 void print_headers(std::ostream &out,
const std::vector<size_t> &widths)
const {
865 Header<T00>()(out, prefix_, headers_[ 0], widths[ 0]);
866 Header<T01>()(out, colsep_, headers_[ 1], widths[ 1]);
867 Header<T02>()(out, colsep_, headers_[ 2], widths[ 2]);
868 Header<T03>()(out, colsep_, headers_[ 3], widths[ 3]);
869 Header<T04>()(out, colsep_, headers_[ 4], widths[ 4]);
870 Header<T05>()(out, colsep_, headers_[ 5], widths[ 5]);
871 Header<T06>()(out, colsep_, headers_[ 6], widths[ 6]);
872 Header<T07>()(out, colsep_, headers_[ 7], widths[ 7]);
873 Header<T08>()(out, colsep_, headers_[ 8], widths[ 8]);
874 Header<T09>()(out, colsep_, headers_[ 9], widths[ 9]);
875 Header<T10>()(out, colsep_, headers_[10], widths[10]);
876 Header<T11>()(out, colsep_, headers_[11], widths[11]);
877 Header<T12>()(out, colsep_, headers_[12], widths[12]);
878 Header<T13>()(out, colsep_, headers_[13], widths[13]);
879 Header<T14>()(out, colsep_, headers_[14], widths[14]);
880 Header<T15>()(out, colsep_, headers_[15], widths[15]);
885 void print_rowsep(std::ostream &out,
const std::vector<size_t> &widths)
const {
886 std::string colsep = colsep_;
887 for (
size_t i=0; i<colsep.size(); ++i) {
888 if (isspace(colsep[i])) {
890 }
else if (
'|'==colsep[i]) {
915 print_row(std::ostream &out,
const Tuple &t,
const std::vector<size_t> &widths)
const {
917 out << prefix_ <<std::setw(widths[ 0]) <<render(render_.r0, t.
v0, widths[ 0])
937 void print(std::ostream &out)
const {
938 std::vector<size_t> widths = colsizes();
941 bool has_headers =
false;
942 for (
size_t i=0; i<MAXCOLS; ++i) {
943 widths[i] =
std::max(widths[i], headers_[i].size());
944 if (!headers_[i].empty())
948 print_headers(out, widths);
949 print_rowsep(out, widths);
954 out <<prefix_ <<
"(0 rows)\n\n";
956 for (
size_t i=0; i<rows_.size(); ++i) {
957 if (i>0 && has_headers && reprint_headers_>0 && 0==i%reprint_headers_) {
958 print_rowsep(out, widths);
959 print_headers(out, widths);
960 print_rowsep(out, widths);
963 (*pre_row_)(out,
this, i, widths);
964 print_row(out, rows_[i], widths);
966 (*post_row_)(out,
this, i, widths);
971 if (has_headers && !rows_.empty())
972 print_rowsep(out, widths);