00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00040 #include "pg_sql.h"
00041
00042 #include "../../lib/srdb2/db_cmd.h"
00043 #include "../../lib/srdb2/db_fld.h"
00044 #include "../../mem/mem.h"
00045 #include "../../dprint.h"
00046 #include "../../ut.h"
00047
00048 #include <string.h>
00049
00050
00051 enum {
00052 STR_DELETE,
00053 STR_INSERT,
00054 STR_UPDATE,
00055 STR_SELECT,
00056 STR_REPLACE,
00057 STR_SET,
00058 STR_WHERE,
00059 STR_IS,
00060 STR_AND,
00061 STR_OR,
00062 STR_ESC,
00063 STR_OP_EQ,
00064 STR_OP_NE,
00065 STR_OP_LT,
00066 STR_OP_GT,
00067 STR_OP_LEQ,
00068 STR_OP_GEQ,
00069 STR_VALUES,
00070 STR_FROM,
00071 STR_OID,
00072 STR_TIMESTAMP,
00073 STR_ZT
00074 };
00075
00076
00077 static str strings[] = {
00078 STR_STATIC_INIT("delete from "),
00079 STR_STATIC_INIT("insert into "),
00080 STR_STATIC_INIT("update "),
00081 STR_STATIC_INIT("select "),
00082 STR_STATIC_INIT("replace "),
00083 STR_STATIC_INIT(" set "),
00084 STR_STATIC_INIT(" where "),
00085 STR_STATIC_INIT(" is "),
00086 STR_STATIC_INIT(" and "),
00087 STR_STATIC_INIT(" or "),
00088 STR_STATIC_INIT("?"),
00089 STR_STATIC_INIT("="),
00090 STR_STATIC_INIT("!="),
00091 STR_STATIC_INIT("<"),
00092 STR_STATIC_INIT(">"),
00093 STR_STATIC_INIT("<="),
00094 STR_STATIC_INIT(">="),
00095 STR_STATIC_INIT(") values ("),
00096 STR_STATIC_INIT(" from "),
00097 STR_STATIC_INIT("select typname,pg_type.oid from pg_type"),
00098 STR_STATIC_INIT("select timestamp '2000-01-01 00:00:00' + time '00:00:01'"),
00099 STR_STATIC_INIT("\0")
00100 };
00101
00102
00106 struct string_buffer {
00107 char *s;
00108 int len;
00109 int size;
00110 int increment;
00111 };
00112
00113
00122 static inline int sb_add(struct string_buffer *sb, str *nstr)
00123 {
00124 int new_size = 0;
00125 int rsize = sb->len + nstr->len;
00126 int asize;
00127 char *newp;
00128
00129 if (rsize > sb->size) {
00130 asize = rsize - sb->size;
00131 new_size = sb->size + (asize / sb->increment +
00132 (asize % sb->increment > 0)) * sb->increment;
00133 newp = pkg_malloc(new_size);
00134 if (!newp) {
00135 ERR("postgres: No memory left\n");
00136 return -1;
00137 }
00138 if (sb->s) {
00139 memcpy(newp, sb->s, sb->len);
00140 pkg_free(sb->s);
00141 }
00142 sb->s = newp;
00143 sb->size = new_size;
00144 }
00145 memcpy(sb->s + sb->len, nstr->s, nstr->len);
00146 sb->len += nstr->len;
00147 return 0;
00148 }
00149
00150
00159 static inline str* set_str(str *str, const char *s)
00160 {
00161 str->s = (char *)s;
00162 str->len = strlen(s);
00163 return str;
00164 }
00165
00166
00173 static str* get_marker(unsigned int i)
00174 {
00175 static char buf[INT2STR_MAX_LEN + 1];
00176 static str res;
00177 const char* c;
00178
00179 buf[0] = '$';
00180 res.s = buf;
00181
00182 c = int2str(i, &res.len);
00183 memcpy(res.s + 1, c, res.len);
00184 res.len++;
00185 return &res;
00186 }
00187
00188
00189 int build_update_sql(str* sql_cmd, db_cmd_t* cmd)
00190 {
00191 struct string_buffer sql_buf = {.s = NULL, .len = 0,
00192 .size = 0, .increment = 128};
00193 db_fld_t* fld;
00194 int i, rv = 0;
00195 str tmpstr;
00196
00197 rv = sb_add(&sql_buf, &strings[STR_UPDATE]);
00198 rv |= sb_add(&sql_buf, set_str(&tmpstr, "\""));
00199 rv |= sb_add(&sql_buf, &cmd->table);
00200 rv |= sb_add(&sql_buf, set_str(&tmpstr, "\""));
00201 rv |= sb_add(&sql_buf, &strings[STR_SET]);
00202
00203
00204 for(i = 0, fld = cmd->vals; !DB_FLD_EMPTY(fld) && !DB_FLD_LAST(fld[i]); i++) {
00205 rv |= sb_add(&sql_buf, set_str(&tmpstr, fld[i].name));
00206 rv |= sb_add(&sql_buf, set_str(&tmpstr, "="));
00207 rv |= sb_add(&sql_buf, &strings[STR_ESC]);
00208 if (!DB_FLD_LAST(fld[i + 1])) rv |= sb_add(&sql_buf, set_str(&tmpstr, ","));
00209 }
00210 if (rv) goto error;
00211
00212 if (!DB_FLD_EMPTY(cmd->match)) {
00213 rv |= sb_add(&sql_buf, &strings[STR_WHERE]);
00214
00215 for(i = 0, fld = cmd->match; !DB_FLD_LAST(fld[i]); i++) {
00216 rv |= sb_add(&sql_buf, set_str(&tmpstr, fld[i].name));
00217
00218 switch(fld[i].op) {
00219 case DB_EQ: rv |= sb_add(&sql_buf, &strings[STR_OP_EQ]); break;
00220 case DB_NE: rv |= sb_add(&sql_buf, &strings[STR_OP_NE]); break;
00221 case DB_LT: rv |= sb_add(&sql_buf, &strings[STR_OP_LT]); break;
00222 case DB_GT: rv |= sb_add(&sql_buf, &strings[STR_OP_GT]); break;
00223 case DB_LEQ: rv |= sb_add(&sql_buf, &strings[STR_OP_LEQ]); break;
00224 case DB_GEQ: rv |= sb_add(&sql_buf, &strings[STR_OP_GEQ]); break;
00225 }
00226
00227 rv |= sb_add(&sql_buf, get_marker(i + 1));
00228 if (!DB_FLD_LAST(fld[i + 1])) rv |= sb_add(&sql_buf, &strings[STR_AND]);
00229 }
00230 }
00231 rv |= sb_add(&sql_buf, &strings[STR_ZT]);
00232 if (rv) goto error;
00233
00234 sql_cmd->s = sql_buf.s;
00235 sql_cmd->len = sql_buf.len;
00236 return 0;
00237
00238 error:
00239 if (sql_buf.s) pkg_free(sql_buf.s);
00240 return -1;
00241 }
00242
00243
00244 int build_insert_sql(str* sql_cmd, db_cmd_t* cmd)
00245 {
00246 struct string_buffer sql_buf = {.s = NULL, .len = 0,
00247 .size = 0, .increment = 128};
00248 db_fld_t* fld;
00249 int i, rv = 0;
00250 str tmpstr;
00251
00252 rv = sb_add(&sql_buf, &strings[STR_INSERT]);
00253 rv |= sb_add(&sql_buf, set_str(&tmpstr, "\""));
00254 rv |= sb_add(&sql_buf, &cmd->table);
00255 rv |= sb_add(&sql_buf, set_str(&tmpstr, "\" ("));
00256
00257
00258 for(i = 0, fld = cmd->vals; !DB_FLD_EMPTY(fld) && !DB_FLD_LAST(fld[i]); i++) {
00259 rv |= sb_add(&sql_buf, set_str(&tmpstr, fld[i].name));
00260 if (!DB_FLD_LAST(fld[i + 1])) rv |= sb_add(&sql_buf, set_str(&tmpstr, ","));
00261 }
00262 if (rv) goto error;
00263
00264 rv |= sb_add(&sql_buf, &strings[STR_VALUES]);
00265
00266 for(i = 0, fld = cmd->vals; !DB_FLD_EMPTY(fld) && !DB_FLD_LAST(fld[i]); i++) {
00267 rv |= sb_add(&sql_buf, get_marker(i + 1));
00268 if (!DB_FLD_LAST(fld[i + 1])) rv |= sb_add(&sql_buf, set_str(&tmpstr, ","));
00269 }
00270 rv |= sb_add(&sql_buf, set_str(&tmpstr, ")"));
00271 rv |= sb_add(&sql_buf, &strings[STR_ZT]);
00272 if (rv) goto error;
00273
00274 sql_cmd->s = sql_buf.s;
00275 sql_cmd->len = sql_buf.len;
00276 return 0;
00277
00278 error:
00279 if (sql_buf.s) pkg_free(sql_buf.s);
00280 return -1;
00281 }
00282
00283
00284 int build_delete_sql(str* sql_cmd, db_cmd_t* cmd)
00285 {
00286 struct string_buffer sql_buf = {.s = NULL, .len = 0,
00287 .size = 0, .increment = 128};
00288 db_fld_t* fld;
00289 int i, rv = 0;
00290 str tmpstr;
00291
00292 rv = sb_add(&sql_buf, &strings[STR_DELETE]);
00293 rv |= sb_add(&sql_buf, set_str(&tmpstr, "\""));
00294 rv |= sb_add(&sql_buf, &cmd->table);
00295 rv |= sb_add(&sql_buf, set_str(&tmpstr, "\""));
00296
00297 if (!DB_FLD_EMPTY(cmd->match)) {
00298 rv |= sb_add(&sql_buf, &strings[STR_WHERE]);
00299
00300 for(i = 0, fld = cmd->match; !DB_FLD_LAST(fld[i]); i++) {
00301 rv |= sb_add(&sql_buf, set_str(&tmpstr, fld[i].name));
00302
00303 switch(fld[i].op) {
00304 case DB_EQ: rv |= sb_add(&sql_buf, &strings[STR_OP_EQ]); break;
00305 case DB_NE: rv |= sb_add(&sql_buf, &strings[STR_OP_NE]); break;
00306 case DB_LT: rv |= sb_add(&sql_buf, &strings[STR_OP_LT]); break;
00307 case DB_GT: rv |= sb_add(&sql_buf, &strings[STR_OP_GT]); break;
00308 case DB_LEQ: rv |= sb_add(&sql_buf, &strings[STR_OP_LEQ]); break;
00309 case DB_GEQ: rv |= sb_add(&sql_buf, &strings[STR_OP_GEQ]); break;
00310 }
00311
00312 rv |= sb_add(&sql_buf, get_marker(i + 1));
00313 if (!DB_FLD_LAST(fld[i + 1])) rv |= sb_add(&sql_buf, &strings[STR_AND]);
00314 }
00315 }
00316 rv |= sb_add(&sql_buf, &strings[STR_ZT]);
00317 if (rv) goto error;
00318
00319 sql_cmd->s = sql_buf.s;
00320 sql_cmd->len = sql_buf.len;
00321 return 0;
00322
00323 error:
00324 if (sql_buf.s) pkg_free(sql_buf.s);
00325 return -1;
00326 }
00327
00328
00329 int build_select_sql(str* sql_cmd, db_cmd_t* cmd)
00330 {
00331 struct string_buffer sql_buf = {.s = NULL, .len = 0,
00332 .size = 0, .increment = 128};
00333 db_fld_t* fld;
00334 int i, rv = 0;
00335 str tmpstr;
00336
00337 rv = sb_add(&sql_buf, &strings[STR_SELECT]);
00338
00339 if (DB_FLD_EMPTY(cmd->result)) {
00340 rv |= sb_add(&sql_buf, set_str(&tmpstr, "*"));
00341 } else {
00342 for(i = 0, fld = cmd->result; !DB_FLD_LAST(fld[i]); i++) {
00343 rv |= sb_add(&sql_buf, set_str(&tmpstr, fld[i].name));
00344 if (!DB_FLD_LAST(fld[i + 1])) rv |= sb_add(&sql_buf, set_str(&tmpstr, ","));
00345 }
00346 }
00347
00348 rv |= sb_add(&sql_buf, &strings[STR_FROM]);
00349 rv |= sb_add(&sql_buf, set_str(&tmpstr, "\""));
00350 rv |= sb_add(&sql_buf, &cmd->table);
00351 rv |= sb_add(&sql_buf, set_str(&tmpstr, "\""));
00352
00353 if (!DB_FLD_EMPTY(cmd->match)) {
00354 rv |= sb_add(&sql_buf, &strings[STR_WHERE]);
00355
00356 for(i = 0, fld = cmd->match; !DB_FLD_LAST(fld[i]); i++) {
00357 rv |= sb_add(&sql_buf, set_str(&tmpstr, fld[i].name));
00358
00359 switch(fld[i].op) {
00360 case DB_EQ: rv |= sb_add(&sql_buf, &strings[STR_OP_EQ]); break;
00361 case DB_NE: rv |= sb_add(&sql_buf, &strings[STR_OP_NE]); break;
00362 case DB_LT: rv |= sb_add(&sql_buf, &strings[STR_OP_LT]); break;
00363 case DB_GT: rv |= sb_add(&sql_buf, &strings[STR_OP_GT]); break;
00364 case DB_LEQ: rv |= sb_add(&sql_buf, &strings[STR_OP_LEQ]); break;
00365 case DB_GEQ: rv |= sb_add(&sql_buf, &strings[STR_OP_GEQ]); break;
00366 }
00367
00368 rv |= sb_add(&sql_buf, get_marker(i + 1));
00369 if (!DB_FLD_LAST(fld[i + 1])) rv |= sb_add(&sql_buf, &strings[STR_AND]);
00370 }
00371 }
00372 rv |= sb_add(&sql_buf, &strings[STR_ZT]);
00373 if (rv) goto error;
00374
00375 sql_cmd->s = sql_buf.s;
00376 sql_cmd->len = sql_buf.len;
00377 return 0;
00378
00379 error:
00380 if (sql_buf.s) pkg_free(sql_buf.s);
00381 return -1;
00382 }
00383
00384
00385 int build_select_oid_sql(str* sql_cmd)
00386 {
00387 struct string_buffer sql_buf = {.s = NULL, .len = 0,
00388 .size = 0, .increment = 128};
00389 int rv = 0;
00390
00391 rv = sb_add(&sql_buf, &strings[STR_OID]);
00392 rv |= sb_add(&sql_buf, &strings[STR_ZT]);
00393 if (rv) goto error;
00394
00395 sql_cmd->s = sql_buf.s;
00396 sql_cmd->len = sql_buf.len;
00397 return 0;
00398
00399 error:
00400 if (sql_buf.s) pkg_free(sql_buf.s);
00401 return -1;
00402 }
00403
00404
00405 int build_timestamp_format_sql(str* sql_cmd)
00406 {
00407 struct string_buffer sql_buf = {.s = NULL, .len = 0,
00408 .size = 0, .increment = 128};
00409 int rv = 0;
00410
00411 rv = sb_add(&sql_buf, &strings[STR_TIMESTAMP]);
00412 rv |= sb_add(&sql_buf, &strings[STR_ZT]);
00413 if (rv) goto error;
00414
00415 sql_cmd->s = sql_buf.s;
00416 sql_cmd->len = sql_buf.len;
00417 return 0;
00418
00419 error:
00420 if (sql_buf.s) pkg_free(sql_buf.s);
00421 return -1;
00422 }
00423