1. Support negation of an expression (except in a few cases where it
[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 Expression_;
25 typedef struct Expression_ Expression;
26
27 struct QSeq_;
28 typedef struct QSeq_ QSeq;
29
30 struct OrderItem_;
31 typedef struct OrderItem_ OrderItem;
32
33 struct BuildSQLState_;
34 typedef struct BuildSQLState_ BuildSQLState;
35
36 struct IdNode_;
37 typedef struct IdNode_ IdNode;
38
39 /**
40         @brief Stores various things related to the construction of an SQL query.
41         
42         This struct carries around various bits and scraps of context for constructing and
43         executing an SQL query.  It also provides a way for buildSQLQuery() to return more than
44         one kind of thing to its caller.  In particular it can return a status code, a list of
45         error messages, and (if there is no error) an SQL string.
46 */
47 struct BuildSQLState_ {
48         dbi_conn dbhandle;            /**< Handle for the database connection */
49         dbi_result result;            /**< Reference to current row or result set */
50         int error;                    /**< Boolean; true if an error has occurred */
51         osrfStringArray* error_msgs;  /**< Descriptions of errors, if any */
52         growing_buffer* sql;          /**< To hold the constructed query */
53         IdNode* query_stack;          /**< For avoiding infinite recursion of nested queries */
54         IdNode* expr_stack;           /**< For avoiding infinite recursion of nested expressions */
55         IdNode* from_stack;           /**< For avoiding infinite recursion of from clauses */
56         int indent;                   /**< For prettifying SQL output: level of indentation */
57 };
58
59 typedef enum {
60         QT_SELECT,
61         QT_UNION,
62         QT_INTERSECT,
63         QT_EXCEPT
64 } QueryType;
65
66 struct StoredQ_ {
67         StoredQ*      next;
68         int           id;
69         QueryType     type;
70         int           use_all;        /**< Boolean */
71         int           use_distinct;   /**< Boolean */
72         FromRelation* from_clause;
73         Expression*   where_clause;
74         SelectItem*   select_list;
75         QSeq*         child_list;
76         Expression*   having_clause;
77         OrderItem*    order_by_list;
78 };
79
80 typedef enum {
81         FRT_RELATION,
82         FRT_SUBQUERY,
83         FRT_FUNCTION
84 } FromRelationType;
85
86 typedef enum {
87         JT_NONE,
88         JT_INNER,
89         JT_LEFT,
90         JT_RIGHT,
91         JT_FULL
92 } JoinType;
93
94 struct FromRelation_ {
95         FromRelation*    next;
96         int              id;
97         FromRelationType type;
98         char*            table_name;
99         char*            class_name;
100         int              subquery_id;
101         StoredQ*         subquery;
102         int              function_call_id;
103         char*            table_alias;
104         int              parent_relation_id;
105         int              seq_no;
106         JoinType         join_type;
107         Expression*      on_clause;
108         FromRelation*    join_list;
109 };
110
111 struct SelectItem_ {
112         SelectItem* next;
113         int         id;
114         int         stored_query_id;
115         int         seq_no;
116         Expression* expression;
117         char*       column_alias;
118         int         grouped_by;        // Boolean
119 };
120
121 typedef enum {
122         EXP_BETWEEN,
123         EXP_BOOL,
124         EXP_CASE,
125         EXP_CAST,
126         EXP_COLUMN,
127         EXP_EXIST,
128         EXP_FIELD,
129         EXP_FUNCTION,
130         EXP_IN,
131         EXP_NULL,
132         EXP_NUMBER,
133         EXP_OPERATOR,
134         EXP_STRING,
135         EXP_SUBQUERY
136 } ExprType;
137
138 struct Expression_ {
139         Expression* next;
140         int         id;
141         ExprType    type;
142         int         parenthesize;       // Boolean
143         int         parent_expr_id;
144         int         seq_no;
145         char*       literal;
146         char*       table_alias;
147         char*       column_name;
148         Expression* left_operand;
149         char*       op;
150         Expression* right_operand;
151         int         function_id;
152         int         subquery_id;
153         StoredQ*    subquery;
154         int         cast_type_id;
155         int         negate;             // Boolean
156 };
157
158 struct QSeq_ {
159         QSeq*    next;
160         int      id;
161         int      parent_query_id;
162         int      seq_no;
163         StoredQ* child_query;
164 };
165
166 struct OrderItem_ {
167         OrderItem* next;
168         int        id;
169         int        stored_query_id;
170         int        seq_no;
171         Expression* expression;
172 };
173
174 BuildSQLState* buildSQLStateNew( dbi_conn dbhandle );
175
176 void buildSQLStateFree( BuildSQLState* state );
177
178 void buildSQLCleanup( void );
179
180 const char* sqlAddMsg( BuildSQLState* state, const char* msg, ... );
181
182 StoredQ* getStoredQuery( BuildSQLState* state, int query_id );
183
184 jsonObject* oilsGetColNames( BuildSQLState* state, StoredQ* query );
185
186 void pop_id( IdNode** stack );
187
188 void storedQFree( StoredQ* sq );
189
190 void storedQCleanup( void );
191
192 int buildSQL( BuildSQLState* state, StoredQ* query );
193
194 void oilsStoredQSetVerbose( void );
195
196 jsonObject* oilsFirstRow( BuildSQLState* state );
197
198 jsonObject* oilsNextRow( BuildSQLState* state );
199
200 #ifdef __cplusplus
201 }
202 #endif
203
204 #endif