1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
#pragma once
#include "Core/Array.h"
#include "Type.h"
namespace sql {
/**
* A class that represents a generalized query string.
*
* This is so that we can describe parts of the query in a general manner, bridging the
* differences between different databases. Using this approach the query builder in the SQL
* library can output a generic representation of what it wishes to achieve, and then each SQL
* driver can make adjustments to fit the peculiarities of that driver.
*
* Some examples of differences:
* - Quoting of names: MySQL uses backtick, which is non-standard. Others use single quote.
* - Placeholders in prepared statements: Most accept ?, but Oracle uses a special syntax.
*
* The actual QueryStr class is immutable. Use the QueryBuilder to build a string.
*
* The representation in the class consists of a sequence of integers that dictate what to add,
* accompanied by a sequence of strings that are added as appropriate. The integers act like
* "op-codes" that determine how to interpret the strings, and if anything need to be added in
* between.
*/
class QueryStr : public Object {
STORM_CLASS;
public:
/**
* Class to generate a visitor.
*/
class Visitor : public Object {
STORM_ABSTRACT_CLASS;
public:
STORM_CTOR Visitor();
// Output regular text.
virtual void STORM_FN put(StrBuf *to, Str *text);
// Output a name.
virtual void STORM_FN name(StrBuf *to, Str *name);
// Output a placeholder.
virtual void STORM_FN placeholder(StrBuf *to);
// Output autoincrement.
virtual void STORM_FN autoIncrement(StrBuf *to);
// Output last row id.
virtual void STORM_FN lastRowId(StrBuf *to);
// Output a type.
virtual void STORM_FN type(StrBuf *to, QueryType type);
};
// Create.
QueryStr(GcArray<Nat> *ops, GcArray<Str *> *text);
// Generate a query string using the specified method.
Str *generate(Visitor *visitor) const;
// To string.
void STORM_FN toS(StrBuf *to) const override;
private:
// Operations.
GcArray<Nat> *opData;
// Text.
GcArray<Str *> *textData;
};
/**
* A builder class to create a QueryStr.
*/
class QueryStrBuilder : public Object {
STORM_CLASS;
public:
// Create.
STORM_CTOR QueryStrBuilder();
// Deep copy.
void STORM_FN deepCopy(CloneEnv *env);
// Add a piece of a regular string.
void STORM_FN put(Str *str);
void put(const wchar *str) { put(new (this) Str(str)); }
// Add a string as a quoted string literal.
void STORM_FN quoted(Str *str);
// Add a quoted name.
void STORM_FN name(Str *str);
// Add a placeholder for prepared statements.
void STORM_FN placeholder();
// Add "autoincrement" keyword.
void STORM_FN autoIncrement();
// Add expression for "last row id".
void STORM_FN lastRowId();
// Add a generic type.
void STORM_FN type(QueryType type);
// Create the query string.
QueryStr *STORM_FN build();
// Clear contents.
void STORM_FN clear();
private:
// String buffer for the string data being built.
StrBuf *currentStr;
// Op-code array being constructed.
Array<Nat> *ops;
// String array being constructed.
Array<Str *> *strings;
// Flush the current string.
void flush();
};
}
|