1 /*
2  * Copyright (C) 2007 - 2011 Vivien Malerba <malerba@gnome-db.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA  02110-1301, USA.
18  */
19 
20 #ifndef __GDA_VCONNECTION_DATA_MODEL_H__
21 #define __GDA_VCONNECTION_DATA_MODEL_H__
22 
23 #include <virtual/gda-virtual-connection.h>
24 #include <sql-parser/gda-statement-struct-parts.h>
25 
26 #define GDA_TYPE_VCONNECTION_DATA_MODEL            (gda_vconnection_data_model_get_type())
27 #define GDA_VCONNECTION_DATA_MODEL(obj)            (G_TYPE_CHECK_INSTANCE_CAST (obj, GDA_TYPE_VCONNECTION_DATA_MODEL, GdaVconnectionDataModel))
28 #define GDA_VCONNECTION_DATA_MODEL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST (klass, GDA_TYPE_VCONNECTION_DATA_MODEL, GdaVconnectionDataModelClass))
29 #define GDA_IS_VCONNECTION_DATA_MODEL(obj)         (G_TYPE_CHECK_INSTANCE_TYPE (obj, GDA_TYPE_VCONNECTION_DATA_MODEL))
30 #define GDA_IS_VCONNECTION_DATA_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDA_TYPE_VCONNECTION_DATA_MODEL))
31 
32 G_BEGIN_DECLS
33 
34 typedef struct _GdaVconnectionDataModel      GdaVconnectionDataModel;
35 typedef struct _GdaVconnectionDataModelClass GdaVconnectionDataModelClass;
36 typedef struct _GdaVconnectionDataModelPrivate GdaVconnectionDataModelPrivate;
37 typedef struct _GdaVconnectionDataModelSpec  GdaVconnectionDataModelSpec;
38 typedef struct _GdaVconnectionDataModelFilter GdaVconnectionDataModelFilter;
39 
40 /**
41  * GdaVconnectionDataModelCreateColumnsFunc:
42  * @Param1: a pointer to a #GdaVconnectionDataModelSpec structure
43  * @Param2: a place to store errors, or %NULL
44  * @Returns: (element-type GdaColumn) (transfer full): a new list of #GdaColumn objects
45  *
46  * Function called to create the virtual table's columns, as #GdaColumn objects.
47  */
48 typedef GList *(*GdaVconnectionDataModelCreateColumnsFunc) (GdaVconnectionDataModelSpec *, GError **);
49 
50 /**
51  * GdaVconnectionDataModelCreateModelFunc:
52  * @Param1: a pointer to a #GdaVconnectionDataModelSpec structure
53  * @Returns: (transfer full): a new #GdaDataModel
54  *
55  * Function called to create a #GdaDataModel object, called when a virtual table's data need to
56  * be accessed, and when optimization is not handled.
57  */
58 typedef GdaDataModel *(*GdaVconnectionDataModelCreateModelFunc) (GdaVconnectionDataModelSpec *);
59 
60 /**
61  * GdaVconnectionDataModelFunc:
62  * @Param1: (allow-none): a pointer to a #GdaDataModel
63  * @Param2: the name of the table represented by @Param1
64  * @Param3: a data pointer, passed as last ergument to gda_vconnection_data_model_foreach()
65  *
66  * This function is called for every #GdaDataModel representing a table in a #GdaVconnectionDataModel
67  * connection, when using the gda_vconnection_data_model_foreach() method.
68  */
69 typedef void (*GdaVconnectionDataModelFunc) (GdaDataModel *, const gchar *, gpointer );
70 
71 /**
72  * GdaVconnectionDataModelFilter:
73  *
74  * This structure contains data which should be analysed to produce a data model (used as data
75  * for a virtual table) when a #GdaVconnectionDataModelCreateFModelFunc is called. The structure
76  * contains an input part (which should not be modified) and and output part (it is
77  * closely mapped with SQLite's sqlite3_index_info type).
78  *
79  * A pointer to this structure is passed to the #GdaVconnectionDataModelParseFilterFunc function
80  * and the function has to modify the variables in the output part (marked as *Outputs*).
81  *
82  * The @idxNum and @idxPointer are passed to the #GdaVconnectionDataModelCreateFModelFunc function call
83  * and they represent nothing specific except that the GdaVconnectionDataModelParseFilterFunc and
84  * GdaVconnectionDataModelCreateFModelFunc functions need to agree on their meaning.
85  *
86  * See the gda-vconnection-hub.c file for an usage example.
87  */
88 struct _GdaVconnectionDataModelFilter {
89 	/* Inputs */
90 	int nConstraint; /* Number of entries in aConstraint */
91 	struct GdaVirtualConstraint {
92 		int iColumn;       /* Column on left-hand side of constraint */
93 		GdaSqlOperatorType op;  /* Constraint operator, among _EQ, _LT, _LEQ, _GT, _GEQ, _REGEXP */
94 	} *aConstraint;            /* Table of WHERE clause constraints */
95 	int nOrderBy;              /* Number of terms in the ORDER BY clause */
96 	struct GdaVirtualOrderby {
97 		int iColumn;       /* Column number */
98 		gboolean desc;     /* TRUE for DESC.  FALSE for ASC. */
99 	} *aOrderBy;               /* The ORDER BY clause */
100 
101 	/* Outputs */
102 	struct GdaVirtualConstraintUsage {
103 		int argvIndex;     /* if >0, constraint is part of argv to xFilter */
104 		gboolean omit;     /* Do not code a test for this constraint if TRUE */
105 	} *aConstraintUsage;
106 	int idxNum;                /* Number used to identify the index */
107 	gpointer idxPointer;       /* Pointer used to identify the index */
108 	gboolean orderByConsumed;  /* TRUE if output is already ordered */
109 	double estimatedCost;      /* Estimated cost of using this index */
110 };
111 
112 /**
113  * GdaVconnectionDataModelParseFilterFunc:
114  * @Param1: a pointer to a #GdaVconnectionDataModelSpec structure
115  * @Param2: a pointer to a #GdaVconnectionDataModelFilter structure
116  *
117  * This function actually analyses the proposed optimization and modified @Param2 to tell the database
118  * engine how (if applicable) it implements the optimization.
119  */
120 typedef void (*GdaVconnectionDataModelParseFilterFunc) (GdaVconnectionDataModelSpec *, GdaVconnectionDataModelFilter *);
121 
122 /**
123  * GdaVconnectionDataModelCreateFModelFunc:
124  * @Param1: a pointer to a #GdaVconnectionDataModelSpec structure
125  * @Param2: the index number chosen to actually execute the optimization (from #GdaVconnectionDataModelFilter's #idxNum attribute)
126  * @Param3: corresponds to the #GdaVconnectionDataModelFilter's #idxPointer attribute
127  * @Param4: size of @Param5
128  * @Param5: an array of #GValue, as specified by the #GdaVconnectionDataModelFilter's #aConstraintUsage's #argvIndex value
129  * @Returns: (transfer full): a new #GdaDataModel
130  *
131  * Function called to create a #GdaDataModel object, called when a virtual table's data need to
132  * be accessed, and when optimization is handled.
133  */
134 typedef GdaDataModel *(*GdaVconnectionDataModelCreateFModelFunc) (GdaVconnectionDataModelSpec *, int, const char *, int, GValue **);
135 
136 /**
137  * GdaVconnectionDataModelSpec:
138  * @data_model: (allow-none): a #GdaDataModel, or %NULL
139  * @create_columns_func: (allow-none): a pointer to a #GdaVconnectionDataModelCreateColumnsFunc function, or %NULL
140  * @create_model_func: (allow-none): a pointer to a #GdaVconnectionDataModelCreateModelFunc function, or %NULL
141  * @create_filter_func: (allow-none): a pointer to a #GdaVconnectionDataModelParseFilterFunc function, or %NULL
142  * @create_filtered_model_func: (allow-none): a pointer to a #GdaVconnectionDataModelCreateFModelFunc function, or %NULL
143  *
144  * This structure holds all the information supplied to declare a virtual table using
145  * gda_vconnection_data_model_add(). You don't need to provider pointers for all the functions and
146  * for @data_model, but the following rules have to be respected:
147  * <itemizedlist>
148  *  <listitem><para>@data_model is not %NULL and all the function pointers are %NULL: this is the situation
149  *   when the virtual table's contents is defined once by @data_model</para></listitem>
150  *  <listitem><para>@data_model is %NULL and @create_columns_func is not %NULL:
151  *     <itemizedlist>
152  *        <listitem><para>@create_filtered_model_func is not %NULL: this is the situation where the
153  *                        virtual table's associated data model handles filter optimizations.
154  *                        @create_model_func is ignored in this case.
155  *        </para></listitem>
156  *        <listitem><para>@create_model_func is not %NULL: this is the situation where the
157  *                        virtual table's associated data model does not handle filter optimizations
158  *        </para></listitem>
159  *     </itemizedlist>
160  *  </para></listitem>
161  * </itemizedlist>
162  *
163  * Note that if specifying a @create_filtered_model_func, you should also specifiy a @create_filter_func
164  * function which is actually responsible for analysing the optimization.
165  */
166 struct _GdaVconnectionDataModelSpec {
167 	GdaDataModel                             *data_model;
168 	GdaVconnectionDataModelCreateColumnsFunc  create_columns_func;
169 	GdaVconnectionDataModelCreateModelFunc    create_model_func;
170 
171 	GdaVconnectionDataModelParseFilterFunc    create_filter_func;
172 	GdaVconnectionDataModelCreateFModelFunc   create_filtered_model_func;
173 };
174 #define GDA_VCONNECTION_DATA_MODEL_SPEC(x) ((GdaVconnectionDataModelSpec*)(x))
175 
176 struct _GdaVconnectionDataModel {
177 	GdaVirtualConnection            connection;
178 	GdaVconnectionDataModelPrivate *priv;
179 };
180 
181 struct _GdaVconnectionDataModelClass {
182 	GdaVirtualConnectionClass       parent_class;
183 
184 	void                          (*vtable_created) (GdaVconnectionDataModel *cnc,
185 							  const gchar *table_name);
186 	void                          (*vtable_dropped) (GdaVconnectionDataModel *cnc,
187 							    const gchar *table_name);
188 
189 	/*< private >*/
190 	/* Padding for future expansion */
191 	void (*_gda_reserved1) (void);
192 	void (*_gda_reserved2) (void);
193 };
194 
195 /**
196  * SECTION:gda-vconnection-data-model
197  * @short_description: Virtual connection based on a list of GdaDataModel
198  * @title: GdaVconnectionDataModel
199  * @stability: Stable
200  * @see_also: The #GdaVproviderDataModel provider to use to create such connection objects.
201  *
202  * The #GdaVconnectionDataModel is a virtual connection in which #GdaDataModel data models can be added
203  * or removed, each representing a table in the connection, the gda_vconnection_data_model_add_model()
204  * and gda_vconnection_data_model_remove() methods.
205  *
206  * Furthermore it is possible to declare tables without any associated data model yet,
207  * the real data model being automatically created when the
208  * table's data is needed. This allows more dynamic table's contents and filtering optimizations.
209  * See the gda_vconnection_data_model_add() and gda_vconnection_data_model_remove() methods. The
210  * filtering optimizations are based on SQLite's virtual table optimisations see
211  * <ulink url="http://www.sqlite.org/cvstrac/wiki?p=VirtualTableBestIndexMethod">SQLite's documentation</ulink>
212  * for some background information.
213  */
214 
215 GType               gda_vconnection_data_model_get_type  (void) G_GNUC_CONST;
216 
217 gboolean            gda_vconnection_data_model_add       (GdaVconnectionDataModel *cnc, GdaVconnectionDataModelSpec *spec,
218 							  GDestroyNotify spec_free_func,
219 							  const gchar *table_name, GError **error);
220 gboolean            gda_vconnection_data_model_add_model (GdaVconnectionDataModel *cnc,
221 							  GdaDataModel *model, const gchar *table_name, GError **error);
222 gboolean            gda_vconnection_data_model_remove    (GdaVconnectionDataModel *cnc, const gchar *table_name, GError **error);
223 
224 GdaVconnectionDataModelSpec *gda_vconnection_data_model_get (GdaVconnectionDataModel *cnc, const gchar *table_name);
225 const gchar        *gda_vconnection_data_model_get_table_name (GdaVconnectionDataModel *cnc, GdaDataModel *model);
226 GdaDataModel       *gda_vconnection_data_model_get_model (GdaVconnectionDataModel *cnc, const gchar *table_name);
227 
228 void                gda_vconnection_data_model_foreach   (GdaVconnectionDataModel *cnc,
229 							  GdaVconnectionDataModelFunc func, gpointer data);
230 
231 G_END_DECLS
232 
233 #endif
234