1 #include "statementtokenbuilder.h"
2 #include "parser/ast/sqlitestatement.h"
3 #include "common/utils_sql.h"
4 #include <QVariant>
5
withKeyword(const QString & value)6 StatementTokenBuilder& StatementTokenBuilder::withKeyword(const QString& value)
7 {
8 return with(Token::KEYWORD, value);
9 }
10
withOther(const QString & value)11 StatementTokenBuilder& StatementTokenBuilder::withOther(const QString& value)
12 {
13 return withOther(value, true);
14 }
15
withOther(const QString & value,bool wrapIfNeeded)16 StatementTokenBuilder& StatementTokenBuilder::withOther(const QString& value, bool wrapIfNeeded)
17 {
18 return with(Token::OTHER, wrapIfNeeded ? wrapObjIfNeeded(value) : value);
19 }
20
withStringPossiblyOther(const QString & value)21 StatementTokenBuilder&StatementTokenBuilder::withStringPossiblyOther(const QString& value)
22 {
23 if (value.contains("\""))
24 return withOther(wrapObjIfNeeded(value));
25 else
26 return withOther(wrapObjName(value, NameWrapper::DOUBLE_QUOTE));
27 }
28
withOtherList(const QList<QString> & value,const QString & separator)29 StatementTokenBuilder& StatementTokenBuilder::withOtherList(const QList<QString>& value, const QString& separator)
30 {
31 bool first = true;
32 for (const QString& str : value)
33 {
34 if (!first)
35 {
36 if (!separator.isEmpty())
37 withOperator(separator);
38
39 withSpace();
40 }
41 withOther(str);
42 first = false;
43 }
44 return *this;
45 }
46
withOperator(const QString & value)47 StatementTokenBuilder& StatementTokenBuilder::withOperator(const QString& value)
48 {
49 return with(Token::OPERATOR, value);
50 }
51
withComment(const QString & value)52 StatementTokenBuilder& StatementTokenBuilder::withComment(const QString& value)
53 {
54 return with(Token::COMMENT, value);
55 }
56
withFloat(const QVariant & value)57 StatementTokenBuilder& StatementTokenBuilder::withFloat(const QVariant& value)
58 {
59 return with(Token::FLOAT, doubleToString(value));
60 }
61
withInteger(qint64 value)62 StatementTokenBuilder& StatementTokenBuilder::withInteger(qint64 value)
63 {
64 return with(Token::INTEGER, QString::number(value));
65 }
66
withBindParam(const QString & value)67 StatementTokenBuilder& StatementTokenBuilder::withBindParam(const QString& value)
68 {
69 return with(Token::BIND_PARAM, value);
70 }
71
withParLeft()72 StatementTokenBuilder& StatementTokenBuilder::withParLeft()
73 {
74 return with(Token::PAR_LEFT, "(");
75 }
76
withParRight()77 StatementTokenBuilder& StatementTokenBuilder::withParRight()
78 {
79 return with(Token::PAR_RIGHT, ")");
80 }
81
withSpace()82 StatementTokenBuilder& StatementTokenBuilder::withSpace()
83 {
84 return with(Token::SPACE, " ");
85 }
86
withBlob(const QString & value)87 StatementTokenBuilder& StatementTokenBuilder::withBlob(const QString& value)
88 {
89 return with(Token::BLOB, value);
90 }
91
withString(const QString & value)92 StatementTokenBuilder& StatementTokenBuilder::withString(const QString& value)
93 {
94 return with(Token::STRING, wrapStringIfNeeded(value));
95 }
96
withConflict(SqliteConflictAlgo onConflict)97 StatementTokenBuilder& StatementTokenBuilder::withConflict(SqliteConflictAlgo onConflict)
98 {
99 if (onConflict != SqliteConflictAlgo::null)
100 return withSpace().withKeyword("ON").withSpace().withKeyword("CONFLICT")
101 .withSpace().withKeyword(sqliteConflictAlgo(onConflict));
102
103 return *this;
104 }
105
withSortOrder(SqliteSortOrder sortOrder)106 StatementTokenBuilder& StatementTokenBuilder::withSortOrder(SqliteSortOrder sortOrder)
107 {
108 if (sortOrder != SqliteSortOrder::null)
109 return withSpace().withKeyword(sqliteSortOrder(sortOrder));
110
111 return *this;
112 }
113
withStatement(SqliteStatement * stmt)114 StatementTokenBuilder& StatementTokenBuilder::withStatement(SqliteStatement* stmt)
115 {
116 if (!stmt)
117 return *this;
118
119 stmt->rebuildTokens();
120 if (stmt->tokens.size() > 0)
121 {
122 if (tokens.size() > 0 && !tokens.last()->isWhitespace() && tokens.last()->type != Token::PAR_LEFT)
123 withSpace();
124
125 tokens += stmt->tokens;
126 tokens.trimRight(Token::OPERATOR, ";");
127 }
128 return *this;
129 }
130
withTokens(TokenList tokens)131 StatementTokenBuilder& StatementTokenBuilder::withTokens(TokenList tokens)
132 {
133 this->tokens += tokens;
134 return *this;
135 }
136
withLiteralValue(const QVariant & value)137 StatementTokenBuilder& StatementTokenBuilder::withLiteralValue(const QVariant& value)
138 {
139 if (value.isNull())
140 return *this;
141
142 if (value.userType() == QVariant::String)
143 {
144 withString(value.toString());
145 return *this;
146 }
147
148 bool ok;
149 if (value.userType() == QVariant::Double)
150 {
151 value.toDouble(&ok);
152 if (ok)
153 {
154 withFloat(value);
155 return *this;
156 }
157 }
158
159 qint64 longVal = value.toLongLong(&ok);
160 if (ok)
161 {
162 withInteger(longVal);
163 return *this;
164 }
165
166 QString str = value.toString();
167 if (str.startsWith("x'", Qt::CaseInsensitive) && str.endsWith("'"))
168 {
169 withBlob(str);
170 return *this;
171 }
172
173 withString(str);
174 return *this;
175 }
176
build() const177 TokenList StatementTokenBuilder::build() const
178 {
179 return tokens;
180 }
181
clear()182 void StatementTokenBuilder::clear()
183 {
184 tokens.clear();
185 currentIdx = 0;
186 }
187
with(Token::Type type,const QString & value)188 StatementTokenBuilder& StatementTokenBuilder::with(Token::Type type, const QString& value)
189 {
190 int size = value.size();
191 tokens << TokenPtr::create(type, value, currentIdx, currentIdx + size - 1);
192 currentIdx += size;
193 return *this;
194 }
195