1 /* This file is part of the Zebra server.
2 Copyright (C) 1994-2009 Index Data
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #include "indexplugin.h"
21 #include <mysql/mysql.h>
26 static int mysqlConnect(const char *username, const char *password, const char *database, const char *hostname)
30 /* Set the default encoding to utf-8 so that zebra
31 doesn't gribe that the XML conflicts with it's encoding */
32 mysql_options(&mCon, MYSQL_SET_CHARSET_NAME, "utf8");
34 mysql_options(&mCon, MYSQL_READ_DEFAULT_GROUP, "indexplugin_mysql");
35 if (!mysql_real_connect(&mCon, hostname, username, password, database, 0, NULL, 0))
37 yaz_log(YLOG_FATAL, "Failed to connect to database: %s\n", mysql_error(&mCon));
42 yaz_log(YLOG_LOG, "Connected to Mysql Database");
49 static int repositoryExtract(ZebraHandle zh, const char *driverCommand, enum zebra_recctrl_action_t action)
51 /* this doesn't really need to be initialised */
54 //nasty parsing method
55 char *sqlQuery = strchr(driverCommand, ':');
56 if(sqlQuery) *(sqlQuery ++) = NULL;
59 yaz_log(YLOG_LOG, "No MySQL Query given, falling back on config default");
60 sqlQuery = res_get_named(zh->session_res, "indexplugin.mysql_defaultsql", driverCommand);
63 yaz_log(YLOG_LOG, "Database configuration selected: %s", driverCommand);
65 //Get our connection specific info from the config
66 //TODO: make the "test" bit configurable by command line
67 const char *username = res_get_named(zh->session_res, "indexplugin.mysql_username", driverCommand);
68 const char *password = res_get_named(zh->session_res, "indexplugin.mysql_password", driverCommand);
69 const char *hostname = res_get_named(zh->session_res, "indexplugin.mysql_hostname", driverCommand);
70 const char *database = res_get_named(zh->session_res, "indexplugin.mysql_database", driverCommand);
72 const char *idfield = res_get_named(zh->session_res, "indexplugin.mysql_idfield", driverCommand);
73 const char *datafield = res_get_named(zh->session_res, "indexplugin.mysql_datafield", driverCommand);
77 yaz_log(YLOG_FATAL, "Database configuration incomplete or missing");
83 yaz_log(YLOG_FATAL, "No valid MySQL query");
92 //This is a rudimentary way of binding fields, it's nasty
93 uint8_t fieldBind[2] = {0xFF, 0xFF};
95 yaz_log(YLOG_LOG, "MySQL Query: %s", sqlQuery);
97 if ((ret = mysqlConnect(username, password, database, hostname)) == ZEBRA_OK)
99 const char *mQuery = sqlQuery;
100 if (mysql_real_query(&mCon, mQuery, strlen(mQuery)) == 0)
102 MYSQL_RES *result = NULL;
103 if ((result = mysql_store_result(&mCon)))
105 //Check for the binding fields
108 while(field = mysql_fetch_field(result))
110 if(strcmp(field->name, idfield) == 0) fieldBind[IDFIELD] = i;
111 if(strcmp(field->name, datafield) == 0) fieldBind[DATAFIELD] = i;
115 //Test the binding fields
116 if(fieldBind[IDFIELD] == 0xFF || fieldBind[DATAFIELD] == 0xFF)
118 yaz_log(YLOG_FATAL, "Query did not reveal all/any binding columns");
123 yaz_log(YLOG_LOG, "Successfully found all binding columns");
125 unsigned int num_fields;
126 num_fields = mysql_num_fields(result);
129 while ((row = mysql_fetch_row(result)))
131 unsigned long *lengths;
132 lengths = mysql_fetch_lengths(result);
134 //This is the critical line, that actually indexes your data
135 //Args: Zebra Handle, Data, Data length, Action, FileName(Unique identifier)
136 zebraIndexBuffer(zh, row[fieldBind[DATAFIELD]], lengths[fieldBind[DATAFIELD]], action, row[fieldBind[IDFIELD]]);
139 mysql_free_result(result);
144 yaz_log(YLOG_FATAL, "Failed to run query: %s", mysql_error(&mCon));
149 /* Drop our MYSQL connection as we don't need it anymore
150 and deallocate anything allocated */
156 void indexPluginRegister(void)
158 /* register our function that gets called while indexing a document */
159 addDriverFunction(repositoryExtract);
164 * c-file-style: "Stroustrup"
165 * indent-tabs-mode: nil
167 * vim: shiftwidth=4 tabstop=8 expandtab