summaryrefslogtreecommitdiffstats
path: root/server/parser/pgsql.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/parser/pgsql.c')
-rw-r--r--server/parser/pgsql.c65
1 files changed, 64 insertions, 1 deletions
diff --git a/server/parser/pgsql.c b/server/parser/pgsql.c
index 44032e5..8ea5d08 100644
--- a/server/parser/pgsql.c
+++ b/server/parser/pgsql.c
@@ -44,6 +44,14 @@
#include <log.h>
#include <statuses.h>
+/** forward declaration, to be able to setup dbhelper_func pointers */
+static char * pgsql_BuildArray(LogContext *log, xmlNode *sql_n);
+
+/** Helper functions the xmlparser might beed */
+static dbhelper_func pgsql_helpers = {
+ .dbh_FormatArray = &(pgsql_BuildArray)
+};
+
/**
* Connect to a database, based on the given configuration
*
@@ -106,7 +114,7 @@ dbconn *db_connect(eurephiaVALUES *cfg, unsigned int id, LogContext *log) {
if( dbr ) {
PQclear(dbr);
}
-
+ init_xmlparser(&pgsql_helpers);
return ret;
}
@@ -414,6 +422,61 @@ eurephiaVALUES *pgsql_INSERT(dbconn *dbc, xmlDoc *sqldoc) {
return res;
}
+/**
+ * @copydoc sqldataValueArray()
+ */
+static char * pgsql_BuildArray(LogContext *log, xmlNode *sql_n) {
+ char *ret = NULL, *ptr = NULL;
+ xmlNode *node = NULL;
+ size_t retlen = 0;
+
+ ret = malloc_nullsafe(log, 2);
+ if( ret == NULL ) {
+ writelog(log, LOG_ERR,
+ "Failed to allocate memory for a new PostgreSQL array");
+ return NULL;
+ }
+ strncat(ret, "{", 1);
+
+ /* Iterate all ./value/value elements and build up a PostgreSQL specific array */
+ foreach_xmlnode(sql_n->children, node) {
+ if( (node->type != XML_ELEMENT_NODE)
+ || xmlStrcmp(node->name, (xmlChar *) "value") != 0 ) {
+ // Skip uninteresting nodes
+ continue;
+ }
+ ptr = sqldataValueHash(log, node);
+ if( ptr ) {
+ retlen += strlen(ptr) + 4;
+ ret = realloc(ret, retlen);
+ if( ret == NULL ) {
+ writelog(log, LOG_ERR,
+ "Failed to allocate memory to expand "
+ "array to include '%s'", ptr);
+ free_nullsafe(ret);
+ free_nullsafe(ptr);
+ return NULL;
+ }
+ /* Newer PostgreSQL servers expects numbers to be without quotes */
+ if( isNumber(ptr) == 0 ) {
+ /* Data is a string */
+ strncat(ret, "'", 1);
+ strncat(ret, ptr, strlen(ptr));
+ strncat(ret, "',", 2);
+ } else {
+ /* Data is a number */
+ strncat(ret, ptr, strlen(ptr));
+ strncat(ret, ",", 1);
+ }
+ free_nullsafe(ptr);
+ }
+ }
+ /* Replace the last comma with a close-array marker */
+ ret[strlen(ret)-1] = '}';
+ ret[strlen(ret)] = 0;
+ return ret;
+}
+
/**
* Start an SQL transaction (SQL BEGIN)