#ifndef __MADCONF_H__
#define __MADCONF_H__
#include <qstring.h>
#include <qcstring.h>
#include "MadSQLite.h"
/*
tables:
Key:
id, pid, typeid, name, dataid
data:
id, data
data possibilities:
id, typeid, data
type ids: val, val list, mult choice|single val, mult choice|mult val
*/
extern const char sql_create_key_table[];
extern const char sql_create_data_table[];
extern const char sql_create_data_opt_table[];
enum {
MCKT_VALUE = 1,
MCKT_VALUE_LIST,
MCKT_MCAV, // mult choice, any value (like for an editable combo box, like a union of a VALUE_LIST and MCMV :))
MCKT_MCSV, // mult choice, single value
MCKT_MCMV, // mult choice, mult value
};
class MadConf;
// Got an idea from The_Vulture on #C++@freenode
// methods returning an object byvalue, change to return error, and take object by reference.
class MadConfKeyValue {
friend class MadConfKey;
public:
MadConfKeyValue() : conf(0), id(0) { }
MadConfKeyValue(MadConf *cnf, int i, const char *c) : conf(cnf), id(i), value(c) { }
int getInt() { return value.toInt(); }
bool getBool() { return (bool)value.toInt(); }
const char *getText() { return (const char *)value; }
double getDouble() { return value.toDouble(); }
bool set(int);
bool set(bool);
bool set(const char *);
bool set(double);
void erase();
operator bool() { return valid(); }
bool operator!() { return !valid(); }
bool valid() { return (bool)((conf != 0) ? true : false); }
private:
MadConf *conf;
int id;
QString value;
};
class MadConfKeyOpt {
friend class MadConfKey;
public:
MadConfKeyOpt() : conf(0), id(0) { }
MadConfKeyOpt(MadConf *cnf, int i, const char *c) : conf(cnf), id(i), value(c) { }
int getInt() { return value.toInt(); }
bool getBool() { return (bool)value.toInt(); }
const char *getText() { return (const char *)value; }
double getDouble() { return value.toDouble(); }
bool set(int);
bool set(bool);
bool set(const char *);
bool set(double);
void erase();
operator bool() { return valid(); }
bool operator!() { return !valid(); }
bool valid() { return (bool)((conf != 0) ? true : false); }
private:
MadConf *conf;
int id;
QString value;
};
class MadConfKey {
friend class MadConf;
public:
MadConfKey() : key(0), id(-1), type(0), conf(0), value_result(0), child_result(0), opt_result(0) { }
MadConfKey(MadConf *, int, int, const char *);
~MadConfKey();
operator bool() { return valid(); }
bool operator!() { return !valid(); }
MadConfKey(const MadConfKey& ck)
{
id = ck.id;
key = ck.key;
type = ck.type;
conf = ck.conf;
value_result = child_result = opt_result = 0;
printf("Key copy constructor: %s(%i)\n", (const char *)key, id);
}
MadConfKey &operator=(const MadConfKey &ck)
{
id = ck.id;
key = ck.key;
type = ck.type;
conf = ck.conf;
if(value_result)
delete value_result;
if(child_result)
delete child_result;
if(opt_result)
delete opt_result;
value_result = child_result = opt_result = 0;
printf("Key copy assign: %s(%i)\n", (const char *)key, id);
return *this;
}
bool valid() { return (bool)((conf != 0) ? true : false); }
int getId() { return id; }
QString name();
bool setName(const char *);
int getType() { return type; }
bool setType(int t);
int getValueCount() { return ValueCount; }
// maybe do something funky here with references?
bool beginValue();
bool value(MadConfKeyValue &);
bool step(MadConfKeyValue &);
bool addValue(MadConfKeyValue &, const char *);
bool beginOpt();
bool step(MadConfKeyOpt &);
bool addOpt(MadConfKeyOpt &, const char *);
// Funky, calling setValue() will invalidate any MadConfKeyValues that are allocated...
int getChildCount() { return ChildCount; }
bool child(MadConfKey &, const char *); // obviously messes up the first/next stuff
bool beginChild();
bool step(MadConfKey &);
bool newChild(MadConfKey &, const char *keyname, int type = MCKT_VALUE);
// MadConfKey *getParent();
bool erase();
inline bool setAutoCommit(bool ac) { AutoCommitSet = true; bool old = AutoCommit; AutoCommit = ac; return old; }
inline bool isAutoCommitEnabled() { return (AutoCommitSet && AutoCommit) || (!AutoCommitSet && AUTO_COMMIT); }
static bool AUTO_COMMIT;
bool isType(int t) { return t == type; }
void fin() {
if(value_result)
delete value_result;
if(child_result)
delete child_result;
if(opt_result)
delete opt_result;
value_result = child_result = opt_result = 0;
}
private:
int ChildCount;
int ValueCount;
bool AutoCommitSet, AutoCommit;
QString key;
int id;
int type;
MadConf *conf;
MadSQLiteResult *value_result, *child_result, *opt_result;
bool insert_key();
bool delete_key(int kid);
};
class MadConf {
friend class MadConfKey;
friend class MadConfKeyValue;
friend class MadConfKeyOpt;
public:
MadConf(const char *);
~MadConf();
bool beginKey();
bool step(MadConfKey &);
bool key(MadConfKey &, const char *key);
bool key(MadConfKey &, int id);
bool newKey(MadConfKey &, const char *key, int type = MCKT_VALUE);
MadSQLite *getDB() { return db; }
private:
MadSQLite *db;
MadSQLiteResult *result;
bool initDB();
};
#if 0
MadConfKey *key = conf->newKey("foo"); // default type is single choice, single value
key->setVaue("foo");
MadConfKey *child = key->addChild("lala", MCKT_MCSV); // Multiple Choice, Single Value
child->addChoice("foo");
child->addChoice("bar");
child->addChoice("baz");
child->addChoice("frob");
child->setValue("foob"); // fails
MadConfKey *child2 = key->addChild("meep", MCKT_MCMV); // Multiple Choice, Multiple Value
child->addChoice("foo");
child->addChoice("bar");
child->addChoice("baz");
child->addChoice("frob");
child->setValue("foo"); // clears all values, and sets this,
child->addValue("bar"); // adds bar, so now child2 == foo, bar
for(val = child->firstValue(); val; val = child->nextValue()) {
printf("value: %s\n", val->getText());
}
for(ckey = key->fisrtChild(); ckey; ckey = key->nextChild()) {
printf("child: %s\n", ckey->name());
}
#endif
#endif /* __MADCONF_H__ */