Get column name & consumer cannot receive select error callback bug fix 97/56997/9 accepted/tizen/ivi/20160218.023319 accepted/tizen/mobile/20160115.113825 accepted/tizen/tv/20160115.113847 accepted/tizen/wearable/20160115.113857 submit/tizen/20160115.082829 submit/tizen_common/20160218.142243 submit/tizen_ivi/20160217.000000 submit/tizen_ivi/20160217.000002
authorHyunho Kang <hhstark.kang@samsung.com>
Thu, 14 Jan 2016 07:37:24 +0000 (16:37 +0900)
committerHyunho Kang <hhstark.kang@samsung.com>
Fri, 15 Jan 2016 07:33:43 +0000 (16:33 +0900)
- datacontrol_sql_get_column_name API return wrong column name because
of wrong file descriptor offset. Old cursor file(tizen_2.4) contains
only column name but new cursor file(tizen_3.0) contains both colum name
and column name length.

- When provider encounter error it can notify error
informaion to consumer with data_control_provider_send_error.
If provider send error information while processing select/get
process, consumer wait select data(select process has to receive two
response, result and selected data).
So, we fix this issue in the way that consumer try to receive select
data after check select result is success or not.

Change-Id: I22cd765b8cfe5297a1990730e0e54f8d6de26188
Signed-off-by: Hyunho Kang <hhstark.kang@samsung.com>
src/data-control-map.c
src/data-control-provider.c
src/data-control-sql-cursor.c
src/data-control-sql.c

index c0a84773b27ca58a8326cd984db0a0ade0ae2c6e..31581629411b8a6c2fc39e174c1d22c80b0e5400 100755 (executable)
@@ -193,7 +193,7 @@ static void __remove_map_request_info(int request_id, map_response_cb_s *map_dc)
 
 }
 
-static int __map_handle_cb(int fd, bundle *b, int request_type, appsvc_result_val res, void *data)
+static int __map_handle_cb(int fd, bundle *b, int request_type, int request_id, appsvc_result_val res, void *data)
 {
        LOGI("__map_handle_cb, request_type: %d", request_type);
 
@@ -202,31 +202,17 @@ static int __map_handle_cb(int fd, bundle *b, int request_type, appsvc_result_va
        const char *provider_id = NULL;
        const char *data_id = NULL;
        const char *error_message = NULL;
-       int request_id = -1;
        int result_list_len = 0;
        int provider_result = 0;
        int value_count = 0;
        char **value_list = NULL;
        const char *p = NULL;
-       map_response_cb_s *map_dc = (map_response_cb_s *)data;
 
        if (!b) {
                LOGE("the bundle returned from datacontrol-provider-service is null");
                return DATACONTROL_ERROR_INVALID_PARAMETER;
        }
 
-       p = bundle_get_val(b, OSP_K_REQUEST_ID);
-       if (!p) {
-               LOGE("Invalid Bundle: request_id is null");
-               return DATACONTROL_ERROR_INVALID_PARAMETER;
-       } else {
-               request_id = atoi(p);
-       }
-
-       LOGI("Request ID: %d", request_id);
-
-       __remove_map_request_info(request_id, map_dc);
-
        /* result list */
        result_list = bundle_get_str_array(b, OSP_K_ARG, &result_list_len);
        if (!result_list) {
@@ -298,7 +284,6 @@ static int __map_handle_cb(int fd, bundle *b, int request_type, appsvc_result_va
        } else
                ret = DATACONTROL_ERROR_INVALID_PARAMETER;
 
-
        return ret;
 }
 
@@ -348,10 +333,7 @@ static gboolean __recv_map_message(GIOChannel *channel,
                GIOCondition cond,
                gpointer data)
 {
-
        gint fd = g_io_channel_unix_get_fd(channel);
-       gboolean retval = TRUE;
-
        LOGI("__recv_map_message: ...from %d:%s%s%s%s\n", fd,
                        (cond & G_IO_ERR) ? " ERR" : "",
                        (cond & G_IO_HUP) ? " HUP" : "",
@@ -367,6 +349,8 @@ static gboolean __recv_map_message(GIOChannel *channel,
                guint nb;
                int request_type = 0;
                const char *request_code = NULL;
+               const char *p = NULL;
+               int request_id = -1;
 
                if (_read_socket(fd, (char *)&nbytes, sizeof(nbytes), &nb)) {
                        LOGE("Fail to read nbytes from socket");
@@ -410,6 +394,15 @@ static gboolean __recv_map_message(GIOChannel *channel,
                        LOGI("__recv_map_message: ...from %d: OK\n", fd);
                        LOGI("__recv_map_message: ...caller appid %s: OK\n", bundle_get_val(kb, AUL_K_CALLER_APPID));
 
+                       p = bundle_get_val(kb, OSP_K_REQUEST_ID);
+                       if (!p) {
+                               LOGE("Invalid Bundle: request_id is null");
+                               goto error;
+                       } else {
+                               request_id = atoi(p);
+                       }
+                       LOGI("Request ID: %d", request_id);
+
                        if (data) {
                                request_code = bundle_get_val(kb, OSP_K_DATACONTROL_REQUEST_TYPE);
                                if (!request_code) {
@@ -420,7 +413,7 @@ static gboolean __recv_map_message(GIOChannel *channel,
                                }
                                request_type = atoi(request_code);
 
-                               if (__map_handle_cb(fd, kb, request_type, 0, data) != DATACONTROL_ERROR_NONE) {
+                               if (__map_handle_cb(fd, kb, request_type, request_id, 0, data) != DATACONTROL_ERROR_NONE) {
                                        free(buf);
                                        bundle_free(kb);
                                        goto error;
@@ -432,11 +425,12 @@ static gboolean __recv_map_message(GIOChannel *channel,
                                bundle_free(kb);
                                goto error;
                        }
+                       __remove_map_request_info(request_id, data);
                        free(buf);
                        bundle_free(kb);
                }
        }
-       return retval;
+       return TRUE;
 error:
        if (((map_response_cb_s *)data) != NULL) {
 
index 2f34eaaf73cbd83e07648dc1c17a1b1cc99efeb7..15b14104b14caf535a1142296ba347a355d7e154 100755 (executable)
@@ -470,8 +470,9 @@ static bundle *__set_result(bundle *b, datacontrol_request_type type, void *data
                strncpy(type_str, request_type, MAX_LEN_DATACONTROL_REQ_TYPE);
                LOGI("type is %s", type_str);
 
-       } else
+       } else {
                snprintf(type_str, MAX_LEN_DATACONTROL_REQ_TYPE, "%d", (int)type);
+       }
 
        bundle_add_str(res, OSP_K_DATACONTROL_REQUEST_TYPE, type_str);
 
index b1d50aea28cdef195acda2c271ccdb327891fb90..460e5711ce1944d0d91b3b4660aa4783ac16ecbc 100755 (executable)
@@ -113,43 +113,47 @@ int datacontrol_sql_get_column_count(resultset_cursor *cursor)
 
 int datacontrol_sql_get_column_name(resultset_cursor *cursor, int column_index, char *name)
 {
-       char col_name[4096] = {0, };
+       char *col_name = NULL;
        int i = 0;
        int ret = 0;
-       FILE *fp = NULL;
-       int resultset_fd = dup(cursor->resultset_fd);
-       if (resultset_fd < 0) {
-               LOGE("dup failed errno %d : %s \n", errno, strerror(errno));
-               return DATACONTROL_ERROR_IO_ERROR;
-       }
-
-       fp = fdopen(resultset_fd, "r");
-       if (fp == NULL) {
-               LOGE("unable to open resultset file: %s", strerror(errno));
-               return DATACONTROL_ERROR_IO_ERROR;
-       }
+       int column_len = 0;
+       int fd = cursor->resultset_fd;
 
-       ret = fseek(fp, cursor->resultset_col_name_offset, SEEK_SET);
+       ret = lseek(fd, cursor->resultset_col_name_offset, SEEK_SET);
        if (ret < 0) {
-               LOGE("unable to seek in the resultset file: %s", strerror(errno));
-               fclose(fp);
+               LOGE("unable to seek in the resultset file: %d %s", cursor->resultset_current_offset,
+                               strerror(errno));
                return DATACONTROL_ERROR_IO_ERROR;
        }
 
        for (i = 0; i < column_index + 1; i++) {
-               if (!(fgets(col_name, 4096, fp))) {
-                       LOGE("unable to read a line in the resultset file: %s", strerror(errno));
-                       fclose(fp);
+               ret = read(fd, &column_len, sizeof(int));
+               if (ret == 0) {
+                       LOGE("unable to read column_len: %d", column_len);
                        return DATACONTROL_ERROR_IO_ERROR;
                }
-       }
-
-       memset(name, 0, strlen(col_name)); /* To avoid copying newline */
-       memcpy(name, col_name, strlen(col_name) - 1);
 
+               if (i == column_index) {
+                       col_name = (char *)calloc(column_len, sizeof(char));
+                       ret = read(fd, col_name, column_len);
+                       if (ret == 0) {
+                               LOGE("unable to read col_name : %s", strerror(errno));
+                               free(col_name);
+                               return DATACONTROL_ERROR_IO_ERROR;
+                       }
+               } else {
+                       ret = lseek(fd, column_len, SEEK_CUR);
+                       if (ret < 0) {
+                               LOGE("unable to seek in the resultset file: %s", strerror(errno));
+                               return DATACONTROL_ERROR_IO_ERROR;
+                       }
+               }
+       }
+       memset(name, 0, column_len);
+       memcpy(name, col_name, column_len);
+       free(col_name);
        LOGI("The column name is %s", name);
 
-       fclose(fp);
        return DATACONTROL_ERROR_NONE;
 }
 
index d150007283932802963d9a71ec210fec40c8c9c1..da3ea8884cc68c43dae3cdea71f639b378428783 100755 (executable)
@@ -43,6 +43,7 @@ typedef struct {
 
 static void *datacontrol_sql_tree_root = NULL;
 static GHashTable *__socket_pair_hash = NULL;
+static int __recv_sql_select_process(bundle *kb, int fd, resultset_cursor *cursor);
 
 static void __sql_call_cb(const char *provider_id, int request_id, datacontrol_request_type type,
                const char *data_id, bool provider_result, const char *error, long long insert_rowid, resultset_cursor *cursor, void *data)
@@ -144,8 +145,9 @@ static void __remove_sql_request_info(int request_id, sql_response_cb_s *sql_dc)
 
 }
 
-static int __sql_handle_cb(bundle *b, void *data, resultset_cursor *cursor)
+static int __sql_handle_cb(bundle *b, void *data, int fd, int request_id)
 {
+       resultset_cursor *cursor = NULL;
        int ret = 0;
        const char **result_list = NULL;
        const char *provider_id = NULL;
@@ -153,24 +155,11 @@ static int __sql_handle_cb(bundle *b, void *data, resultset_cursor *cursor)
        const char *error_message = NULL;
        long long insert_rowid = -1;
        datacontrol_request_type request_type = 0;
-       int request_id = -1;
        int result_list_len = 0;
        int provider_result = 0;
        const char *p = NULL;
-       sql_response_cb_s *sql_dc = (sql_response_cb_s *)data;
 
        if (b) {
-               p = appsvc_get_data(b, OSP_K_REQUEST_ID);
-               if (!p) {
-                       LOGE("Invalid Bundle: request_id is null");
-                       return DATACONTROL_ERROR_INVALID_PARAMETER;
-
-               } else
-                       request_id = atoi(p);
-
-               LOGI("Request ID: %d", request_id);
-
-               __remove_sql_request_info(request_id, sql_dc);
 
                /* result list */
                result_list = appsvc_get_data_array(b, OSP_K_ARG, &result_list_len);
@@ -221,6 +210,19 @@ static int __sql_handle_cb(bundle *b, void *data, resultset_cursor *cursor)
 
                switch (request_type) {
 
+               case DATACONTROL_TYPE_SQL_SELECT:
+               {
+                       if (provider_result) {
+                               cursor = datacontrol_sql_get_cursor();
+                               if (!cursor) {
+                                       LOGE("failed to get cursor on sql query resultset");
+                                       return DATACONTROL_ERROR_IO_ERROR;
+                               }
+                               if (__recv_sql_select_process(b, fd, cursor)
+                                               != DATACONTROL_ERROR_NONE)
+                                       return DATACONTROL_ERROR_IO_ERROR;
+                       }
+               }
                case DATACONTROL_TYPE_SQL_INSERT:
                {
                        LOGI("INSERT RESPONSE");
@@ -513,8 +515,6 @@ static gboolean __consumer_recv_sql_message(GIOChannel *channel,
                gpointer data) {
 
        gint fd = g_io_channel_unix_get_fd(channel);
-       gboolean retval = TRUE;
-       resultset_cursor *cursor = NULL;
        char *buf = NULL;
 
        LOGI("__consumer_recv_sql_message: ...from %d:%s%s%s%s\n", fd,
@@ -529,8 +529,8 @@ static gboolean __consumer_recv_sql_message(GIOChannel *channel,
        if (cond & G_IO_IN) {
                int data_len;
                guint nb;
-               datacontrol_request_type request_type = 0;
                const char *p = NULL;
+               int request_id;
 
                if (_read_socket(fd, (char *)&data_len, sizeof(data_len), &nb) != DATACONTROL_ERROR_NONE)
                        goto error;
@@ -542,14 +542,13 @@ static gboolean __consumer_recv_sql_message(GIOChannel *channel,
                }
                if (data_len > 0) {
                        bundle *kb = NULL;
-                       buf = (char *) calloc(data_len + 1, sizeof(char));
+                       buf = (char *)calloc(data_len + 1, sizeof(char));
                        if (buf == NULL) {
                                LOGE("Out of memory.");
                                goto error;
                        }
 
                        if (_read_socket(fd, buf, data_len, &nb) != DATACONTROL_ERROR_NONE) {
-
                                LOGE("Out of memory.");
                                goto error;
                        }
@@ -560,45 +559,36 @@ static gboolean __consumer_recv_sql_message(GIOChannel *channel,
                        }
 
                        kb = bundle_decode_raw((bundle_raw *)buf, data_len);
-                       LOGE("__consumer_recv_sql_message: ...from %d: OK\n", fd);
-                       if (buf) {
-                               free(buf);
-                               buf = NULL;
+
+                       free(buf);
+                       buf = NULL;
+
+                       if (kb == NULL) {
+                               LOGE("bundle_decode_raw fail");
+                               goto error;
                        }
 
-                       p = bundle_get_val(kb, OSP_K_DATACONTROL_REQUEST_TYPE);
+                       p = appsvc_get_data(kb, OSP_K_REQUEST_ID);
                        if (!p) {
-                               LOGE("Invalid Bundle: data-control request type is null");
+                               LOGE("Invalid Bundle: request_id is null");
                                goto error;
+                       } else {
+                               request_id = atoi(p);
                        }
-                       LOGI("request_type : %s", p);
-                       request_type = (datacontrol_request_type)atoi(p);
-                       if (request_type == DATACONTROL_TYPE_SQL_SELECT) {
-                               cursor = datacontrol_sql_get_cursor();
-                               if (!cursor) {
-                                       LOGE("failed to get cursor on sql query resultset");
-                                       goto error;
-                               }
-                               if (__recv_sql_select_process(kb, fd, cursor)
-                                               != DATACONTROL_ERROR_NONE)
-                                       goto error;
-                       }
-
-                       if (__sql_handle_cb(kb, data, cursor)
+                       LOGI("Request ID: %d", request_id);
+                       if (__sql_handle_cb(kb, data, fd, request_id)
                                                != DATACONTROL_ERROR_NONE)
                                goto error;
+                       __remove_sql_request_info(request_id, data);
                }
-
        }
-       return retval;
-
+       return TRUE;
 error:
        if (buf)
                free(buf);
 
        if (((sql_response_cb_s *)data) != NULL) {
                LOGE("g_hash_table_remove");
-               g_hash_table_remove(__socket_pair_hash, ((sql_response_cb_s *)data)->provider_id);
 
                sql_response_cb_s *sql_dc = (sql_response_cb_s *)data;
                g_hash_table_remove(__socket_pair_hash, sql_dc->provider_id);