aboutsummaryrefslogtreecommitdiff
path: root/src/dictionary.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dictionary.c')
-rw-r--r--src/dictionary.c228
1 files changed, 228 insertions, 0 deletions
diff --git a/src/dictionary.c b/src/dictionary.c
new file mode 100644
index 0000000..c31baf8
--- /dev/null
+++ b/src/dictionary.c
@@ -0,0 +1,228 @@
+/* wydawca - automatic release submission daemon
+ Copyright (C) 2007 Sergey Poznyakoff
+
+ Wydawca is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+ Wydawca is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with wydawca. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "wydawca.h"
+#include "sql.h"
+#include "builtin.h"
+
+struct dictionary_descr
+{
+ const char *name;
+
+ int (*init) (struct dictionary *);
+ int (*done) (struct dictionary *);
+ int (*free) (struct dictionary *, void *);
+
+ void *(*open) (struct dictionary *);
+ int (*close) (struct dictionary *, void *);
+
+ int (*get) (struct dictionary *, void *, unsigned, unsigned);
+ int (*lookup) (struct dictionary *, void *, const char *);
+ int (*quote) (struct dictionary *, void *, const char *, char **, size_t *);
+};
+
+static struct dictionary_descr dictionary_tab[] = {
+ { "none", NULL, NULL, NULL, NULL, NULL, NULL, NULL },
+ { "sql", sql_init_dictionary, sql_done_dictionary, sql_free_result,
+ sql_open, NULL, sql_get_dictionary, sql_lookup_dictionary, sql_quote },
+ { "builtin", builtin_init, builtin_done, builtin_free_result,
+ builtin_open, NULL,
+ builtin_get,
+ builtin_lookup },
+ { "external", NULL, NULL, NULL, NULL, NULL, NULL, NULL }
+};
+
+struct dictionary *
+dictionary_new (enum dictionary_id id, enum dictionary_type type)
+{
+ struct dictionary *mp = xmalloc (sizeof mp[0]);
+ memset (mp, 0, sizeof mp[0]);
+ mp->id = id;
+ mp->type = type;
+ return mp;
+}
+
+int
+dictionary_init (struct dictionary *dict)
+{
+ struct dictionary_descr *mp = dictionary_tab + dict->type;
+ int rc = 0;
+
+ if (dict->init_passed++)
+ return 0;
+ if (debug_level > 1)
+ {
+ int i;
+ logmsg (LOG_DEBUG, _("initializing dictionary: %s \"%s\""),
+ mp->name, SP (dict->query));
+ for (i = 0; i < dict->parmc; i++)
+ logmsg (LOG_DEBUG, " parmv[%d]=%s", i, dict->parmv[i]);
+ }
+ if (mp->init)
+ rc = mp->init (dict);
+ if (rc == 0)
+ dict->init_passed = 1;
+ return rc;
+}
+
+void *
+dictionary_open (struct dictionary *dict)
+{
+ struct dictionary_descr *mp = dictionary_tab + dict->type;
+
+ if (!mp->open)
+ return NULL;
+ return mp->open (dict);
+}
+
+int
+dictionary_close (struct dictionary *dict, void *handle)
+{
+ struct dictionary_descr *mp = dictionary_tab + dict->type;
+ if (!mp->close)
+ return 0;
+ return mp->close (dict, handle);
+}
+
+int
+dictionary_done (struct dictionary *dict)
+{
+ struct dictionary_descr *mp = dictionary_tab + dict->type;
+ int rc = 0;
+
+ if (dict->init_passed == 0)
+ return 0;
+ if (--dict->init_passed)
+ return 0;
+ if (debug_level > 1)
+ {
+ int i;
+ logmsg (LOG_DEBUG, _("closing dictionary: %s \"%s\""),
+ mp->name, SP (dict->query));
+ for (i = 0; i < dict->parmc; i++)
+ logmsg (LOG_DEBUG, " parmv[%d]=%s", i, dict->parmv[i]);
+ }
+ if (mp->done)
+ rc = mp->done (dict);
+ free (dict->result);
+ dict->result = NULL;
+ dict->result_size = 0;
+ return rc;
+}
+
+int
+dictionary_lookup (struct dictionary *dict, void *handle, const char *cmd)
+{
+ struct dictionary_descr *mp = dictionary_tab + dict->type;
+
+ if (debug_level > 1)
+ {
+ if (cmd)
+ logmsg (LOG_DEBUG, _("dictionary lookup: %s \"%s\""),
+ mp->name, cmd);
+ else
+ logmsg (LOG_DEBUG, _("dictionary lookup: %s"), mp->name);
+ }
+
+ if (!dict->init_passed)
+ {
+ logmsg (LOG_CRIT,
+ _("INTERNAL ERROR: dictionary %s \"%s\" not initialized"),
+ mp->name, SP (dict->query));
+ return 1;
+ }
+ if (!mp->lookup)
+ {
+ logmsg (LOG_CRIT,
+ _("INTERNAL ERROR: no lookup function for dictionary %s \"%s\""),
+ mp->name, SP (dict->query));
+ return 1;
+ }
+ if (mp->free)
+ mp->free (dict, handle);
+ return mp->lookup (dict, handle, cmd);
+}
+
+unsigned
+dictionary_num_rows (struct dictionary *dict)
+{
+ return dict->nrow;
+}
+
+unsigned
+dictionary_num_cols (struct dictionary *dict)
+{
+ return dict->ncol;
+}
+
+const char *
+dictionary_result (struct dictionary *dict, void *handle,
+ unsigned nrow, unsigned ncol)
+{
+ struct dictionary_descr *mp = dictionary_tab + dict->type;
+
+ if (nrow >= dict->nrow || ncol >= dict->ncol
+ || mp->get (dict, handle, nrow, ncol))
+ return NULL;
+ return dict->result;
+}
+
+void
+dictionary_copy_result (struct dictionary *dict, const char *res, size_t size)
+{
+ if (dict->result_size < size + 1)
+ {
+ dict->result_size = size + 1;
+ dict->result = x2realloc (dict->result, &dict->result_size);
+ }
+ memcpy (dict->result, res, size);
+ dict->result[size] = 0;
+}
+
+/* Quote non-printable characters in INPUT. Point *OUTPUT to the malloc'ed
+ quoted string. Return its length. */
+int
+dictionary_quote_string (struct dictionary *dict, void *handle,
+ const char *input,
+ char **poutput, size_t *psize)
+{
+ struct dictionary_descr *mp = dictionary_tab + dict->type;
+ size_t size;
+ int quote;
+ char *output;
+
+ if (!input)
+ {
+ *poutput = xmalloc (1);
+ (*poutput)[0] = 0;
+ *psize = 1;
+ return 0;
+ }
+
+ if (mp->quote)
+ return mp->quote (dict, handle, input, poutput, psize);
+
+ size = wordsplit_quoted_length (input, 0, &quote);
+ output = xmalloc (size + 1);
+ wordsplit_quote_copy (output, input, 0);
+ output[size] = 0;
+
+ *poutput = output;
+ if (psize)
+ *psize = size;
+ return 0;
+}
+

Return to:

Send suggestions and report system problems to the System administrator.