1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
|
/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd: (C) 2002-2010 InspIRCd Development Team
* See: http://wiki.inspircd.org/Credits
*
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef INSPIRCD_SQLAPI_3
#define INSPIRCD_SQLAPI_3
/** Defines the error types which SQLerror may be set to
*/
enum SQLerrorNum { SQL_NO_ERROR, SQL_BAD_DBID, SQL_BAD_CONN, SQL_QSEND_FAIL, SQL_QREPLY_FAIL };
/** A list of format parameters for an SQLquery object.
*/
typedef std::vector<std::string> ParamL;
typedef std::map<std::string, std::string> ParamM;
class SQLEntry
{
public:
std::string value;
bool nul;
SQLEntry() : nul(true) {}
SQLEntry(const std::string& v) : value(v), nul(false) {}
inline operator std::string&() { return value; }
};
typedef std::vector<SQLEntry> SQLEntries;
/**
* Result of an SQL query. Only valid inside OnResult
*/
class SQLResult : public classbase
{
public:
/**
* Return the number of rows in the result.
*
* Note that if you have perfomed an INSERT or UPDATE query or other
* query which will not return rows, this will return the number of
* affected rows. In this case you SHOULD NEVER access any of the result
* set rows, as there aren't any!
* @returns Number of rows in the result set.
*/
virtual int Rows() = 0;
/**
* Return a single row (result of the query). The internal row counter
* is incremented by one.
*
* @param result Storage for the result data.
* @returns true if there was a row, false if no row exists (end of
* iteration)
*/
virtual bool GetRow(SQLEntries& result) = 0;
/** Returns column names for the items in this row
*/
virtual void GetCols(std::vector<std::string>& result) = 0;
};
/** SQLerror holds the error state of a request.
* The error string varies from database software to database software
* and should be used to display informational error messages to users.
*/
class SQLerror
{
public:
/** The error id
*/
SQLerrorNum id;
/** The error string
*/
std::string str;
/** Initialize an SQLerror
* @param i The error ID to set
* @param s The (optional) error string to set
*/
SQLerror(SQLerrorNum i, const std::string &s = "")
: id(i), str(s)
{
}
/** Return the error string for an error
*/
const char* Str()
{
if(str.length())
return str.c_str();
switch(id)
{
case SQL_BAD_DBID:
return "Invalid database ID";
case SQL_BAD_CONN:
return "Invalid connection";
case SQL_QSEND_FAIL:
return "Sending query failed";
case SQL_QREPLY_FAIL:
return "Getting query result failed";
default:
return "Unknown error";
}
}
};
/**
* Object representing an SQL query. This should be allocated on the heap and
* passed to an SQLProvider, which will free it when the query is complete or
* when the querying module is unloaded.
*
* You should store whatever information is needed to have the callbacks work in
* this object (UID of user, channel name, etc).
*/
class SQLQuery : public classbase
{
public:
ModuleRef creator;
const std::string query;
SQLQuery(Module* Creator, const std::string& q)
: creator(Creator), query(q) {}
virtual ~SQLQuery() {}
virtual void OnResult(SQLResult& result) = 0;
/**
* Called when the query fails
*/
virtual void OnError(SQLerror& error) { }
};
/**
* Provider object for SQL servers
*/
class SQLProvider : public DataProvider
{
public:
SQLProvider(Module* Creator, const std::string& Name) : DataProvider(Creator, Name) {}
/** Submit an asynchronous SQL request
* @param dbid The database ID to apply the request to
* @param query The query string
* @param callback The callback that the result is sent to
*/
virtual void submit(SQLQuery* query) = 0;
/** Format a parameterized query string using proper SQL escaping.
* @param q The query string, with '?' parameters
* @param p The parameters to fill in in the '?' slots
*/
virtual std::string FormatQuery(const std::string& q, const ParamL& p) = 0;
/** Format a parameterized query string using proper SQL escaping.
* @param q The query string, with '$foo' parameters
* @param p The map to look up parameters in
*/
virtual std::string FormatQuery(const std::string& q, const ParamM& p) = 0;
/** Convenience function */
void PopulateUserInfo(User* user, ParamM& userinfo)
{
userinfo["nick"] = user->nick;
userinfo["host"] = user->host;
userinfo["ip"] = user->GetIPString();
userinfo["gecos"] = user->fullname;
userinfo["ident"] = user->ident;
userinfo["server"] = user->server;
userinfo["uuid"] = user->uuid;
}
};
#endif
|