|
void wftk_sql_build_select (XML * list, char * key, WFTK_SQL_FORCE_MAPPING force)
{
XML * field;
XML * query = xml_create ("q");
char * value;
/* Make sure table is set in list definition. */
if (!*xml_attrval (list, "table")) xml_set (list, "table", xml_attrval (list, "id"));
/* Build the where clause for the query. */
/* TODO: this is incredibly naive and needs to know a lot more about the new where specs. */
/* TODO: See whether Oracle minds quotes around numeric constants, as MySQL doesn't. */
/* TODO: Make sure we look at type in the first place, oy. */
xml_set (query, "where", xml_attrval (list, "where"));
field = xml_firstelem (list);
while (field) {
if (xml_is (field, "field")) {
if (force) { (*force) (field); }
if (!strcmp (xml_attrval (field, "special"), "constant")) {
value = xml_stringcontenthtml (field);
if (*xml_attrval (query, "where")) { xml_attrcat (query, "where", " and "); }
xml_attrcat (query, "where", xml_attrval (field, "alias"));
xml_attrcat (query, "where", "='");
sql_escaped_append (query, "where", value);
xml_attrcat (query, "where", "'");
free ((void *) value);
}
}
field = xml_nextelem (field);
}
if (key) {
if (!*xml_attrval (list, "key")) {
field = xml_search (list, "field", NULL, NULL);
xml_set (list, "key", xml_attrval (field, "id"));
}
if (*xml_attrval (query, "where")) { xml_attrcat (query, "where", " and "); }
xml_attrcat (query, "where", xml_attrval (list, "key")); /* TODO: map key */
xml_attrcat (query, "where", "='");
sql_escaped_append (query, "where", key);
xml_attrcat (query, "where", "'");
}
/* Build the query itself. */
/* TODO: note that our order builder is also way too damned naive. */
xml_setf (list, "_select", "select * from %s", xml_attrval (list, "table"));
if (*xml_attrval (query, "where")) {
xml_attrcat (list, "_select", " where ");
xml_attrcat (list, "_select", xml_attrval (query, "where"));
}
if (*xml_attrval (list, "order")) {
xml_attrcat (list, "_select", " order by ");
xml_attrcat (list, "_select", xml_attrval (list, "order"));
}
xml_free (query);
}
XML * wftk_sql_build_insert (XML * list, XML * object, WFTK_SQL_FORCE_MAPPING force)
{
XML * query = xml_create ("q");
XML * mark;
XML * field;
XML * rest_xml = NULL;
char * value;
int keygen = 0;
char timebuf[20];
struct tm * timeptr;
time_t julian;
/* Make sure table is set in list definition. */
if (!*xml_attrval (list, "table")) xml_set (list, "table", xml_attrval (list, "id"));
xml_set (query, "fields", "");
xml_set (query, "values", "");
keygen = 0;
/* Get the time. */
time (&julian);
timeptr = localtime (&julian);
sprintf (timebuf, "'%04d%02d%02d_%02d%02d%02d'",
timeptr->tm_year + 1900, timeptr->tm_mon + 1, timeptr->tm_mday,
timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec);
for (mark = xml_firstelem (list); mark; mark = xml_nextelem (mark)) { /* First scan to see whether there's a rest_xml field. */
if (xml_is (mark, "field") && force) { (*force) (mark); }
if (xml_is (mark, "field") && !strcmp ("rest_xml", xml_attrval (mark, "special"))) {
rest_xml = xml_copy (object);
xml_set (rest_xml, "storage", xml_attrval (mark, "storage"));
xml_set (rest_xml, "field", xml_attrval (mark, "alias"));
break;
}
}
for (mark = xml_firstelem (list); mark; mark = xml_nextelem (mark)) { /* Second scan to build actual query. */
if (xml_is (mark, "field")) {
if (!keygen && !strcmp (xml_attrval (mark, "special"), "key")) {
keygen = 1;
xml_set (query, "keygen", xml_attrval (mark, "id"));
field = xml_search (object, "field", "id", xml_attrval (mark, "id"));
if (!field) {
field = xml_create ("field");
xml_set (field, "id", xml_attrval (mark, "id"));
if (*xml_attrval (mark, "type")) xml_set (field, "type", xml_attrval (mark, "type"));
xml_prepend_pretty (object, field);
}
xml_set_nodup (query, "keygeninit", xmlobj_get (object, list, xml_attrval (mark, "id"))); /* TODO: LIST_localdir should do this, too. */
if (!*xml_attrval (mark, "keygen")) xml_set (mark, "keygen", xml_attrval (list, "_keygen"));
if (*xml_attrval (mark, "keygen")) {
xml_unset (query, "keygen");
xml_attrcat (query, "fields", ", ");
xml_attrcat (query, "fields", xml_attrval (mark, "alias"));
xml_attrcat (query, "values", ", ");
xml_setf (query, "_keygen", xml_attrval (mark, "keygen"), xml_attrval (list, "table"), xml_attrval (mark, "id"));
xml_attrcat (query, "values", xml_attrval (query, "_keygen"));
xml_set (list, "_keycol", xml_attrval (mark, "id"));
}
xmlobj_unset (rest_xml, NULL, xml_attrval (mark, "id"));
} else {
if (rest_xml) {
if (!strcmp (xml_attrval (mark, "special"), "constant") ||
!strcmp (xml_attrval (mark, "special"), "key") ||
!strcmp (xml_attrval (mark, "special"), "rest_xml") ||
!strcmp (xml_attrval (mark, "id"), xml_attrval (list, "keycol")) ||
(!strcmp (xml_attrval (mark, "storage"), "record") ||
!strncmp (xml_attrval (mark, "storage"), "record:", 7))) {
xmlobj_unset (rest_xml, NULL, xml_attrval (mark, "id"));
} else {
continue; /* If not stored in record, skip this field. */
}
}
/* Handle field. */
xml_attrcat (query, "fields", ", ");
xml_attrcat (query, "fields", *xml_attrval (mark, "alias") ? xml_attrval (mark, "alias") : xml_attrval (mark, "id"));
xml_attrcat (query, "values", ", ");
if (strcmp (xml_attrval (mark, "special"), "constant")) {
value = xmlobj_get (object, list, xml_attrval (mark, "id"));
if (!value) value = strdup ("");
} else {
value = xml_stringcontenthtml (mark);
field = xml_search (object, "field", "id", xml_attrval (mark, "id"));
if (!field) {
field = xml_create ("field");
xml_set (field, "id", xml_attrval (mark, "id"));
if (*xml_attrval (mark, "type")) xml_set (field, "type", xml_attrval (mark, "type"));
xml_append_pretty (object, field);
}
xml_replacecontent (field, xml_createtext (value));
}
if (!strcmp (xml_attrval (mark, "special"), "now") || !strcmp (xml_attrval (mark, "special"), "add")) {
xml_attrcat (query, "values", *xml_attrval (list, "_now") ? xml_attrval (list, "_now") : timebuf);
} else if (!strncmp (xml_attrval (mark, "type"), "numeric", 7)) {
if (!value) {
xml_attrcat (query, "values", "0");
} else if (!*value) {
xml_attrcat (query, "values", "0");
} else {
xml_attrcat (query, "values", value);
}
} else if (!strcmp (xml_attrval (mark, "special"), "rest_xml")) {
xml_attrcat (query, "values", *xml_attrval (list, "_blob") ? xml_attrval (list, "_blob") : "''");
} else {
xml_attrcat (query, "values", "'");
sql_escaped_append (query, "values", value);
xml_attrcat (query, "values", "'");
}
if (value) free ((void *)value);
}
}
}
if (keygen && *xml_attrval (query, "keygen")) {
sprintf (timebuf + 16, "_%d", rand() * 100 / RAND_MAX);
xml_setf (list, "_keyval", "%s%s", xml_attrval (query, "keygeninit"), timebuf + 1);
xml_set (list, "_retry", "yes");
xml_setf (list, "_insert", "insert into %s (%s%s) values ('%s'%s)",
xml_attrval (list, "table"),
xml_attrval (query, "keygen"),
xml_attrval (query, "fields"),
xml_attrval (list, "_keyval"),
xml_attrval (query, "values"));
} else {
xml_unset (list, "_retry");
xml_unset (list, "_keyval");
xml_setf (list, "_insert", "insert into %s (%s) values (%s)",
xml_attrval (list, "table"),
xml_attrval (query, "fields") + 2,
xml_attrval (query, "values") + 2);
}
xml_free (query);
return (rest_xml);
}
|