]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/include/openils/oils_buildq.h
f9cfe79d42c23234860b36a2c0b41fe43d1cbedb
[working/Evergreen.git] / Open-ILS / include / openils / oils_buildq.h
1 /**
2         @file buildquery.h
3         @brief Header for routines for building database queries.
4 */
5
6 #ifndef OILS_BUILDQ_H
7 #define OILS_BUILDQ_H
8
9 #include "opensrf/osrf_json.h"
10
11 #ifdef __cplusplus
12 extern "C" {
13 #endif
14
15 struct StoredQ_;
16 typedef struct StoredQ_ StoredQ;
17
18 struct FromRelation_;
19 typedef struct FromRelation_ FromRelation;
20
21 struct SelectItem_;
22 typedef struct SelectItem_ SelectItem;
23
24 struct BindVar_;
25 typedef struct BindVar_ BindVar;
26
27 struct Expression_;
28 typedef struct Expression_ Expression;
29
30 struct QSeq_;
31 typedef struct QSeq_ QSeq;
32
33 struct OrderItem_;
34 typedef struct OrderItem_ OrderItem;
35
36 struct BuildSQLState_;
37 typedef struct BuildSQLState_ BuildSQLState;
38
39 struct IdNode_;
40 typedef struct IdNode_ IdNode;
41
42 /**
43         @brief Stores various things related to the construction of an SQL query.
44         
45         This struct carries around various bits and scraps of context for constructing and
46         executing an SQL query.  It also provides a way for buildSQLQuery() to return more than
47         one kind of thing to its caller.  In particular it can return a status code, a list of
48         error messages, and (if there is no error) an SQL string.
49 */
50 struct BuildSQLState_ {
51         dbi_conn dbhandle;            /**< Handle for the database connection */
52         dbi_result result;            /**< Reference to current row or result set */
53         int error;                    /**< Boolean; true if an error has occurred */
54         osrfStringArray* error_msgs;  /**< Descriptions of errors, if any */
55         growing_buffer* sql;          /**< To hold the constructed query */
56         osrfHash* bindvar_list;       /**< List of bind variables used by this query, each with
57                                            a pointer to the corresponding BindVar. */
58         IdNode* query_stack;          /**< For avoiding infinite recursion of nested queries */
59         IdNode* expr_stack;           /**< For avoiding infinite recursion of nested expressions */
60         IdNode* from_stack;           /**< For avoiding infinite recursion of from clauses */
61         int indent;                   /**< For prettifying SQL output: level of indentation */
62         int defaults_usable;          /**< Boolean; if true, we can use unconfirmed default
63                                            values for bind variables */
64         int values_required;          /**< Boolean: if true, we need values for a bind variables */
65 };
66
67 typedef enum {
68         QT_SELECT,
69         QT_UNION,
70         QT_INTERSECT,
71         QT_EXCEPT
72 } QueryType;
73
74 struct StoredQ_ {
75         StoredQ*      next;
76         int           id;
77         QueryType     type;
78         int           use_all;        /**< Boolean */
79         int           use_distinct;   /**< Boolean */
80         FromRelation* from_clause;
81         Expression*   where_clause;
82         SelectItem*   select_list;
83         QSeq*         child_list;
84         Expression*   having_clause;
85         OrderItem*    order_by_list;
86 };
87
88 typedef enum {
89         FRT_RELATION,
90         FRT_SUBQUERY,
91         FRT_FUNCTION
92 } FromRelationType;
93
94 typedef enum {
95         JT_NONE,
96         JT_INNER,
97         JT_LEFT,
98         JT_RIGHT,
99         JT_FULL
100 } JoinType;
101
102 struct FromRelation_ {
103         FromRelation*    next;
104         int              id;
105         FromRelationType type;
106         char*            table_name;
107         char*            class_name;
108         int              subquery_id;
109         StoredQ*         subquery;
110         int              function_call_id;
111         Expression*      function_call;
112         char*            table_alias;
113         int              parent_relation_id;
114         int              seq_no;
115         JoinType         join_type;
116         Expression*      on_clause;
117         FromRelation*    join_list;
118 };
119
120 struct SelectItem_ {
121         SelectItem* next;
122         int         id;
123         int         stored_query_id;
124         int         seq_no;
125         Expression* expression;
126         char*       column_alias;
127         int         grouped_by;        // Boolean
128 };
129
130 typedef enum {
131         BIND_STR,
132         BIND_NUM,
133         BIND_STR_LIST,
134         BIND_NUM_LIST
135 } BindVarType;
136
137 struct BindVar_ {
138         BindVar*    next;
139         char*       name;
140         char*       label;
141         BindVarType type;
142         char*       description;
143         jsonObject* default_value;
144         jsonObject* actual_value;
145 };
146
147 typedef enum {
148         EXP_BETWEEN,
149         EXP_BIND,
150         EXP_BOOL,
151         EXP_CASE,
152         EXP_CAST,
153         EXP_COLUMN,
154         EXP_EXIST,
155         EXP_FIELD,
156         EXP_FUNCTION,
157         EXP_IN,
158         EXP_ISNULL,
159         EXP_NULL,
160         EXP_NUMBER,
161         EXP_OPERATOR,
162     EXP_SERIES,
163         EXP_STRING,
164         EXP_SUBQUERY
165 } ExprType;
166
167 struct Expression_ {
168         Expression* next;
169         int         id;
170         ExprType    type;
171         int         parenthesize;       // Boolean
172         int         parent_expr_id;
173         int         seq_no;
174         char*       literal;
175         char*       table_alias;
176         char*       column_name;
177         Expression* left_operand;
178         char*       op;
179         Expression* right_operand;
180         int         subquery_id;
181         StoredQ*    subquery;
182         int         cast_type_id;
183         int         negate;             // Boolean
184         BindVar*    bind;
185         Expression* subexp_list;        // Linked list of subexpressions
186         // The next column comes, not from query.expression,
187         // but from query.function_sig:
188         char*       function_name;
189 };
190
191 struct QSeq_ {
192         QSeq*    next;
193         int      id;
194         int      parent_query_id;
195         int      seq_no;
196         StoredQ* child_query;
197 };
198
199 struct OrderItem_ {
200         OrderItem* next;
201         int        id;
202         int        stored_query_id;
203         int        seq_no;
204         Expression* expression;
205 };
206
207 BuildSQLState* buildSQLStateNew( dbi_conn dbhandle );
208
209 void buildSQLStateFree( BuildSQLState* state );
210
211 void buildSQLCleanup( void );
212
213 const char* sqlAddMsg( BuildSQLState* state, const char* msg, ... );
214
215 StoredQ* getStoredQuery( BuildSQLState* state, int query_id );
216
217 jsonObject* oilsGetColNames( BuildSQLState* state, StoredQ* query );
218
219 void pop_id( IdNode** stack );
220
221 void storedQFree( StoredQ* sq );
222
223 void storedQCleanup( void );
224
225 int buildSQL( BuildSQLState* state, const StoredQ* query );
226
227 void oilsStoredQSetVerbose( void );
228
229 jsonObject* oilsFirstRow( BuildSQLState* state );
230
231 jsonObject* oilsNextRow( BuildSQLState* state );
232
233 jsonObject* oilsBindVarList( osrfHash* bindvar_list );
234
235 int oilsApplyBindValues( BuildSQLState* state, const jsonObject* bindings );
236
237 #ifdef __cplusplus
238 }
239 #endif
240
241 #endif