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