}
</pre>
+
+<h3>The SQL module</h3>
+<h4>Structure definitions</h4>
+
+<p>The map module uses the following structure to hold its data:</p>
+<pre class="prettyprint">
+static struct {
+ data_control_provider_sql_cb sql_callback; /* Provider callbacks */
+ sqlite3 *db; /* The map structure */
+} s_info;
+</pre>
+
+<h4>Initialization</h4>
+<p>The SQL module uses a SQLite database to hold data. As opposed to the map module, the SQL module uses an external file to store the data so it is not lost when the app is killed. Four callback are used to provide communication with the consumer application.</p>
+
+<p>The function below is used to initialize the SQL provider module.</p>
+<pre class="prettyprint">
+void sql_provider_init(void)
+{
+ int result = __create_database(); /* Create and open a database file */
+
+ /* Initialize the callback structure with function pointers */
+ s_info.sql_callback.select_cb = __select_request_cb;
+ s_info.sql_callback.insert_cb = __insert_request_cb;
+ s_info.sql_callback.delete_cb = __delete_request_cb;
+ s_info.sql_callback.update_cb = __update_request_cb;
+
+ /* Register the callbacks */
+ result = data_control_provider_sql_register_cb(&s_info.sql_callback, NULL);
+ /* ... */
+}
+</pre>
+
+<h4>Callbacks</h4>
+
+<p>The callback invoked when an 'insert' request is sent:</p>
+<pre class="prettyprint">
+static void __insert_request_cb(int request_id, data_control_h provider, bundle *insert_data, void *user_data)
+{
+ /* The insert_data argument contains a list of column name / value pairs. Check the <a href = "data_control_consumer_sd_mn.htm#consumer-sql-insert-request">consumer</a> app documentation for details.
+ Based on the values stored in the bundle a SQL INSERT query is created. */
+ command = data_control_provider_create_insert_statement(provider, insert_data);
+ /* ... */
+
+ /* The new row is added to the database using standard SQLite API's functions */
+ ret = sqlite3_exec(s_info.db, command, NULL, NULL, NULL);
+ /* ... */
+ inserted_row_id = sqlite3_last_insert_rowid(s_info.db);
+
+ /* The operation result is sent back to the consumer application */
+ ret = data_control_provider_send_insert_result(request_id, inserted_row_id);
+
+ /* ... */
+}
+</pre>
+
+<p>The callback invoked when a 'delete' request is sent:</p>
+<pre class="prettyprint">
+static void __delete_request_cb(int request_id, data_control_h provider, const char *where, void *user_data)
+{
+ /* ... */
+
+ /* The 'where' text is used to create a SQL DELETE query */
+ command = data_control_provider_create_delete_statement(provider, where);
+ /* ... */
+
+ /* The new row is added to the database using standard SQLite API's functions */
+ ret = sqlite3_exec(s_info.db, command, NULL, NULL, NULL);
+ /* ... */
+
+ /* The operation result is sent back to the consumer application */
+ ret = data_control_provider_send_delete_result(request_id);
+ /* ... */
+}
+</pre>
+
+<p>The callback invoked when a 'select' request is sent:</p>
+<pre class="prettyprint">
+static void __select_request_cb(int request_id, data_control_h provider, const char **column_list,
+ int column_count, const char *where, const char *order, void *user_data)
+{
+ /* ... */
+
+ /* A SQL SELECT query is created using the callback arguments. Note that some of the arguments can be NULL.
+ The resulting query:
+ SELECT column_list[0], column_list[1] .. column_list[column_count - 1] FROM Sample_Table WHERE where ORDER BY order;
+
+ If the where string is NULL, there is no filter used and if order string is NULL there is no sorting applied.
+ */
+ command = data_control_provider_create_select_statement(provider, column_list, column_count, where, order);
+ if (!command) {
+ dlog_print(DLOG_ERROR, LOG_TAG, "command == NULL");
+ return;
+ } else {
+ dlog_print(DLOG_ERROR, LOG_TAG, "command == %s", command);
+ }
+
+ /* A SQL statement object is created and sent to the consumer application */
+ ret = sqlite3_prepare_v2(s_info.db, command, strlen(command), &sql_stmt, NULL);
+ /* ... */
+
+ ret = data_control_provider_send_select_result(request_id, (void *)sql_stmt);
+ /* ... */
+
+ sqlite3_finalize(sql_stmt);
+
+ /* ... */
+}
+</pre>
+
+<p>The callback invoked when an 'update' request is sent:</p>
+<pre class="prettyprint">
+static void __update_request_cb(int request_id, data_control_h provider, bundle *update_data, const char *where, void *user_data)
+{
+ int ret = -1;
+ char *command = NULL;
+
+
+ /* The SQL query is created using the bundle structure similar to the structure used in add query and where string similar to the one used in the delete query.
+ The final query will look like this:
+ UPDATE Sample_Table SET bundle_key1 = bundle_value_1, bundle_key1 = bundle_value_1, ..., columnN = valueN WHERE where
+
+ */
+ command = data_control_provider_create_update_statement(provider, update_data, where);
+ if (!command) {
+ dlog_print(DLOG_ERROR, LOG_TAG, "command == NULL");
+ return;
+ }
+
+ /* The generated command is then used as a SQLite query */
+ ret = sqlite3_exec(s_info.db, command, NULL, NULL, NULL);
+ /* ... */
+
+ /* After the database update information about the update's result is sent to the consumer app*/
+ ret = data_control_provider_send_update_result(request_id);
+ /* ... */
+}
+</pre>
<!-- ********************************************************************************** -->
<script type="text/javascript" src="../scripts/jquery.zclip.min.js"></script>