summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--baltisot-config.in4
-rw-r--r--include/BString.h5
-rw-r--r--include/ConfigFile.h27
-rw-r--r--include/Makefile.am2
-rw-r--r--include/SQL.h17
-rw-r--r--lib/ConfigFile.cc43
-rw-r--r--lib/Makefile.am2
-rw-r--r--lib/SQL.cc61
-rw-r--r--lib/String.cc28
9 files changed, 170 insertions, 19 deletions
diff --git a/baltisot-config.in b/baltisot-config.in
index c9e846d..6262e8a 100644
--- a/baltisot-config.in
+++ b/baltisot-config.in
@@ -39,11 +39,11 @@ while test $# -gt 0; do
echo @VERSION@
;;
--cflags)
- echo -I@includedir@/Baltisot
+ echo -I@includedir@/Baltisot @CFLAGS@ @MYSQL_CFLAGS@
;;
--libs)
libdirs="-L@libdir@"
- echo $libdirs -lBaltisot @LIBS@
+ echo $libdirs -lBaltisot @LIBS@ @MYSQL_LIBS@
;;
*)
echo "${usage}" 1>&2
diff --git a/include/BString.h b/include/BString.h
index b5a273f..4540e70 100644
--- a/include/BString.h
+++ b/include/BString.h
@@ -47,6 +47,9 @@ class String : public Base {
ssize_t strrchr(char) const;
ssize_t strstr(const String &) const;
int strchrcnt(char) const;
+ String ltrim() const;
+ String rtrim() const;
+ String trim() const;
String & operator=(const String &);
String operator+(const String &) const;
String & operator+=(const String &);
@@ -73,6 +76,4 @@ std::istream & operator>>(std::istream &, String &);
String operator+(const char *, const String &);
-bool compare(String, String);
-
#endif
diff --git a/include/ConfigFile.h b/include/ConfigFile.h
new file mode 100644
index 0000000..8a7c34d
--- /dev/null
+++ b/include/ConfigFile.h
@@ -0,0 +1,27 @@
+#ifndef __CONFIGFILE_H__
+#define __CONFIGFILE_H__
+
+#include <Exceptions.h>
+#include <Handle.h>
+#include <map>
+
+namespace BConfigFile {
+ struct ltstr {
+ bool operator()(String s1, String s2) const {
+ return s1 < s2;
+ }
+ };
+};
+
+typedef std::map<String, String, BConfigFile::ltstr> ConfigSectionContents;
+typedef std::map<String, ConfigSectionContents, BConfigFile::ltstr> ConfigSection;
+
+class ConfigFile : public Base {
+ public:
+ ConfigFile(Handle *) throw (GeneralException);
+ ConfigSectionContents & operator[](String);
+ private:
+ ConfigSection c;
+};
+
+#endif
diff --git a/include/Makefile.am b/include/Makefile.am
index a84dd81..3fc5f29 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -2,6 +2,6 @@ pkginclude_HEADERS = \
Exceptions.h Handle.h BString.h Output.h Socket.h HttpServ.h Variables.h Menu.h \
Action.h Message.h Form.h Confirm.h Table.h IRC.h Task.h Buffer.h generic.h \
CopyJob.h ReadJob.h Regex.h TaskMan.h InPipe.h OutPipe.h Input.h Image.h \
-Main.h Color.h GMPString.h SQL.h
+Main.h Color.h GMPString.h SQL.h ConfigFile.h
noinst_HEADERS = gettext.h
diff --git a/include/SQL.h b/include/SQL.h
index ee28eb0..846afe2 100644
--- a/include/SQL.h
+++ b/include/SQL.h
@@ -1,20 +1,33 @@
#ifndef __SQL_H__
#define __SQL_H__
-#include <set>
+#include <map>
#include <mysql.h>
#include <Exceptions.h>
-//typedef AssocArray std::set<String, compare>;
+namespace BMySQL {
+ struct ltstr {
+ bool operator()(String s1, String s2) const {
+ return s1 < s2;
+ }
+ };
+};
+
+typedef std::map<String, String, BMySQL::ltstr> AssocArray;
class SQLConnection : public Base {
public:
SQLConnection(String host, String user, String passwd, String db, int port = 3306, String socket = "", unsigned long clags = 0) throw (GeneralException);
~SQLConnection();
void query(String) throw (GeneralException);
+ int numrows();
+ int numfields();
+ AssocArray fetchrow();
private:
MYSQL con;
MYSQL_RES * res;
+ int nr, nf;
+ MYSQL_FIELD * fields;
};
#endif
diff --git a/lib/ConfigFile.cc b/lib/ConfigFile.cc
new file mode 100644
index 0000000..85cbb00
--- /dev/null
+++ b/lib/ConfigFile.cc
@@ -0,0 +1,43 @@
+#include "ConfigFile.h"
+#include "Regex.h"
+
+ConfigFile::ConfigFile(Handle * f) throw (GeneralException) {
+ Regex r("^\\[.*\\]$"), comment("^#.*$"), empty("^ *$"), line("^.*=.*$");
+ bool started = false;
+ String s, section, key, value;
+ ConfigSectionContents contents;
+ int pos;
+
+ while (!f->IsClosed()) {
+ (*f) >> s;
+ if (comment.Match(s) || empty.Match(s))
+ continue;
+ if (r.Match(s)) {
+ if (!started) {
+ started = true;
+ } else {
+ c[section] = contents;
+ contents.clear();
+ }
+ section = s.extract(1, s.strlen() - 2);
+ continue;
+ }
+ if (line.Match(s)) {
+ if (!started) {
+ throw GeneralException("Config file must begin with a section");
+ }
+ pos = s.strchr('=');
+ key = s.extract(0, pos - 1).trim();
+ value = s.extract(pos + 1).trim();
+ contents[key] = value;
+ continue;
+ }
+ throw GeneralException("Invalid line: " + s);
+ }
+
+ c[section] = contents;
+}
+
+ConfigSectionContents & ConfigFile::operator[](String s) {
+ return c[s];
+}
diff --git a/lib/Makefile.am b/lib/Makefile.am
index c843753..29edcf1 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -9,4 +9,4 @@ libBaltisot_la_SOURCES = Action.cc Buffer.cc checkargs.c Confirm.cc CopyJob.cc \
datecalc.c Exceptions.cc Form.cc GMPString.cc Handle.cc HttpServ.cc Image.cc \
InPipe.cc Input.cc IRC.cc Main.cc Menu.cc Message.cc OutPipe.cc Output.cc \
ReadJob.cc Regex.cc Socket.cc String.cc Table.cc Task.cc TaskMan.cc \
-Variables.cc generic.cc fileutils.cc SQL.cc
+Variables.cc generic.cc fileutils.cc SQL.cc ConfigFile.cc
diff --git a/lib/SQL.cc b/lib/SQL.cc
index 9091c23..e158904 100644
--- a/lib/SQL.cc
+++ b/lib/SQL.cc
@@ -5,15 +5,17 @@ SQLConnection::SQLConnection(String host, String user, String passwd,
unsigned long cflags) throw (GeneralException) : res(0) {
mysql_init(&con);
- char * p;
-
- if (!mysql_real_connect(&con,
- p = ((ugly_string)(host)).p ? p : 0,
- ((ugly_string)(user)).p,
- ((ugly_string)(passwd)).p,
- ((ugly_string)(db)).p, port,
- ((ugly_string)(socket)).p, cflags)) {
- throw GeneralException(String("Could not connect to MySQL host ") + p);
+ const char * phost = ((ugly_string) host).p;
+ const char * puser = ((ugly_string) user).p;
+ const char * ppasswd = ((ugly_string) passwd).p;
+ const char * pdb = ((ugly_string) db).p;
+ const char * psocket = ((ugly_string) socket).p;
+
+ phost = *phost ? phost : 0;
+ psocket = *psocket ? psocket : 0;
+
+ if (!mysql_real_connect(&con, phost, puser, ppasswd, pdb, port, psocket, cflags)) {
+ throw GeneralException("Could not connect to MySQL host " + host);
}
}
@@ -22,4 +24,45 @@ SQLConnection::~SQLConnection() {
}
void SQLConnection::query(String q) throw(GeneralException) {
+ if (res) {
+ mysql_free_result(res);
+ }
+
+ if (mysql_real_query(&con, ((ugly_string)q).p, q.strlen())) {
+ throw GeneralException(String("Couldn't run query ") + q);
+ }
+
+ res = mysql_store_result(&con);
+
+ if (res) {
+ nr = mysql_num_rows(res);
+ nf = mysql_num_fields(res);
+ fields = mysql_fetch_fields(res);
+ } else {
+ nr = 0;
+ nf = 0;
+ fields = 0;
+ }
+}
+
+int SQLConnection::numrows() {
+ return nr;
+}
+
+int SQLConnection::numfields() {
+ return nf;
+}
+
+AssocArray SQLConnection::fetchrow() {
+ AssocArray r;
+ MYSQL_ROW row;
+ int i;
+
+ row = mysql_fetch_row(res);
+
+ for (i = 0; i < nf; i++) {
+ r[fields[i].name] = row[i];
+ }
+
+ return r;
}
diff --git a/lib/String.cc b/lib/String.cc
index 402424c..f24dcca 100644
--- a/lib/String.cc
+++ b/lib/String.cc
@@ -475,6 +475,30 @@ String & String::tolower() {
return *this;
}
-bool compare(String a, String b) {
- return a < b;
+String String::ltrim() const {
+ char * d = (char *) malloc(strlen() + 1), * p, * r;
+ int s;
+
+ r = d;
+
+ for (p = str; *p && *p == ' '; p++);
+ for (s = 0; *p; *(d++) = *(p++), s++);
+ *d = 0;
+
+ return String(s, r);
+}
+
+String String::rtrim() const {
+ char * d = strdup(), * r;
+ int s = strlen();
+
+ r = d;
+
+ for (d += s - 1; s && (*d == ' '); *(d--) = 0, s--);
+
+ return String(s, r);
+}
+
+String String::trim() const {
+ return rtrim().ltrim();
}