1 enum Sql_Dialect_Enum {
2 	ORACLE    = 1,
3 	SQLITE3   = 2,
4 	MY_SQL    = 4,
5 	MSSQL     = 8,
6 	PGSQL     = 16,
7 	FIREBIRD  = 32, // not implemented yet
8 	DB2       = 64, // not implemented yet
9 };
10 
11 class SqlBool;
12 class SqlVal;
13 class SqlSet;
14 class SqlSelect;
15 class SqlCase;
16 
17 struct S_info;
18 
19 // ----------
20 
21 struct FieldOperator {
22 	String table;
23 
TableFieldOperator24 	void Table(const char *name)                           { table = name; }
25 
26 	virtual void Field(Ref f);
27 	virtual void Field(const char *name, Ref f);
28 	virtual void Field(const char *name, Ref f, bool *b); // Ugly fix to resolve bool issue with S_info creation
29 
operatorFieldOperator30 	FieldOperator& operator()(const char *name, Ref f)     { Field(name, f, NULL); return *this; }
operatorFieldOperator31 	FieldOperator& operator()(const String& name, Ref f)   { Field(name, f, NULL); return *this; }
operatorFieldOperator32 	FieldOperator& operator()(Id id, Ref f)                { Field(~id, f); return *this; }
33 	FieldOperator& operator()(const char *name, bool& b);
operatorFieldOperator34 	FieldOperator& operator()(const String& name, bool& b) { return (*this)(~name, b); }
operatorFieldOperator35 	FieldOperator& operator()(Id id, bool& b)              { return (*this)(~id, b); }
36 
37 	virtual void Width(int width); // Only to be used for S_info
38 
39 	FieldOperator();
40 	virtual ~FieldOperator();
41 };
42 
43 typedef Callback1<FieldOperator&> Fields;
44 
45 struct FieldDumper : public FieldOperator {
46 	String s;
47 	virtual void Field(const char *name, Ref f);
48 };
49 
50 template <class T>
DumpFields(T & s)51 String DumpFields(T& s) {
52 	FieldDumper dump;
53 	s.FieldLayout(dump);
54 	return dump.s;
55 }
56 
57 void td_scalar(SqlSet& set, const String& prefix, const char *x);
58 void td_array(SqlSet& set, const String& prefix, const char *x, int cnt);
59 void td_var(SqlSet& set, const String& prefix, const char *x, SqlSet (*f)(const String&));
60 void td_shrink(String *array, int cnt);
61 
62 bool   EqualFields(Fields a, Fields b);
63 String AsString(Fields a);
64 
65 // ----------
66 
67 enum {
68 	SQLC_IF = 1,
69 	SQLC_ELSEIF = 2,
70 	SQLC_ELSE = 3,
71 	SQLC_ENDIF = 4,
72 	SQLC_DATE = 5,
73 	SQLC_TIME = 6,
74 	SQLC_STRING = 7,
75 	SQLC_BINARY = 8,
76 	SQLC_ID = 9, // '\t'
77 	SQLC_OF = 10,
78 	SQLC_AS = 11,
79 	SQLC_COMMA = 12,
80 };
81 
82 class SqlCode {
83 	String s;
84 
85 public:
86 	SqlCode(byte cond, const String& text);
87 	SqlCode operator()(byte cond, const String& text);
88 
89 	String operator()(const String& text);
90 	String operator()();
91 };
92 
93 String SqlCompile(byte dialect, const String& s);
94 String SqlCompile(const String& s);
95 
96 Vector<SqlVal> SplitSqlSet(const SqlSet& set);
97 
98 String SqlFormat(int x);
99 String SqlFormat(double x);
100 String SqlFormat(int64 x);
101 String SqlFormat(const char *s, int len);
102 String SqlFormat(const char *s);
103 String SqlFormat(const String& x);
104 String SqlFormat(Date x);
105 String SqlFormat(Time x);
106 String SqlFormat(const Value& x);
107 String SqlFormatBinary(const char *s, int l);
108 String SqlFormatBinary(const String& x);
109 
110 class SqlId : Moveable<SqlId> {
111 protected:
112 	Id id;
113 
114 private:
115 	void PutOf0(String& s, const SqlId& b) const;
116 	void PutOf(String& s, const SqlId& b) const;
117 
118 public:
119 	static void   UseQuotes(bool b = true);
120 	static bool   IsUseQuotes();
121 	static void   ToLowerCase(bool b = true);
122 	static void   ToUpperCase(bool b = true);
123 
IsEqual(const SqlId & b)124 	bool          IsEqual(const SqlId& b) const  { return id == b.id; }
IsEqual(const Id & b)125 	bool          IsEqual(const Id& b) const     { return id == b; }
IsNull()126 	bool          IsNull() const                 { return id.IsNull(); }
127 
128 	operator      const Id&() const              { return id; }
ToString()129 	const String& ToString() const               { return id.ToString(); }
130 	const String& operator~() const              { return ToString(); }
131 	String        Quoted() const;
132 
133 	SqlId         Of(SqlId id) const;
134 	SqlId         Of(const char *of) const;
135 	SqlId         As(const char *as) const;
As(SqlId id)136 	SqlId         As(SqlId id) const             { return As(~id.ToString()); }
137 	SqlId         operator[](int i) const; // deprecated
138 	SqlId         operator&(const SqlId& s) const; // depreceted
139 	SqlId         operator[](const SqlId& id) const; // deprecated
140 
141 	SqlId         operator()(SqlId p) const;
142 	SqlId         operator()(const S_info& table) const;
143 
144 //$-SqlId     operator()(SqlId p, SqlId p1, ...);
145 #define E__PutSqlId(I)      PutOf(x, p##I)
146 #define E__SqlId(I)         const SqlId& p##I
147 #define E__Of(I) \
148 	SqlId operator()(const SqlId& p, __List##I(E__SqlId)) const { \
149 	String x; \
150 	PutOf0(x, p); \
151 	__List##I(E__PutSqlId); \
152 	return x; \
153 }
154 __Expand(E__Of)
155 #undef  E__Of
156 #undef E__PutSqlId
157 #undef E__SqlId
158 //$+
SqlId()159 	SqlId()                                      {}
SqlId(const char * s)160 	SqlId(const char *s) : id(s)                 {}
SqlId(const String & s)161 	SqlId(const String& s) : id(s)               {}
SqlId(const Id & id)162 	SqlId(const Id& id) : id(id)                 {}
163 };
164 
165 typedef SqlId SqlCol; // Deprecated
166 
167 #define SQLID(x)     const UPP::SqlId x(#x);
168 #define SQL_ID(n, x) const UPP::SqlId n(#x);
169 
170 class SqlS : Moveable<SqlS> {
171 protected:
172 	String text;
173 	byte   priority;
174 
175 	void   Init(const SqlS& a, const char *o, int olen, const SqlS& b, int pr, int prb);
176 
177 public:
178 	enum PRIORITY {
179 		EMPTY    =   0,
180 		LOW      =  20,
181 		SETOP    =  50,
182 		SET      = 100,
183 		LOR      = 120,
184 		LAND     = 130,
185 		TRUEVAL  = 135,
186 		FALSEVAL = 136,
187 		COMP     = 140,
188 		ADD      = 150,
189 		MUL      = 160,
190 		UNARY    = 170,
191 		FN       = 180,
192 		HIGH     = 200,
193 		NULLVAL  = 250,
194 	};
195 
196 	String        operator()() const;
197 	String        operator()(int at) const;
198 	String        operator()(int at, byte cond) const;
199 	const String& operator~() const         { return text; }
IsEmpty()200 	bool          IsEmpty() const           { return priority == EMPTY; }
201 
SqlS()202 	SqlS()                                  : priority(EMPTY) {}
SqlS(const char * s,int pr)203 	SqlS(const char *s, int pr)             : text(s), priority(pr) {}
SqlS(const String & s,int pr)204 	SqlS(const String& s, int pr)           : text(s), priority(pr) {}
205 
SqlS(const SqlS & a,const char * op,const SqlS & b,int pr,int prb)206 	force_inline SqlS(const SqlS& a, const char *op, const SqlS& b, int pr, int prb) { Init(a, op, (int)strlen(op), b, pr, prb); }
SqlS(const SqlS & a,const char * op,const SqlS & b,int pr)207 	force_inline SqlS(const SqlS& a, const char *op, const SqlS& b, int pr)          { Init(a, op, (int)strlen(op), b, pr, pr); }
208 };
209 
210 class SqlVal : public SqlS, Moveable<SqlVal> {
211 public:
SetNull()212 	void SetNull()                          { text = "NULL"; priority = NULLVAL; }
SetHigh(const String & s)213 	void SetHigh(const String& s)           { text = s; priority = HIGH; }
IsNull()214 	bool IsNull() const                     { return priority == NULLVAL; }
215 
216 	SqlVal As(const char *as) const;
217 	SqlVal As(const SqlId& id) const;
218 
SqlVal()219 	SqlVal()                                {}
SqlVal(const String & s,int pr)220 	SqlVal(const String& s, int pr)         : SqlS(s, pr) {}
SqlVal(const SqlS & a,const char * o,const SqlS & b,int pa,int pb)221 	SqlVal(const SqlS& a, const char *o, const SqlS& b, int pa, int pb)
222 		                                    : SqlS(a, o, b, pa, pb) {}
SqlVal(const SqlS & a,const char * o,const SqlS & b,int p)223 	SqlVal(const SqlS& a, const char *o, const SqlS& b, int p)
224 		                                    : SqlS(a, o, b, p) {}
225 
226 	SqlVal(int x);
227 	SqlVal(int64 x);
228 	SqlVal(double x);
229 	SqlVal(const String& x);
230 	SqlVal(const char *x);
231 	SqlVal(Date x);
232 	SqlVal(Time x);
233 	SqlVal(const Value& x);
234 	SqlVal(const Nuller&);
235 	SqlVal(const SqlId& id);
236 	SqlVal(const SqlId& (*id)());
237 	SqlVal(const SqlCase& x);
238 };
239 
240 SqlVal operator-(const SqlVal& a);
241 SqlVal operator+(const SqlVal& a, const SqlVal& b);
242 SqlVal operator-(const SqlVal& a, const SqlVal& b);
243 SqlVal operator*(const SqlVal& a, const SqlVal& b);
244 SqlVal operator/(const SqlVal& a, const SqlVal& b);
245 SqlVal operator%(const SqlVal& a, const SqlVal& b);
246 SqlVal operator|(const SqlVal& a, const SqlVal& b); // String concatenation
247 
248 SqlVal& operator+=(SqlVal& a, const SqlVal& b);
249 SqlVal& operator-=(SqlVal& a, const SqlVal& b);
250 SqlVal& operator*=(SqlVal& a, const SqlVal& b);
251 SqlVal& operator/=(SqlVal& a, const SqlVal& b);
252 SqlVal& operator%=(SqlVal& a, const SqlVal& b);
253 SqlVal& operator|=(SqlVal& a, const SqlVal& b);
254 
255 SqlVal SqlFunc(const char* name, const SqlVal& a);
256 SqlVal SqlFunc(const char* name, const SqlVal& a, const SqlVal& b);
257 SqlVal SqlFunc(const char* name, const SqlVal& a, const SqlVal& b, const SqlVal& c);
258 SqlVal SqlFunc(const char* name, const SqlVal& a, const SqlVal& b, const SqlVal& c, const SqlVal& d);
259 SqlVal SqlFunc(const char* name, const SqlSet& set);
260 
261 SqlBool SqlBoolFunc(const char* name, const SqlBool& a);
262 SqlBool SqlBoolFunc(const char* name, const SqlBool& a, const SqlBool& b);
263 SqlBool SqlBoolFunc(const char* name, const SqlBool& a, const SqlBool& b, const SqlBool& c);
264 SqlBool SqlBoolFunc(const char* name, const SqlBool& a, const SqlBool& b, const SqlBool& c, const SqlBool& d);
265 
266 SqlVal Decode(const SqlVal& exp, const SqlSet& variants);
267 SqlVal Distinct(const SqlVal& exp);
268 SqlSet Distinct(const SqlSet& columns);
269 SqlVal All(const SqlVal& exp);
270 SqlSet All(const SqlSet& columns);
271 SqlId  SqlAll();
272 SqlVal Count(const SqlVal& exp);
273 SqlVal Count(const SqlSet& exp);
274 SqlVal SqlCountRows();
275 SqlVal Descending(const SqlVal& exp);
276 
277 SqlVal SqlMax(const SqlVal& a);
278 SqlVal SqlMin(const SqlVal& a);
279 SqlVal SqlSum(const SqlVal& a);
280 
281 SqlVal Avg(const SqlVal& a);
282 SqlVal Abs(const SqlVal& a);
283 SqlVal Stddev(const SqlVal& a);
284 SqlVal Variance(const SqlVal& a);
285 
286 SqlVal Greatest(const SqlVal& a, const SqlVal& b);
287 SqlVal Least(const SqlVal& a, const SqlVal& b);
288 
289 SqlVal ConvertCharset(const SqlVal& exp, const SqlVal& charset);
290 SqlVal ConvertAscii(const SqlVal& exp);
291 SqlVal Upper(const SqlVal& exp);
292 SqlVal Lower(const SqlVal& exp);
293 SqlVal Length(const SqlVal& exp);
294 SqlVal UpperAscii(const SqlVal& exp);
295 SqlVal Substr(const SqlVal& a, const SqlVal& b); // Deprecated, use 3 args variant bellow
296 SqlVal Substr(const SqlVal& a, const SqlVal& b, const SqlVal& c);
297 SqlVal Instr(const SqlVal& a, const SqlVal& b);
298 SqlVal Wild(const char* s);
299 
300 SqlVal SqlDate(const SqlVal& year, const SqlVal& month, const SqlVal& day);
301 SqlVal AddMonths(const SqlVal& date, const SqlVal& months);
302 SqlVal LastDay(const SqlVal& date);
303 SqlVal MonthsBetween(const SqlVal& date1, const SqlVal& date2);
304 SqlVal NextDay(const SqlVal& date);
305 
306 SqlVal SqlCurrentDate();
307 SqlVal SqlCurrentTime();
308 
309 SqlVal Cast(const char* type, const SqlId& a);
310 
311 SqlVal SqlNvl(const SqlVal& a);
Nvl(const SqlVal & a)312 inline SqlVal Nvl(const SqlVal& a)     { return SqlNvl(SqlVal(a)); }
Nvl(const SqlId & a)313 inline SqlVal Nvl(const SqlId& a)      { return SqlNvl(SqlVal(a)); }
314 
315 SqlVal SqlNvl(const SqlVal& a, const SqlVal& b);
Nvl(const SqlVal & a,const SqlVal & b)316 inline SqlVal Nvl(const SqlVal& a, const SqlVal& b) { return SqlNvl(SqlVal(a), SqlVal(b)); }
Nvl(const SqlVal & a,const SqlId & b)317 inline SqlVal Nvl(const SqlVal& a, const SqlId& b)  { return SqlNvl(SqlVal(a), SqlVal(b)); }
Nvl(const SqlId & a,const SqlVal & b)318 inline SqlVal Nvl(const SqlId& a, const SqlVal& b)  { return SqlNvl(SqlVal(a), SqlVal(b)); }
Nvl(const SqlId & a,const SqlId & b)319 inline SqlVal Nvl(const SqlId& a, const SqlId& b)   { return SqlNvl(SqlVal(a), SqlVal(b)); }
320 
SqlNvl(const SqlVal & a,const SqlVal & b,const SqlVal & c)321 inline SqlVal SqlNvl(const SqlVal& a, const SqlVal& b, const SqlVal& c)
322 {
323 	return SqlNvl(SqlNvl(a, b), c);
324 }
325 
SqlNvl(const SqlVal & a,const SqlVal & b,const SqlVal & c,const SqlVal & d)326 inline SqlVal SqlNvl(const SqlVal& a, const SqlVal& b, const SqlVal& c, const SqlVal& d)
327 {
328 	return SqlNvl(SqlNvl(a, b), c, d);
329 }
330 
SqlNvl(const SqlVal & a,const SqlVal & b,const SqlVal & c,const SqlVal & d,const SqlVal & e)331 inline SqlVal SqlNvl(const SqlVal& a, const SqlVal& b, const SqlVal& c, const SqlVal& d, const SqlVal& e)
332 {
333 	return SqlNvl(SqlNvl(a, b), c, d, e);
334 }
335 
336 SqlVal Coalesce(const SqlVal& exp1, const SqlVal& exp2);
337 SqlVal Coalesce(const SqlVal& exp1, const SqlVal& exp2, const SqlVal& exp3);
338 SqlVal Coalesce(const SqlVal& exp1, const SqlVal& exp2, const SqlVal& exp3, const SqlVal& exp4);
339 SqlVal Coalesce(const SqlSet& exps);
340 
341 SqlVal Prior(const SqlId& a);
342 
343 SqlVal NextVal(const SqlId& a);
344 SqlVal CurrVal(const SqlId& a);
345 SqlVal OuterJoin(const SqlId& col); //Oracle only, deprecated
346 
347 inline SqlVal operator++(const SqlId& a)           { return NextVal(a); }
348 
349 SqlVal SqlTxt(const char *s);
350 
351 SqlVal SqlRowNum();
352 
353 SqlVal SqlArg();
354 
355 SqlVal SqlBinary(const String& data);
356 
357 class SqlBool : public SqlS, Moveable<SqlBool> {
358 public:
359 	void     SetTrue();
360 	void     SetFalse();
361 	void     SetBool(bool b);
362 
IsTrue()363 	bool     IsTrue()  const                { return priority == TRUEVAL; }
IsFalse()364 	bool     IsFalse() const                { return priority == FALSEVAL; }
IsBool()365 	bool     IsBool()  const                { return IsTrue() || IsFalse(); }
AsBool()366 	bool     AsBool()  const                { ASSERT(IsBool()); return IsTrue(); }
367 
AsValue()368 	SqlVal   AsValue() const                { return SqlVal(text, LOW); }
As(const char * as)369 	SqlVal   As(const char *as) const       { return AsValue().As(as); }
As(const SqlId & id)370 	SqlVal   As(const SqlId& id) const      { return AsValue().As(id); }
371 
SqlBool(const String & s,int pr)372 	SqlBool(const String& s, int pr)        : SqlS(s, pr) {}
SqlBool(const SqlS & a,const char * o,const SqlS & b,int pa,int pb)373 	SqlBool(const SqlS& a, const char *o, const SqlS& b, int pa, int pb)
374 		                                    : SqlS(a, o, b, pa, pb) {}
SqlBool(const SqlS & a,const char * o,const SqlS & b,int p)375 	SqlBool(const SqlS& a, const char *o, const SqlS& b, int p)
376 		                                    : SqlS(a, o, b, p) {}
377 
True()378 	static SqlBool True()                   { return SqlBool(true); }
False()379 	static SqlBool False()                  { return SqlBool(false); }
380 
SqlBool()381 	SqlBool()                               {}
SqlBool(bool b)382 	SqlBool(bool b)                         { SetBool(b); }
383 };
384 
385 SqlBool        operator!(const SqlBool& a);
386 
387 SqlBool        operator<(const SqlVal& a, const SqlVal& b);
388 SqlBool        operator<=(const SqlVal& a, const SqlVal& b);
389 SqlBool        operator>=(const SqlVal& a, const SqlVal& b);
390 SqlBool        operator>(const SqlVal& a, const SqlVal& b);
391 SqlBool        operator==(const SqlVal& a, const SqlVal& b);
392 SqlBool        operator!=(const SqlVal& a, const SqlVal& b);
393 
394 SqlBool        IsSame(const SqlVal& a, const SqlVal& b);
395 
396 SqlBool        operator||(const SqlBool& a, const SqlBool& b);
397 SqlBool        operator&&(const SqlBool& a, const SqlBool& b);
398 SqlBool        operator- (const SqlBool& a, const SqlBool& b);
399 SqlBool        operator|=(SqlBool& a, const SqlBool& b);
400 SqlBool        operator&=(SqlBool& a, const SqlBool& b);
401 
402 SqlBool        SqlIsNull(const SqlVal& a);
403 SqlBool        NotNull(const SqlVal& a);
404 
IsNull(const SqlId & a)405 inline SqlBool IsNull(const SqlId& a)  { return SqlIsNull(a); }
IsNull(const SqlVal & a)406 inline SqlBool IsNull(const SqlVal& a) { return SqlIsNull(a); }
407 
408 SqlBool        Like(const SqlVal& a, const SqlVal& b, bool casesensitive = true);
409 SqlBool        NotLike(const SqlVal& a, const SqlVal& b, bool casesensitive = true);
410 
411 SqlBool        Between(const SqlVal& a, const SqlVal& low, const SqlVal& high);
412 SqlBool        NotBetween(const SqlVal&a, const SqlVal& low, const SqlVal& high);
413 
414 SqlBool        In(const SqlVal& a, const SqlSet& b);
415 SqlBool        NotIn(const SqlVal& a, const SqlSet& b);
416 SqlBool        Exists(const SqlSet& set);
417 SqlBool        NotExists(const SqlSet& set);
418 
419 SqlBool        LikeUpperAscii(const SqlVal& a, const SqlVal& b);
420 
421 SqlBool        LeftJoin(SqlVal v1, SqlVal v2); // Deprecated
422 SqlBool        RightJoin(SqlVal v1, SqlVal v2); // Deprecated
423 
424 SqlBool        Join(SqlId tab1, SqlId tab2, SqlId key); // Deprecated
425 SqlBool        LeftJoin(SqlId tab1, SqlId tab2, SqlId key); // Deprecated
426 SqlBool        RightJoin(SqlId tab1, SqlId tab2, SqlId key); // Deprecated
427 
428 SqlBool        SqlFirstRow(); // Oracle specific
429 
430 inline SqlBool operator==(const SqlVal& a, const SqlSet& b) { return In(a, b); }
431 inline SqlBool operator!=(const SqlVal& a, const SqlSet& b) { return NotIn(a, b); }
432 
433 inline const SqlVal& operator+(const SqlVal& a) { return a; }
434 
435 class SqlCase : public SqlS, Moveable<SqlCase> {
436 public:
SqlCase(const SqlBool & cond,const SqlVal & val)437 	SqlCase(const SqlBool& cond, const SqlVal& val)
438 	{
439 		text = "case when " + ~cond + " then " + ~val + " end";
440 	}
operator()441 	SqlCase& operator()(const SqlBool& cond, const SqlVal& val)
442 	{
443 		text.Insert(text.GetLength() - 4, " when " + ~cond + " then " + ~val);
444 		return *this;
445 	}
operator()446 	SqlCase& operator()(const SqlVal& val)
447 	{
448 		text.Insert(text.GetLength() - 4, " else " + ~val);
449 		return *this;
450 	}
451 };
452 
Case(const SqlBool & cond,const SqlVal & val)453 inline SqlCase Case(const SqlBool& cond, const SqlVal& val) { return SqlCase(cond, val); }
454 
455 class Sql;
456 
457 #define E__SqlVal(I)      const SqlVal& p##I
458 
459 SqlSet operator|(const SqlSet& s1, const SqlSet& s2); // union
460 SqlSet operator+(const SqlSet& s1, const SqlSet& s2); // union all
461 SqlSet operator&(const SqlSet& s1, const SqlSet& s2); // intersection
462 SqlSet operator-(const SqlSet& s1, const SqlSet& s2); // difference
463 
464 class SqlSet : Moveable<SqlSet> {
465 protected:
466 	String text;
467 	byte   priority;
468 
469 public:
470 	enum PRIORITY {
471 		SETOP    =  50,
472 		SET      = 100,
473 		HIGH     = 200,
474 	};
475 
476 	String           operator~() const;
477 	String           operator()() const;
478 	String           operator()(int at) const;
479 	String           operator()(int at, byte cond) const;
IsEmpty()480 	bool             IsEmpty() const                    { return text.IsEmpty(); }
481 	bool             operator==(const SqlSet& b) const  { return text == b.text && priority == b.priority; }
482 	bool             operator!=(const SqlSet& b) const  { return !operator==(b); }
483 
484 	SqlSet&          Cat(const SqlVal& val); // adding a member
485 	SqlSet&          Cat(const SqlSet& set);
486 	SqlSet&          operator|=(const SqlVal& val)  { return Cat(val); }
487 	SqlSet&          operator<<(const SqlVal& val)  { return Cat(val); }
488 
489 	SqlSet&          operator|=(const SqlSet& set)  { return *this = *this | set; }
490 	SqlSet&          operator+=(const SqlSet& set)  { return *this = *this + set; }
491 	SqlSet&          operator&=(const SqlSet& set)  { return *this = *this & set; }
492 	SqlSet&          operator-=(const SqlSet& set)  { return *this = *this - set; }
493 
Clear()494 	void             Clear()                        { text.Clear(); }
495 
Split()496 	Vector<SqlVal>   Split() const                  { return SplitSqlSet(*this); }
497 
SqlSet()498 	SqlSet() {}
499 	explicit SqlSet(const SqlVal& p0);
500 
501 //$-SqlSet(const SqlVal& p0, ...)
502 #define E__SqlSet(I)   SqlSet(const SqlVal& p0, __List##I(E__SqlVal));
503 	__Expand(E__SqlSet);
504 //$+
505 	explicit SqlSet(Fields nfields);
506 
SqlSet(const String & s,PRIORITY p)507 	SqlSet(const String& s, PRIORITY p)   { text = s; priority = p; }
508 	void SetRaw(const String& s, PRIORITY p = SETOP) { text = s; priority = p; }
509 };
510 
511 template <typename T>
SqlSetFrom(const T & cont)512 SqlSet SqlSetFrom(const T& cont)
513 {
514 	SqlSet set;
515 	typename T::ConstIterator e = cont.end();
516 	for(typename T::ConstIterator it = cont.begin(); it != e; it++)
517 		set.Cat(*it);
518 	return set;
519 }
520 
521 template <typename T>
SqlSetFrom(const T & cont,int pos,int count)522 SqlSet SqlSetFrom(const T& cont, int pos, int count)
523 {
524 	SqlSet set;
525 	typename T::ConstIterator it = cont.begin() + pos;
526 	typename T::ConstIterator e = it + count;
527 	for(; it != e; it++)
528 		set.Cat(*it);
529 	return set;
530 }
531 
532 SqlSet SqlSetFrom(const ValueArray& va, int pos, int count);
533 SqlSet SqlSetFrom(const ValueArray& va);
534 
535 class SqlSetC : public SqlSet {
536 public:
SqlSetC(const String & s)537 	SqlSetC(const String& s)      { text = s; priority = SET; }
SqlSetC(const char * s)538 	SqlSetC(const char* s)        { text = s; priority = SET; }
539 };
540 
541 class SqlStatement {
542 	String text;
543 
544 public:
SqlStatement()545 	SqlStatement() {}
SqlStatement(const String & s)546 	explicit SqlStatement(const String& s) : text(s) {}
547 
548 	String Get(int dialect) const;
549 #ifndef flagNOAPPSQL
550 	String Get() const;
551 #endif
GetText()552 	String GetText() const                           { return text; }
IsEmpty()553 	bool   IsEmpty() const                           { return text.IsEmpty(); }
554 	operator bool() const                            { return !IsEmpty(); }
555 
556 //Deprecated!!!
557 	bool  Execute(Sql& cursor) const;
558 	void  Force(Sql& cursor) const;
559 	Value Fetch(Sql& cursor) const;
560 	bool  Execute() const;
561 	void  Force() const;
562 	Value Fetch() const;
563 };
564 
565 class SqlSelect {
566 	String  text;
567 	String  tables;
568 	bool    on, valid;
569 
570 	SqlSelect& InnerJoin0(const String& table);
571 	SqlSelect& LeftJoin0(const String& table);
572 	SqlSelect& RightJoin0(const String& table);
573 	SqlSelect& FullJoin0(const String& table);
574 	SqlSelect& SetOp(const SqlSelect& s2, const char *op);
575 
576 public:
577 	SqlSelect& operator()(const SqlVal& val);
578 
579 	operator bool() const                             { return text.GetCount(); }
580 
581 	SqlSelect& Hint(const char *hint);
582 
583 	SqlSelect& Get();
From()584 	SqlSelect& From()                                 { return Get(); }
585 	SqlSelect& From(const SqlSet& set);
586 	SqlSelect& From(const SqlId& table);
587 	SqlSelect& From(const SqlId& table1, const SqlId& table2);
588 	SqlSelect& From(const SqlId& table1, const SqlId& table2, const SqlId& table3);
From(const SqlVal & a)589 	SqlSelect& From(const SqlVal& a)                  { return From(SqlSet(a)); }
590 
InnerJoin(const SqlId & table)591 	SqlSelect& InnerJoin(const SqlId& table)          { return InnerJoin0(table.Quoted()); }
LeftJoin(const SqlId & table)592 	SqlSelect& LeftJoin(const SqlId& table)           { return LeftJoin0(table.Quoted()); }
RightJoin(const SqlId & table)593 	SqlSelect& RightJoin(const SqlId& table)          { return RightJoin0(table.Quoted()); }
FullJoin(const SqlId & table)594 	SqlSelect& FullJoin(const SqlId& table)           { return FullJoin0(table.Quoted()); }
595 
InnerJoin(const SqlSet & set)596 	SqlSelect& InnerJoin(const SqlSet& set)           { return InnerJoin0(set(SqlSet::SET)); }
LeftJoin(const SqlSet & set)597 	SqlSelect& LeftJoin(const SqlSet& set)            { return LeftJoin0(set(SqlSet::SET)); }
RightJoin(const SqlSet & set)598 	SqlSelect& RightJoin(const SqlSet& set)           { return RightJoin0(set(SqlSet::SET)); }
FullJoin(const SqlSet & set)599 	SqlSelect& FullJoin(const SqlSet& set)            { return FullJoin0(set(SqlSet::SET)); }
600 
601 	SqlSelect& InnerJoinRef(const SqlId& table);
602 	SqlSelect& LeftJoinRef(const SqlId& table);
603 	SqlSelect& RightJoinRef(const SqlId& table);
604 	SqlSelect& FullJoinRef(const SqlId& table);
605 
606 	SqlSelect& Where(const SqlBool& exp);
607 	SqlSelect& On(const SqlBool& exp);
608 	SqlSelect& StartWith(const SqlBool& exp);
609 	SqlSelect& ConnectBy(const SqlBool& exp);
610 	SqlSelect& GroupBy(const SqlSet& columnset);
611 	SqlSelect& Having(const SqlBool& exp);
612 	SqlSelect& OrderBy(const SqlSet& columnset);
613 	SqlSelect& ForUpdate();
614 	SqlSelect& NoWait();
615 
GroupBy(SqlVal a)616 	SqlSelect& GroupBy(SqlVal a)                      { return GroupBy(SqlSet(a)); }
GroupBy(SqlVal a,SqlVal b)617 	SqlSelect& GroupBy(SqlVal a, SqlVal b)            { return GroupBy(SqlSet(a, b)); }
GroupBy(SqlVal a,SqlVal b,SqlVal c)618 	SqlSelect& GroupBy(SqlVal a, SqlVal b, SqlVal c)  { return GroupBy(SqlSet(a, b, c)); }
OrderBy(SqlVal a)619 	SqlSelect& OrderBy(SqlVal a)                      { return OrderBy(SqlSet(a)); }
OrderBy(SqlVal a,SqlVal b)620 	SqlSelect& OrderBy(SqlVal a, SqlVal b)            { return OrderBy(SqlSet(a, b)); }
OrderBy(SqlVal a,SqlVal b,SqlVal c)621 	SqlSelect& OrderBy(SqlVal a, SqlVal b, SqlVal c)  { return OrderBy(SqlSet(a, b, c)); }
622 	SqlSelect& Limit(int limit);
623 	SqlSelect& Limit(int64 offset, int limit);
624 	SqlSelect& Offset(int64 offset);
625 
SqlSet()626 	operator  SqlSet() const                           { return SqlSet(text, SqlSet::SETOP); }
SqlStatement()627 	operator  SqlStatement() const                     { return SqlStatement(text); }
628 	SqlVal    AsValue() const;
629 	SqlSet    AsTable(const SqlId& tab) const;
630 
Set(const SqlSet & s)631 	void      Set(const SqlSet& s)                    { text = ~s; on = valid = false; }
IsValid()632 	bool      IsValid() const                         { return valid; }
633 
634 	SqlSelect(Fields f);
SqlSelect(const SqlSet & s)635 	SqlSelect(const SqlSet& s)                        { Set(s); }
SqlSelect()636 	SqlSelect()                                       { on = valid = false; }
637 //$-SqlSelect(SqlVal v, ...);
638 #define E__QSelect(I)   SqlSelect(__List##I(E__SqlVal));
639 	__Expand(E__QSelect);
640 #undef  E__QSelect
641 //$+
642 
IsEmpty()643 	bool IsEmpty()                                    { return text.IsEmpty(); }
644 
645 	SqlSelect& operator|=(const SqlSelect& s2); // union
646 	SqlSelect& operator&=(const SqlSelect& s2); // intersect
647 	SqlSelect& operator-=(const SqlSelect& s2); // except
648 	SqlSelect& operator+=(const SqlSelect& s2); // union all
649 
650 //Deprecated!!!
Execute(Sql & sql)651 	bool  Execute(Sql& sql) const                     { return SqlStatement(*this).Execute(sql); }
Force(Sql & sql)652 	void  Force(Sql& sql) const                       { return SqlStatement(*this).Force(sql); }
Fetch(Sql & sql)653 	Value Fetch(Sql& sql) const                       { return SqlStatement(*this).Fetch(sql); }
Execute()654 	bool  Execute() const                             { return SqlStatement(*this).Execute(); }
Force()655 	void  Force() const                               { return SqlStatement(*this).Force(); }
Fetch()656 	Value Fetch() const                               { return SqlStatement(*this).Fetch(); }
657 };
658 
659 SqlSelect operator|(const SqlSelect& s1, const SqlSelect& s2); // union
660 SqlSelect operator&(const SqlSelect& s1, const SqlSelect& s2); // intersect
661 SqlSelect operator-(const SqlSelect& s1, const SqlSelect& s2); // except
662 SqlSelect operator+(const SqlSelect& s1, const SqlSelect& s2); // union all
663 
SelectAll()664 inline SqlSelect SelectAll()                { return SqlSelect(SqlAll()); }
Select(const SqlSet & set)665 inline SqlSelect Select(const SqlSet& set)  { return SqlSelect(set); }
Select(Fields f)666 inline SqlSelect Select(Fields f)           { return SqlSelect(f); }
667 
668 //$-SqlSelect Select(SqlVal v, ...);
669 #define E__QSelect(I)   SqlSelect Select(__List##I(E__SqlVal));
670 __Expand(E__QSelect);
671 #undef  E__QSelect
672 //$-
673 
674 class SqlDelete {
675 	String text;
676 	SqlSet ret;
677 
678 public:
679 	SqlDelete& Where(const SqlBool& b);
680 	SqlDelete& Returning(const SqlSet& set);
Returning(SqlVal a)681 	SqlDelete& Returning(SqlVal a)                    { return Returning(SqlSet(a)); }
Returning(SqlVal a,SqlVal b)682 	SqlDelete& Returning(SqlVal a, SqlVal b)          { return Returning(SqlSet(a, b)); }
Returning(SqlVal a,SqlVal b,SqlVal c)683 	SqlDelete& Returning(SqlVal a, SqlVal b, SqlVal c){ return Returning(SqlSet(a, b, c)); }
684 
SqlStatement()685 	operator SqlStatement() const                     { return SqlStatement(text); }
686 
687 	SqlDelete(SqlVal table);
688 
689 //Deprecated!!!
Execute(Sql & sql)690 	bool  Execute(Sql& sql) const                     { return SqlStatement(*this).Execute(sql); }
Force(Sql & sql)691 	void  Force(Sql& sql) const                       { return SqlStatement(*this).Force(sql); }
Fetch(Sql & sql)692 	Value Fetch(Sql& sql) const                       { return SqlStatement(*this).Fetch(sql); }
Execute()693 	bool  Execute() const                             { return SqlStatement(*this).Execute(); }
Force()694 	void  Force() const                               { return SqlStatement(*this).Force(); }
Fetch()695 	Value Fetch() const                               { return SqlStatement(*this).Fetch(); }
696 };
697 
Delete(SqlVal table)698 inline SqlDelete Delete(SqlVal table) { return SqlDelete(table); }
699 
700 #define NEWINSERTUPDATE
701 
702 #ifdef NEWINSERTUPDATE
703 
704 class SqlInsert {
705 	SqlId     table;
706 	SqlId     keycolumn;
707 	SqlVal    keyvalue;
708 	SqlSet    set1;
709 	SqlSet    set2;
710 	SqlSelect sel;
711 	SqlSet    ret;
712 
713 public:
714 	void Column(const SqlId& column, SqlVal val);
Column(const SqlId & column)715 	void Column(const SqlId& column)                       { Column(column, column); }
operator()716 	SqlInsert& operator()(const SqlId& column, SqlVal val) { Column(column, val); return *this; }
operator()717 	SqlInsert& operator()(const SqlId& column)             { Column(column, column); return *this; }
718 	SqlInsert& operator()(Fields f, bool nokey = false);
719 	SqlInsert& operator()(const ValueMap& data);
720 
GetTable()721 	SqlId    GetTable() const                        { return table; }
GetKeyColumn()722 	SqlId    GetKeyColumn() const                    { return keycolumn; }
GetKeyValue()723 	SqlVal   GetKeyValue() const                     { return keyvalue; }
724 
Get()725 	SqlInsert& Get()                                 { sel.Get(); return *this; }
From()726 	SqlInsert& From()                                { return Get(); }
From(const SqlSet & set)727 	SqlInsert& From(const SqlSet& set)               { sel.From(set); return *this; }
From(const SqlId & table)728 	SqlInsert& From(const SqlId& table)              { sel.From(table); return *this; }
From(const SqlVal & a)729 	SqlInsert& From(const SqlVal& a)                 { sel.From(SqlSet(a)); return *this; }
730 
InnerJoin(const SqlId & table)731 	SqlInsert& InnerJoin(const SqlId& table)         { sel.InnerJoin(table); return *this; }
LeftJoin(const SqlId & table)732 	SqlInsert& LeftJoin(const SqlId& table)          { sel.LeftJoin(table); return *this; }
RightJoin(const SqlId & table)733 	SqlInsert& RightJoin(const SqlId& table)         { sel.RightJoin(table); return *this; }
FullJoin(const SqlId & table)734 	SqlInsert& FullJoin(const SqlId& table)          { sel.FullJoin(table); return *this; }
735 
InnerJoin(const SqlSet & set)736 	SqlInsert& InnerJoin(const SqlSet& set)          { sel.InnerJoin(set); return *this; }
LeftJoin(const SqlSet & set)737 	SqlInsert& LeftJoin(const SqlSet& set)           { sel.LeftJoin(set); return *this; }
RightJoin(const SqlSet & set)738 	SqlInsert& RightJoin(const SqlSet& set)          { sel.RightJoin(set); return *this; }
FullJoin(const SqlSet & set)739 	SqlInsert& FullJoin(const SqlSet& set)           { sel.FullJoin(set); return *this; }
740 
InnerJoinRef(const SqlId & table)741 	SqlInsert& InnerJoinRef(const SqlId& table)      { sel.InnerJoinRef(table); return *this; }
LeftJoinRef(const SqlId & table)742 	SqlInsert& LeftJoinRef(const SqlId& table)       { sel.LeftJoinRef(table); return *this; }
RightJoinRef(const SqlId & table)743 	SqlInsert& RightJoinRef(const SqlId& table)      { sel.RightJoinRef(table); return *this; }
FullJoinRef(const SqlId & table)744 	SqlInsert& FullJoinRef(const SqlId& table)       { sel.FullJoinRef(table); return *this; }
745 
746 	SqlInsert& Where(const SqlBool& exp);
On(const SqlBool & exp)747 	SqlInsert& On(const SqlBool& exp)                { sel.On(exp); return *this; }
StartWith(const SqlBool & exp)748 	SqlInsert& StartWith(const SqlBool& exp)         { sel.StartWith(exp); return *this; }
ConnectBy(const SqlBool & exp)749 	SqlInsert& ConnectBy(const SqlBool& exp)         { sel.ConnectBy(exp); return *this; }
GroupBy(const SqlSet & columnset)750 	SqlInsert& GroupBy(const SqlSet& columnset)      { sel.GroupBy(columnset); return *this; }
Having(const SqlBool & exp)751 	SqlInsert& Having(const SqlBool& exp)            { sel.Having(exp); return *this; }
OrderBy(const SqlSet & columnset)752 	SqlInsert& OrderBy(const SqlSet& columnset)      { sel.OrderBy(columnset); return *this; }
753 	SqlInsert& Returning(const SqlSet& set);
754 
GroupBy(SqlVal a)755 	SqlInsert& GroupBy(SqlVal a)                     { sel.GroupBy(SqlSet(a)); return *this; }
GroupBy(SqlVal a,SqlVal b)756 	SqlInsert& GroupBy(SqlVal a, SqlVal b)           { sel.GroupBy(SqlSet(a, b)); return *this; }
GroupBy(SqlVal a,SqlVal b,SqlVal c)757 	SqlInsert& GroupBy(SqlVal a, SqlVal b, SqlVal c) { sel.GroupBy(SqlSet(a, b, c)); return *this; }
OrderBy(SqlVal a)758 	SqlInsert& OrderBy(SqlVal a)                     { sel.OrderBy(SqlSet(a)); return *this; }
OrderBy(SqlVal a,SqlVal b)759 	SqlInsert& OrderBy(SqlVal a, SqlVal b)           { sel.OrderBy(SqlSet(a, b)); return *this; }
OrderBy(SqlVal a,SqlVal b,SqlVal c)760 	SqlInsert& OrderBy(SqlVal a, SqlVal b, SqlVal c) { sel.OrderBy(SqlSet(a, b, c)); return *this; }
Returning(SqlVal a)761 	SqlInsert& Returning(SqlVal a)                   { return Returning(SqlSet(a)); }
Returning(SqlVal a,SqlVal b)762 	SqlInsert& Returning(SqlVal a, SqlVal b)         { return Returning(SqlSet(a, b)); }
Returning(SqlVal a,SqlVal b,SqlVal c)763 	SqlInsert& Returning(SqlVal a, SqlVal b, SqlVal c){ return Returning(SqlSet(a, b, c)); }
Limit(int limit)764 	SqlInsert& Limit(int limit)                      { sel.Limit(limit); return *this; }
Limit(int64 offset,int limit)765 	SqlInsert& Limit(int64 offset, int limit)        { sel.Limit(offset, limit); return *this; }
Offset(int64 offset)766 	SqlInsert& Offset(int64 offset)                  { sel.Offset(offset); return *this; }
767 
768 	operator SqlStatement() const;
769 	operator bool() const                            { return !set1.IsEmpty(); }
770 
SqlInsert(const SqlId & table)771 	SqlInsert(const SqlId& table) : table(table) {}
SqlInsert(const SqlId & table,const SqlSet & set1,const SqlSet & set2)772 	SqlInsert(const SqlId& table, const SqlSet& set1, const SqlSet& set2)
773 		: table(table), set1(set1), set2(set2) {}
774 	SqlInsert(Fields f, bool nokey = false);
775 
776 //Deprecated!!!
Execute(Sql & sql)777 	bool  Execute(Sql& sql) const                     { return SqlStatement(*this).Execute(sql); }
Force(Sql & sql)778 	void  Force(Sql& sql) const                       { return SqlStatement(*this).Force(sql); }
Fetch(Sql & sql)779 	Value Fetch(Sql& sql) const                       { return SqlStatement(*this).Fetch(sql); }
Execute()780 	bool  Execute() const                             { return SqlStatement(*this).Execute(); }
Force()781 	void  Force() const                               { return SqlStatement(*this).Force(); }
Fetch()782 	Value Fetch() const                               { return SqlStatement(*this).Fetch(); }
783 };
784 
785 #else
786 
787 class SqlInsert {
788 	SqlId   table;
789 	SqlId   keycolumn;
790 	SqlVal  keyvalue;
791 	SqlSet  set1;
792 	SqlSet  set2;
793 	SqlSet  from;
794 	SqlBool where;
795 	SqlSet  groupby;
796 	SqlBool having;
797 
798 public:
799 	void Column(const SqlId& column, SqlVal val);
Column(const SqlId & column)800 	void Column(const SqlId& column)                       { Column(column, column); }
operator()801 	SqlInsert& operator()(const SqlId& column, SqlVal val) { Column(column, val); return *this; }
operator()802 	SqlInsert& operator()(const SqlId& column)             { Column(column, column); return *this; }
803 	SqlInsert& operator()(Fields f, bool nokey = false);
804 	SqlInsert& operator()(const ValueMap& data);
Get()805 	SqlUpdate& Get()                                 { sel.Get(); return *this; }
From()806 	SqlUpdate& From()                                { return Get(); }
807 	SqlInsert& From(const SqlId& from);
From(SqlSet _from)808 	SqlInsert& From(SqlSet _from)                    { from = _from; return *this; }
From(SqlVal from)809 	SqlInsert& From(SqlVal from)                     { return From(SqlSet(from)); }
Where(SqlBool w)810 	SqlInsert& Where(SqlBool w)                      { where = w; return *this; }
GroupBy(const SqlSet & columnset)811 	SqlInsert& GroupBy(const SqlSet& columnset)      { groupby = columnset; return *this; }
GroupBy(SqlVal a)812 	SqlInsert& GroupBy(SqlVal a)                     { return GroupBy(SqlSet(a)); }
GroupBy(SqlVal a,SqlVal b)813 	SqlInsert& GroupBy(SqlVal a, SqlVal b)           { return GroupBy(SqlSet(a, b)); }
GroupBy(SqlVal a,SqlVal b,SqlVal c)814 	SqlInsert& GroupBy(SqlVal a, SqlVal b, SqlVal c) { return GroupBy(SqlSet(a, b, c)); }
Having(const SqlBool & exp)815 	SqlInsert& Having(const SqlBool& exp)            { having = exp; return *this; }
816 
GetTable()817 	SqlId    GetTable() const                        { return table; }
GetKeyColumn()818 	SqlId    GetKeyColumn() const                    { return keycolumn; }
GetKeyValue()819 	SqlVal   GetKeyValue() const                     { return keyvalue; }
820 
821 	operator SqlStatement() const;
822 	operator bool() const                            { return !set1.IsEmpty(); }
823 
SqlInsert(const SqlId & table)824 	SqlInsert(const SqlId& table) : table(table) {}
SqlInsert(const SqlId & table,const SqlSet & set1,const SqlSet & set2)825 	SqlInsert(const SqlId& table, const SqlSet& set1, const SqlSet& set2)
826 		: table(table), set1(set1), set2(set2) {}
827 	SqlInsert(Fields f, bool nokey = false);
828 
829 //Deprecated!!!
Execute(Sql & sql)830 	bool  Execute(Sql& sql) const                     { return SqlStatement(*this).Execute(sql); }
Force(Sql & sql)831 	void  Force(Sql& sql) const                       { return SqlStatement(*this).Force(sql); }
Fetch(Sql & sql)832 	Value Fetch(Sql& sql) const                       { return SqlStatement(*this).Fetch(sql); }
Execute()833 	bool  Execute() const                             { return SqlStatement(*this).Execute(); }
Force()834 	void  Force() const                               { return SqlStatement(*this).Force(); }
Fetch()835 	Value Fetch() const                               { return SqlStatement(*this).Fetch(); }
836 };
837 
838 #endif
839 
Insert(const SqlId & table)840 inline SqlInsert Insert(const SqlId& table)           { return SqlInsert(table); }
Insert(Fields f)841 inline SqlInsert Insert(Fields f)                     { return SqlInsert(f); }
InsertNoKey(Fields f)842 inline SqlInsert InsertNoKey(Fields f)                { return SqlInsert(f, true); }
843 
844 #ifdef NEWINSERTUPDATE
845 
846 class SqlUpdate {
847 	SqlId     table;
848 	SqlSet    set;
849 	SqlBool   where;
850 	SqlSelect sel;
851 	SqlSet    ret;
852 
853 public:
854 	void Column(const SqlId& column, SqlVal val);
855 	void Column(const SqlSet& cols, const SqlSet& val);
operator()856 	SqlUpdate& operator()(const SqlId& column, SqlVal val)       { Column(column, val); return *this; }
operator()857 	SqlUpdate& operator()(const SqlSet& cols, const SqlSet& val) { Column(cols, val); return *this; }
858 	SqlUpdate& operator()(Fields f);
859 	SqlUpdate& operator()(const ValueMap& data);
860 
Get()861 	SqlUpdate& Get()                                 { sel.Get(); return *this; }
From()862 	SqlUpdate& From()                                { return Get(); }
From(const SqlSet & set)863 	SqlUpdate& From(const SqlSet& set)               { sel.From(set); return *this; }
From(const SqlId & table)864 	SqlUpdate& From(const SqlId& table)              { sel.From(table); return *this; }
From(const SqlVal & a)865 	SqlUpdate& From(const SqlVal& a)                 { sel.From(SqlSet(a)); return *this; }
866 
InnerJoin(const SqlId & table)867 	SqlUpdate& InnerJoin(const SqlId& table)         { sel.InnerJoin(table); return *this; }
LeftJoin(const SqlId & table)868 	SqlUpdate& LeftJoin(const SqlId& table)          { sel.LeftJoin(table); return *this; }
RightJoin(const SqlId & table)869 	SqlUpdate& RightJoin(const SqlId& table)         { sel.RightJoin(table); return *this; }
FullJoin(const SqlId & table)870 	SqlUpdate& FullJoin(const SqlId& table)          { sel.FullJoin(table); return *this; }
871 
InnerJoin(const SqlSet & set)872 	SqlUpdate& InnerJoin(const SqlSet& set)          { sel.InnerJoin(set); return *this; }
LeftJoin(const SqlSet & set)873 	SqlUpdate& LeftJoin(const SqlSet& set)           { sel.LeftJoin(set); return *this; }
RightJoin(const SqlSet & set)874 	SqlUpdate& RightJoin(const SqlSet& set)          { sel.RightJoin(set); return *this; }
FullJoin(const SqlSet & set)875 	SqlUpdate& FullJoin(const SqlSet& set)           { sel.FullJoin(set); return *this; }
876 
InnerJoinRef(const SqlId & table)877 	SqlUpdate& InnerJoinRef(const SqlId& table)      { sel.InnerJoinRef(table); return *this; }
LeftJoinRef(const SqlId & table)878 	SqlUpdate& LeftJoinRef(const SqlId& table)       { sel.LeftJoinRef(table); return *this; }
RightJoinRef(const SqlId & table)879 	SqlUpdate& RightJoinRef(const SqlId& table)      { sel.RightJoinRef(table); return *this; }
FullJoinRef(const SqlId & table)880 	SqlUpdate& FullJoinRef(const SqlId& table)       { sel.FullJoinRef(table); return *this; }
881 
On(const SqlBool & exp)882 	SqlUpdate& On(const SqlBool& exp)                { sel.On(exp); return *this; }
883 
884 	SqlUpdate& Where(SqlBool w);
885 	SqlUpdate& Returning(const SqlSet& set);
Returning(SqlVal a)886 	SqlUpdate& Returning(SqlVal a)                   { return Returning(SqlSet(a)); }
Returning(SqlVal a,SqlVal b)887 	SqlUpdate& Returning(SqlVal a, SqlVal b)         { return Returning(SqlSet(a, b)); }
Returning(SqlVal a,SqlVal b,SqlVal c)888 	SqlUpdate& Returning(SqlVal a, SqlVal b, SqlVal c){ return Returning(SqlSet(a, b, c)); }
889 
890 	operator SqlStatement() const;
891 
892 	operator bool() const                            { return !set.IsEmpty(); }
893 
894 	SqlUpdate(const SqlId& table);
895 	SqlUpdate(Fields f);
896 
897 //Deprecated!!!
Execute(Sql & sql)898 	bool  Execute(Sql& sql) const                     { return SqlStatement(*this).Execute(sql); }
Force(Sql & sql)899 	void  Force(Sql& sql) const                       { return SqlStatement(*this).Force(sql); }
Fetch(Sql & sql)900 	Value Fetch(Sql& sql) const                       { return SqlStatement(*this).Fetch(sql); }
Execute()901 	bool  Execute() const                             { return SqlStatement(*this).Execute(); }
Force()902 	void  Force() const                               { return SqlStatement(*this).Force(); }
Fetch()903 	Value Fetch() const                               { return SqlStatement(*this).Fetch(); }
904 };
905 
906 #else
907 
908 class SqlUpdate {
909 	SqlId   table;
910 	SqlSet  set;
911 	SqlBool where;
912 
913 public:
914 	void Column(const SqlId& column, SqlVal val);
915 	void Column(const SqlSet& cols, const SqlSet& val);
operator()916 	SqlUpdate& operator()(const SqlId& column, SqlVal val)       { Column(column, val); return *this; }
operator()917 	SqlUpdate& operator()(const SqlSet& cols, const SqlSet& val) { Column(cols, val); return *this; }
918 	SqlUpdate& operator()(Fields f);
919 	SqlUpdate& operator()(const ValueMap& data);
Where(SqlBool w)920 	SqlUpdate& Where(SqlBool w)                      { where = w; return *this; }
921 
922 	operator SqlStatement() const;
923 
924 	operator bool() const                            { return !set.IsEmpty(); }
925 
SqlUpdate(const SqlId & table)926 	SqlUpdate(const SqlId& table) : table(table) {}
927 	SqlUpdate(Fields f);
928 
929 //Deprecated!!!
Execute(Sql & sql)930 	bool  Execute(Sql& sql) const                     { return SqlStatement(*this).Execute(sql); }
Force(Sql & sql)931 	void  Force(Sql& sql) const                       { return SqlStatement(*this).Force(sql); }
Fetch(Sql & sql)932 	Value Fetch(Sql& sql) const                       { return SqlStatement(*this).Fetch(sql); }
Execute()933 	bool  Execute() const                             { return SqlStatement(*this).Execute(); }
Force()934 	void  Force() const                               { return SqlStatement(*this).Force(); }
Fetch()935 	Value Fetch() const                               { return SqlStatement(*this).Fetch(); }
936 };
937 
938 #endif
939 
Update(const SqlId & table)940 inline SqlUpdate Update(const SqlId& table)           { return SqlUpdate(table); }
Update(Fields f)941 inline SqlUpdate Update(Fields f)                     { return SqlUpdate(f); }
942 
943 class SqlWith {
944 	String text;
945 	bool   args;
946 
947 public:
948 	SqlWith& With(SqlId table);
949 	SqlWith& WithRecursive(SqlId table);
950 	SqlWith& Arg(SqlId arg);
951 //$-SqlWith& operator()(SqlId id, ..)
952 #define E__SqlId(I)     const SqlId& p##I
953 #define E__Arg(I)       Arg(p##I)
954 #define E__Args(I) \
955 	SqlWith& operator()(__List##I(E__SqlId)) { __List##I(E__Arg); return *this; }
956 	__Expand(E__Args);
957 #undef E__Args
958 #undef E__Arg
959 #undef E__SqlId
960 //$+
961 
962 	SqlWith& As(const SqlSelect& select);
963 
964 	SqlSelect    operator()(const SqlSelect& select);
965 	SqlStatement operator()(const SqlInsert& insert);
966 	SqlStatement operator()(const SqlUpdate& update);
967 	SqlStatement operator()(const SqlDelete& deletes);
968 
SqlWith()969 	SqlWith() { args = false; }
970 };
971 
With(SqlId id)972 inline SqlWith With(SqlId id)          { SqlWith w; w.With(id); return w; }
WithRecursive(SqlId id)973 inline SqlWith WithRecursive(SqlId id) { SqlWith w; w.WithRecursive(id); return w; }
974 
975 struct SqlCreateTable {
976 	SqlId  table;
977 	bool   permanent;
978 	bool   transaction;
979 
980 public:
PermanentSqlCreateTable981 	SqlCreateTable& Permanent()   { permanent = true; return *this; }
TransactionSqlCreateTable982 	SqlCreateTable& Transaction() { transaction = true; return *this; }
983 	SqlStatement As(const SqlSelect& select);
SqlCreateTableSqlCreateTable984 	SqlCreateTable(SqlId table) : table(table) { permanent = false; transaction = false; }
985 };
986 
Temporary(SqlId table)987 inline SqlCreateTable Temporary(SqlId table)          { return SqlCreateTable(table); }
CreateTable(SqlId table)988 inline SqlCreateTable CreateTable(SqlId table)        { SqlCreateTable w(table); w.Permanent(); return w; }
989