From b219ba0db198bf8fdf68f71559e94ac4dc991aa7 Mon Sep 17 00:00:00 2001 From: cxl Date: Tue, 17 Sep 2013 13:22:26 +0000 Subject: [PATCH] Sql: SqlExp support for Insert...From...GroupBy...Having, S_* now has Get and GetColumnIds git-svn-id: svn://ultimatepp.org/upp/trunk@6365 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Sql/SqlStatement.cpp | 13 ++++++++++--- uppsrc/Sql/Sqlexp.h | 7 +++++++ uppsrc/Sql/sch_header.h | 10 ++++++---- uppsrc/Sql/sch_source.h | 22 +++++++++++++++++++--- 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/uppsrc/Sql/SqlStatement.cpp b/uppsrc/Sql/SqlStatement.cpp index 92d1049c4..bf4a7ca75 100644 --- a/uppsrc/Sql/SqlStatement.cpp +++ b/uppsrc/Sql/SqlStatement.cpp @@ -302,12 +302,19 @@ SqlInsert::operator SqlStatement() const { String s = "insert into " + table.Quoted(); if(!set1.IsEmpty()) { s << set1(); - if(from.IsEmpty() && where.IsEmpty()) { + if(from.IsEmpty() && where.IsEmpty() && groupby.IsEmpty()) { if(!set2.IsEmpty()) s << " values " << set2(); } - else - s << ' ' + SqlStatement(Select(set2).From(from).Where(where)).GetText(); + else { + SqlSelect sel; + sel = Select(set2).From(from).Where(where); + if(!groupby.IsEmpty()) + sel.GroupBy(groupby); + if(!having.IsEmpty()) + sel.Having(having); + s << ' ' + SqlStatement(sel).GetText(); + } } return SqlStatement(s); } diff --git a/uppsrc/Sql/Sqlexp.h b/uppsrc/Sql/Sqlexp.h index afd8c1442..114ddfcb7 100644 --- a/uppsrc/Sql/Sqlexp.h +++ b/uppsrc/Sql/Sqlexp.h @@ -628,6 +628,8 @@ class SqlInsert { SqlSet set2; SqlSet from; SqlBool where; + SqlSet groupby; + SqlBool having; public: void Column(const SqlId& column, SqlVal val); @@ -640,6 +642,11 @@ public: SqlInsert& From(SqlSet _from) { from = _from; return *this; } SqlInsert& From(SqlVal from) { return From(SqlSet(from)); } SqlInsert& Where(SqlBool w) { where = w; return *this; } + SqlInsert& GroupBy(const SqlSet& columnset) { groupby = columnset; return *this; } + SqlInsert& GroupBy(SqlVal a) { return GroupBy(SqlSet(a)); } + SqlInsert& GroupBy(SqlVal a, SqlVal b) { return GroupBy(SqlSet(a, b)); } + SqlInsert& GroupBy(SqlVal a, SqlVal b, SqlVal c) { return GroupBy(SqlSet(a, b, c)); } + SqlInsert& Having(const SqlBool& exp) { having = exp; return *this; } SqlId GetTable() const { return table; } SqlId GetKeyColumn() const { return keycolumn; } diff --git a/uppsrc/Sql/sch_header.h b/uppsrc/Sql/sch_header.h index e27f68d0c..0317d6126 100644 --- a/uppsrc/Sql/sch_header.h +++ b/uppsrc/Sql/sch_header.h @@ -5,10 +5,11 @@ struct S_##Table b { \ public:\ void Shrink(); \ void Clear(); \ - static const char TableName[]; \ - static const SqlSet& ColumnSet(); \ - static SqlSet ColumnSet(const String& prefix); \ - static SqlSet Of(SqlId table); \ + static const char TableName[]; \ + static const SqlSet& ColumnSet(); \ + static SqlSet ColumnSet(const String& prefix); \ + static SqlSet Of(SqlId table); \ + static const Vector& GetColumnIds(); \ void FieldLayoutRaw(FieldOperator& f, const String& prefix = String()); \ void FieldLayout(FieldOperator& f); \ operator Fields() { return callback(this, &S_##Table::FieldLayout); } \ @@ -16,6 +17,7 @@ public:\ bool operator!=(const S_##Table& x) const { return !EqualFields(const_cast(*this), const_cast(x)); } \ String ToString() const { return AsString((Fields)const_cast(*this)); } \ Value Get(SqlId column_id) const; \ + ValueMap Get() const; \ S_##Table(); #define TYPE(Table) CODETYPE(Table, __NIL) diff --git a/uppsrc/Sql/sch_source.h b/uppsrc/Sql/sch_source.h index 39fdc9caa..802d9484e 100644 --- a/uppsrc/Sql/sch_source.h +++ b/uppsrc/Sql/sch_source.h @@ -126,15 +126,31 @@ void S_##x::FieldLayoutRaw(FieldOperator& fo, const String& prefix) {\ #include SCHEMADIALECT -// S_*::Get(SqlId column_id) +// S_*::Get(SqlId column_id) const #define TYPE(x) Value S_##x::Get(SqlId column_id) const { String col = ~column_id; -#define COLUMN(type, ctype, name, width, prec) static String _x0_x_##name(#name); if(_x0_x_##name == col) return name; -#define END_TYPE return Value(); } +#define COLUMN(type, ctype, name, width, prec) static String _x0_x_##name(#name); if(_x0_x_##name == col) return name; +#define END_TYPE return Value(); } #include SCHEMADIALECT +// ValueMap S_*::Get() const + +#define TYPE(x) ValueMap S_##x::Get() const { ValueMap vm; +#define COLUMN(type, ctype, name, width, prec) static String _x0_x_##name(#name); vm.Add(_x0_x_##name, name); +#define END_TYPE return vm; } + +#include SCHEMADIALECT + +// static const Vector& GetColumnIds(); + +#define TYPE(x) const Vector& S_##x::GetColumnIds() { static Vector cols; ONCELOCK { +#define COLUMN(type, ctype, name, width, prec) cols.Add(#name); +#define END_TYPE } return cols; } + +#include SCHEMADIALECT + // Introspection #define TYPE(x) void SchDbInfo##x() {