int ctsvc_collation_str(char *src, char **dest)
{
int ret;
- char temp[strlen(src) + 1];
+ char temp[SAFE_STRLEN(src) + 1];
ret = __ctsvc_remove_special_char(src, temp, sizeof(temp));
WARN_IF(ret < CONTACTS_ERROR_NONE, "__ctsvc_remove_special_char() Failed(%d)", ret);
return ret;
}
+
+
+////// contacts_normalized_strstr API should be separated from contacts-service /////////////////////////////////////////////////////////////
+#define CTSVC_COMPARE_BETWEEN(left_range, value, right_range) (((left_range) <= (value)) && ((value) <= (right_range)))
+
+static int __ctsvc_convert_halfwidth_ascii_and_symbol(const char *src, UChar *dest, int dest_size, int* str_size)
+{
+ int i;
+ int32_t size = dest_size;
+ UErrorCode status = 0;
+
+ u_strFromUTF8(dest, dest_size, &size, src, strlen(src), &status);
+ if (U_FAILURE(status)) {
+ CTS_ERR("u_strFromUTF8() Failed(%s)", u_errorName(status));
+ return CONTACTS_ERROR_SYSTEM;
+ }
+
+ *str_size = size;
+
+ // full width -> half width
+ for ( i=0; i < size; i++ ) {
+ // FF00 ~ FF60: Fullwidth ASCII variants
+ if (CTSVC_COMPARE_BETWEEN((UChar)0xFF00, dest[i], (UChar)0xFF60)) {
+ int unicode_value1 = 0;
+ int unicode_value2 = 0;
+ unicode_value1 = 0x0;
+ unicode_value2 = (0xFF & dest[i]) + 0x20;
+ dest[i] = unicode_value1 << 8 | unicode_value2;
+ }
+ // FFE0~FFE6: Fullwidth symbol variants
+ else if (CTSVC_COMPARE_BETWEEN((UChar)0xFFE0, dest[i], (UChar)0xFFE6)) {
+ if( dest[i] == (UChar)0xFFE0 )
+ {
+ dest[i] = (UChar)0x00A2;
+ }
+ else if( dest[i] == (UChar)0xFFE1 )
+ {
+ dest[i] = (UChar)0x00A3;
+ }
+ else if( dest[i] == (UChar)0xFFE2 )
+ {
+ dest[i] = (UChar)0x00AC;
+ }
+ else if( dest[i] == (UChar)0xFFE3 )
+ {
+ dest[i] = (UChar)0x00AF;
+ }
+ else if( dest[i] == (UChar)0xFFE4 )
+ {
+ dest[i] = (UChar)0x00A6;
+ }
+ else if( dest[i] == (UChar)0xFFE5 )
+ {
+ dest[i] = (UChar)0x00A5;
+ }
+ else if( dest[i] == (UChar)0xFFE6 )
+ {
+ dest[i] = (UChar)0x20A9;
+ }
+ else
+ {
+
+ }
+ }
+ else {
+
+ }
+
+ }
+
+ dest[size] = 0x00;
+ return CONTACTS_ERROR_NONE;
+}
+
+static bool __ctsvc_is_phonenumber_halfwidth(const char* keyword)
+{
+ int i;
+ int len = strlen(keyword);
+
+ // TODO: we should add predicate including '+'
+ // TODO: finally, we try to check the number with regular expression.
+ for(i=0; i<len; i++) {
+ if (keyword[i] < '0' || keyword[i] > '9') {
+ CTS_ERR("keyword[%d]: %c is not number)", i, keyword[i]);
+ return false;
+ }
+ }
+ return true;
+}
+
+#define LARGE_BUFFER_SIZE 100
+
+static bool __ctsvc_is_phonenumber_fullwidth(const char* keyword)
+{
+ UChar unicodes[LARGE_BUFFER_SIZE];
+
+ int size = 0;
+ if( __ctsvc_convert_halfwidth_ascii_and_symbol(keyword, unicodes, LARGE_BUFFER_SIZE, &size) != CONTACTS_ERROR_NONE )
+ {
+ CTS_ERR("convert failed! %s", keyword);
+
+ return false;
+ }
+
+ int i = 0;
+ for( i = 0; i < size; i++ )
+ {
+ if (unicodes[i] < (UChar)0xFF10 || unicodes[i] > (UChar)0xFF19 )
+ {
+ CTS_ERR("keyword[%d]: 0x%0x is not number)", i, unicodes[i] );
+
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ctsvc_is_phonenumber(const char* src)
+{
+ return ( __ctsvc_is_phonenumber_halfwidth(src) || __ctsvc_is_phonenumber_fullwidth(src) );
+}
+
+int ctsvc_get_halfwidth_string(const char *src, char** dest, int* dest_size)
+{
+ UChar unicodes[LARGE_BUFFER_SIZE];
+ int ustr_size = 0;
+
+ if( __ctsvc_convert_halfwidth_ascii_and_symbol(src, unicodes, LARGE_BUFFER_SIZE, &ustr_size) != CONTACTS_ERROR_NONE )
+ {
+ CTS_ERR("convert to halfwidth failed! %s ", src);
+
+ return CONTACTS_ERROR_SYSTEM;
+ }
+
+ UErrorCode status = 0;
+
+ // pre-flighting
+ int size = 0;
+ u_strToUTF8(NULL, 0, &size, unicodes, -1, &status);
+ status = U_ZERO_ERROR;
+ *dest = calloc(1, sizeof(char) * (size+1));
+
+ u_strToUTF8(*dest, size+1, dest_size, unicodes, ustr_size, &status);
+ if (U_FAILURE(status)) {
+ CTS_ERR("u_strToUTF8() Failed(%s)", u_errorName(status));
+
+ free(*dest);
+ *dest = NULL;
+ *dest_size = 0;
+
+ return CONTACTS_ERROR_SYSTEM;
+ }
+
+ return CONTACTS_ERROR_NONE;
+}
+
+
static int __ctsvc_normalize_str_to_unicode(const char *src, int src_size, UChar *dest, int dest_size)
{
int ret;
unicode_value1 = (0xFF00 & (tmp_result[0])) >> 8;
unicode_value2 = (0xFF & (tmp_result[0]));
-
- for(i=0; i < 13; i++)
- {
+ for(i=0; i < 13; i++) {
if (hiragana_group[i].start <= unicode_value2
&& unicode_value2 <= hiragana_group[i].end)
result[0] = hiragana_group[i].letter;
return CONTACTS_ERROR_NONE;
}
+#define CTSVC_DB_ESCAPE_CHAR '\\'
+
+static char * __ctsvc_db_get_str_with_escape(char *str, int len, bool with_escape)
+{
+ int i, j = 0;
+ char temp_str[len*2+1];
+
+ if (false == with_escape)
+ return strdup(str);
+
+ for(i=0;i<len;i++) {
+ if (str[i] == '\'' || str[i] == '_' || str[i] == '%' || str[i] == '\\') {
+ temp_str[j++] = CTSVC_DB_ESCAPE_CHAR;
+ }
+ temp_str[j++] = str[i];
+ }
+ temp_str[j] = '\0';
+
+ return strdup(temp_str);
+}
+
static inline int __ctsvc_db_create_str_condition(ctsvc_composite_filter_s *com_filter,
ctsvc_attribute_filter_s *filter, char **condition, GSList **bind_text)
{
int ret;
const char *field_name;
char out_cond[CTS_SQL_MAX_LEN] = {0};
+ bool with_escape = true;
*condition = NULL;
switch(filter->match) {
case CONTACTS_MATCH_EXACTLY:
snprintf(out_cond, sizeof(out_cond), "%s = ?", field_name);
+ with_escape = false;
break;
case CONTACTS_MATCH_FULLSTRING:
- snprintf(out_cond, sizeof(out_cond), "%s LIKE ?", field_name);
+ snprintf(out_cond, sizeof(out_cond), "%s LIKE ? ESCAPE '%c'", field_name, CTSVC_DB_ESCAPE_CHAR);
break;
case CONTACTS_MATCH_CONTAINS:
- snprintf(out_cond, sizeof(out_cond), "%s LIKE ('%%' || ? || '%%')", field_name);
+ snprintf(out_cond, sizeof(out_cond), "%s LIKE ('%%' || ? || '%%') ESCAPE '%c'", field_name, CTSVC_DB_ESCAPE_CHAR);
break;
case CONTACTS_MATCH_STARTSWITH:
- snprintf(out_cond, sizeof(out_cond), "%s LIKE ( ? || '%%')", field_name);
+ snprintf(out_cond, sizeof(out_cond), "%s LIKE ( ? || '%%') ESCAPE '%c'", field_name, CTSVC_DB_ESCAPE_CHAR);
break;
case CONTACTS_MATCH_ENDSWITH:
- snprintf(out_cond, sizeof(out_cond), "%s LIKE ('%%' || ?)", field_name);
+ snprintf(out_cond, sizeof(out_cond), "%s LIKE ('%%' || ?) ESCAPE '%c'", field_name, CTSVC_DB_ESCAPE_CHAR);
break;
case CONTACTS_MATCH_EXISTS:
snprintf(out_cond, sizeof(out_cond), "%s IS NOT NULL", field_name);
char dest[strlen(filter->value.s)+1];
ret = ctsvc_normalize_number(filter->value.s, dest, sizeof(dest), ctsvc_get_phonenumber_min_match_digit());
if (CONTACTS_ERROR_NONE == ret)
- *bind_text = g_slist_append(*bind_text, strdup(dest));
+ *bind_text = g_slist_append(*bind_text, __ctsvc_db_get_str_with_escape(dest, strlen(dest), with_escape));
else
return CONTACTS_ERROR_INVALID_PARAMETER;
}
else
- *bind_text = g_slist_append(*bind_text, strdup(filter->value.s));
+ *bind_text = g_slist_append(*bind_text, __ctsvc_db_get_str_with_escape(filter->value.s, strlen(filter->value.s), with_escape));
}
*condition = strdup(out_cond);
return CONTACTS_ERROR_NONE;
return ret;
}
if (condition && *condition)
- len += snprintf(query+len, sizeof(query)-len, " WHERE %s", condition);
+ len += snprintf(query+len, sizeof(query)-len, " WHERE (%s)", condition);
}
if (__ctsvc_db_view_has_display_name(s_query->view_uri, s_query->properties, s_query->property_count))
cts_stmt_finalize(stmt);
ctsvc_list_reverse(list);
- *out_list = (contacts_list_h)list;
+ *out_list = list;
return CONTACTS_ERROR_NONE;
}
}
}
-static int __ctsvc_db_append_search_query(const char *keyword, char *query, int size)
+static int __ctsvc_db_append_search_query_range(char *query, int size, int range, char *name, char *number, char *data)
{
- bool phonenumber = false;
+ bool first = true;
+ int ret = 0;
+ ret = snprintf(query, size, "'");
+ if (range & CONTACTS_SEARCH_RANGE_NAME) {
+ ret += snprintf(query+ret, size-ret, "name:%s", name);
+ first = false;
+ }
+
+ if (range & CONTACTS_SEARCH_RANGE_NUMBER) {
+ if (first == false)
+ ret += snprintf(query+ret, size-ret, " OR ");
+ ret += snprintf(query+ret, size-ret, "number:%s", number);
+ first = false;
+ }
+
+ if (range & CONTACTS_SEARCH_RANGE_DATA) {
+ if (first == false)
+ ret += snprintf(query+ret, size-ret, " OR ");
+ ret += snprintf(query+ret, size-ret, "data:%s", data);
+ first = false;
+ }
+
+ ret += snprintf(query+ret, size-ret, "' ");
+ return ret;
+}
+
+static int __ctsvc_db_append_search_query(const char *src, char *query, int size, int range)
+{
+ bool phonenumber = true;
int ret;
- int len = 0, i;
+ int i = 0;
+ int temp_len = 0;
- len = strlen(keyword);
- phonenumber = true;
- for(i=0; i<len; i++) {
- if (keyword[i] < '0' || keyword[i] > '9') {
- phonenumber = false;
- break;
- }
+ if( ctsvc_is_phonenumber(src) == false)
+ {
+ CTS_DBG("src is not phone number %s", src);
+ phonenumber = false;
}
- if (phonenumber) {
- char normalized_number[CTSVC_NUMBER_MAX_LEN];
- ctsvc_normalize_number(keyword, normalized_number, CTSVC_NUMBER_MAX_LEN, CTSVC_NUMBER_MAX_LEN -1);
+ char* keyword = NULL;
+ int keyword_size = 0;
+ bool use_replaced_keyword = true;
+ // full width characters -> half width characters (apply to only FW ASCII & some symbols)
+ if( ctsvc_get_halfwidth_string(src, &keyword, &keyword_size) != CONTACTS_ERROR_NONE )
+ {
+ CTS_ERR("UChar converting error : ctsvc_get_halfwidth_string() Failed - %s", src );
+ keyword = (char*)src;
+ use_replaced_keyword = false;
+ }
+ CTS_DBG("UChar converting success : ctsvc_get_halfwidth_string(%s) -> %s[%d] ", src, keyword, keyword_size );
- ret =snprintf(query, size,
- "(SELECT contact_id FROM %s WHERE %s MATCH 'name:%s OR number:%s OR data:%s' "
- "UNION "
- "SELECT contact_id FROM %s WHERE number LIKE '%%%s%%') ",
- CTS_TABLE_SEARCH_INDEX, CTS_TABLE_SEARCH_INDEX,
- keyword, keyword, keyword, CTS_TABLE_PHONE_LOOKUP, normalized_number );
+ char *search_keyword = NULL;
+ search_keyword = __ctsvc_db_make_search_keyword(keyword);
+
+ if (phonenumber) {
+ ret = snprintf(query, size,
+ "(SELECT contact_id FROM %s WHERE %s MATCH ",
+ CTS_TABLE_SEARCH_INDEX, CTS_TABLE_SEARCH_INDEX);
+ ret += __ctsvc_db_append_search_query_range(query+ret, size-ret,
+ range, search_keyword, search_keyword, search_keyword);
+
+ if (range & CONTACTS_SEARCH_RANGE_NUMBER) {
+ char normalized_number[CTSVC_NUMBER_MAX_LEN];
+ int err = ctsvc_normalize_number(keyword, normalized_number, CTSVC_NUMBER_MAX_LEN, CTSVC_NUMBER_MAX_LEN -1);
+ if (0 < err) {
+ ret += snprintf(query+ret, size-ret,
+ "UNION "
+ "SELECT contact_id FROM %s WHERE number LIKE '%%%s%%' ",
+ CTS_TABLE_PHONE_LOOKUP, normalized_number);
+ }
+ }
+ ret += snprintf(query+ret, size-ret, ")");
}
else {
char *normalized_name = NULL;
- char *search_keyword = NULL;
- char *saarch_normal_name = NULL;
- ret = ctsvc_normalize_str(keyword, &normalized_name);
+ char *search_normal_name = NULL;
- search_keyword = __ctsvc_db_make_search_keyword(keyword);
- saarch_normal_name = __ctsvc_db_make_search_keyword(normalized_name);
+ ret = ctsvc_normalize_str(keyword, &normalized_name);
+ search_normal_name = __ctsvc_db_make_search_keyword(normalized_name);
if (CTSVC_LANG_KOREAN == ret) {
char *chosung = calloc(1, strlen(keyword) * 5);
search_chosung = __ctsvc_db_make_search_keyword(chosung);
ret = snprintf(query, size,
- "(SELECT contact_id FROM %s WHERE %s MATCH 'name:%s OR number:%s OR data:%s' "
+ "(SELECT contact_id FROM %s WHERE %s MATCH ",
+ CTS_TABLE_SEARCH_INDEX, CTS_TABLE_SEARCH_INDEX);
+
+ ret += __ctsvc_db_append_search_query_range(query+ret, size-ret,
+ range, search_chosung, search_keyword, search_keyword);
+
+ if (range & CONTACTS_SEARCH_RANGE_NAME) {
+ ret += snprintf(query+ret, size-ret,
"INTERSECT SELECT contact_id FROM %s WHERE name GLOB '*%s*' ",
- CTS_TABLE_SEARCH_INDEX, CTS_TABLE_SEARCH_INDEX,
- search_chosung, search_keyword, search_keyword, CTS_TABLE_NAME_LOOKUP, korean_pattern);
+ CTS_TABLE_NAME_LOOKUP, korean_pattern);
+ }
+
free(chosung);
free(korean_pattern);
free(search_chosung);
search_hiragana = __ctsvc_db_make_search_keyword(hiragana);
ret = snprintf(query, size,
- "(SELECT contact_id FROM %s WHERE %s MATCH 'name:%s OR number:%s OR data:%s' ",
- CTS_TABLE_SEARCH_INDEX, CTS_TABLE_SEARCH_INDEX,
+ "(SELECT contact_id FROM %s WHERE %s MATCH ",
+ CTS_TABLE_SEARCH_INDEX, CTS_TABLE_SEARCH_INDEX);
+ ret += __ctsvc_db_append_search_query_range(query+ret, size-ret, range,
search_hiragana, search_hiragana, search_hiragana);
free(hiragana);
free(search_hiragana);
}
else if (CONTACTS_ERROR_NONE <= ret) {
ret = snprintf(query, size,
- "(SELECT contact_id FROM %s WHERE %s MATCH 'name:%s OR number:%s OR data:%s' ",
- CTS_TABLE_SEARCH_INDEX, CTS_TABLE_SEARCH_INDEX,
- saarch_normal_name, search_keyword, search_keyword);
+ "(SELECT contact_id FROM %s WHERE %s MATCH ",
+ CTS_TABLE_SEARCH_INDEX, CTS_TABLE_SEARCH_INDEX);
+
+ ret += __ctsvc_db_append_search_query_range(query+ret, size-ret, range,
+ search_normal_name, search_keyword, search_keyword);
}
else {
ret = snprintf(query, size,
- "(SELECT contact_id FROM %s WHERE %s MATCH 'name:%s OR number:%s OR data:%s' ",
- CTS_TABLE_SEARCH_INDEX, CTS_TABLE_SEARCH_INDEX,
- search_keyword, search_keyword, search_keyword);
+ "(SELECT contact_id FROM %s WHERE %s MATCH '",
+ CTS_TABLE_SEARCH_INDEX, CTS_TABLE_SEARCH_INDEX);
+ ret += __ctsvc_db_append_search_query_range(query+ret, size-ret,
+ range, search_keyword, search_keyword, search_keyword);
}
- if (strstr(keyword, "@") != NULL) {
+ if (range & CONTACTS_SEARCH_RANGE_NAME) {
+ int j = 0;
+ temp_len = strlen(keyword);
+ char temp_str[temp_len*2+1];
+ for(i=0;i<temp_len;i++) {
+ if (keyword[i] == '\'' || keyword[i] == '_' || keyword[i] == '%' || keyword[i] == '\\') {
+ temp_str[j++] = CTSVC_DB_ESCAPE_CHAR;
+ }
+ temp_str[j++] = keyword[i];
+ }
+ temp_str[j] = '\0';
+ ret += snprintf(query+ret, size-ret,
+ "UNION SELECT contact_id FROM "CTS_TABLE_NAME_LOOKUP" "
+ "WHERE name LIKE '%s%%' ESCAPE '%c'",
+ temp_str, CTSVC_DB_ESCAPE_CHAR);
+ }
+
+ if ((range & CONTACTS_SEARCH_RANGE_DATA) &&
+ (strstr(keyword, "@") != NULL)) {
ret += snprintf(query+ret, size-ret,
" UNION "
"SELECT contact_id FROM %s WHERE %s MATCH 'data:%s' ) ",
ret += snprintf(query+ret, size-ret,") ");
free(normalized_name);
- free(search_keyword);
- free(saarch_normal_name);
+ free(search_normal_name);
}
+ free(search_keyword);
+
+ if( use_replaced_keyword )
+ free(keyword);
+
return ret;
}
static int __ctsvc_db_search_records_exec(const char *view_uri, const property_info_s* properties,
- int ids_count, const char *projection, const char *keyword, int offset, int limit, contacts_list_h* out_list )
+ int ids_count, const char *projection, const char *keyword, int offset, int limit, int range, contacts_list_h* out_list )
{
- char query[CTS_SQL_MAX_LEN*8] = {0}; // temporarily extend
+ char query[CTS_SQL_MAX_LEN + strlen(keyword)*20];
const char *table;
int len;
int ret;
contacts_list_h list = NULL;
ctsvc_record_type_e r_type;
const char *sortkey;
+ query[0] = '\0';
ret = ctsvc_db_get_table_name(view_uri, &table);
RETVM_IF (CONTACTS_ERROR_NONE != ret, ret, "Invalid parameter : view uri (%s)", view_uri);
len = snprintf(query, sizeof(query), "SELECT %s FROM %s "
"WHERE contact_id IN ",
projection, table);
- len += __ctsvc_db_append_search_query(keyword, query + len, sizeof(query) - len);
+ len += __ctsvc_db_append_search_query(keyword, query + len, sizeof(query) - len, range);
}
else { // CTSVC_VIEW_URI_PERSON
len = snprintf(query, sizeof(query), "SELECT %s FROM %s, "
"FROM "CTS_TABLE_CONTACTS " "
"WHERE deleted = 0 AND contact_id IN ",
projection, table);
- len += __ctsvc_db_append_search_query(keyword, query + len, sizeof(query) - len);
+ len += __ctsvc_db_append_search_query(keyword, query + len, sizeof(query) - len, range);
len += snprintf(query + len, sizeof(query) - len, " GROUP BY person_id_in_contact) temp_contacts "
"ON %s.person_id = temp_contacts.person_id_in_contact", table);
}
if( r_type == CTSVC_RECORD_PERSON )
{
unsigned int *project = malloc(sizeof(unsigned int)*ids_count);
- int i;
for(i=0;i<ids_count;i++)
{
project[i] = properties[i].property_id;
char *projection;
const property_info_s *p;
bool can_keyword_search = false;
+ int range = CONTACTS_SEARCH_RANGE_NAME | CONTACTS_SEARCH_RANGE_NUMBER | CONTACTS_SEARCH_RANGE_DATA;
RETVM_IF(NULL == keyword, CONTACTS_ERROR_INVALID_PARAMETER,
"Invalid parameter : keyword is NULL");
ret = __ctsvc_db_create_projection(p, count, NULL, 0, &projection);
RETVM_IF (CONTACTS_ERROR_NONE != ret, ret, "__ctsvc_db_create_projection is failed(%s)", ret);
- __ctsvc_db_search_records_exec(view_uri, p, count, projection, keyword, offset, limit, out_list);
+ ret = __ctsvc_db_search_records_exec(view_uri, p, count, projection, keyword, offset, limit, range, out_list);
free(projection);
- return CONTACTS_ERROR_NONE;
+ return ret;
+}
+
+static int __ctsvc_db_search_records_with_range(const char* view_uri, const char *keyword,
+ int offset, int limit, int range, contacts_list_h* out_list)
+{
+ int ret;
+ unsigned int count;
+ char *projection;
+ const property_info_s *p;
+ bool can_keyword_search = false;
+
+ RETVM_IF(NULL == keyword, CONTACTS_ERROR_INVALID_PARAMETER,
+ "Invalid parameter : keyword is NULL");
+
+ can_keyword_search = __ctsvc_db_view_can_keyword_search(view_uri);
+ RETVM_IF(false == can_keyword_search, CONTACTS_ERROR_INVALID_PARAMETER,
+ "Invalid parameter : can not keyword search");
+
+ p = ctsvc_view_get_all_property_infos(view_uri, &count);
+ ret = __ctsvc_db_create_projection(p, count, NULL, 0, &projection);
+ RETVM_IF (CONTACTS_ERROR_NONE != ret, ret, "__ctsvc_db_create_projection is failed(%s)", ret);
+
+ ret = __ctsvc_db_search_records_exec(view_uri, p, count, projection, keyword, offset, limit, range, out_list);
+ free(projection);
+
+ return ret;
}
static inline int __ctsvc_db_search_records_with_query_exec(ctsvc_query_s *s_query, const char *projection,
const char *condition, GSList *bind, const char *keyword, int offset, int limit, contacts_list_h * out_list )
{
- char query[CTS_SQL_MAX_LEN*8] = {0}; // temporarily extend
+ char query[CTS_SQL_MAX_LEN + strlen(keyword) *20];
int len;
int ret;
int i;
contacts_list_h list = NULL;
const char *table;
const char *sortkey = NULL;
+ int range = CONTACTS_SEARCH_RANGE_NAME | CONTACTS_SEARCH_RANGE_NUMBER | CONTACTS_SEARCH_RANGE_DATA;
+ query[0] = '\0';
RETV_IF(NULL == projection || '\0' == *projection, CONTACTS_ERROR_INVALID_PARAMETER);
if (0 == strcmp(s_query->view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_CONTACT)
|| 0 == strcmp(s_query->view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP)) {
- len += snprintf(query+len, sizeof(query)-len, "FROM %s temp_contacts ", table);
+ len += snprintf(query+len, sizeof(query)-len, "FROM %s WHERE %s.contact_id IN ", table, table);
}
else { // CTSVC_VIEW_URI_PERSON
len += snprintf(query+len, sizeof(query)-len, "FROM %s, "
- "(SELECT contact_id, person_id person_id_in_contact FROM %s WHERE deleted = 0) temp_contacts "
- "ON %s.person_id = temp_contacts.person_id_in_contact "
+ "(SELECT contact_id, person_id person_id_in_contact, addressbook_id FROM %s WHERE deleted = 0) temp_contacts "
+ "ON %s.person_id = temp_contacts.person_id_in_contact WHERE temp_contacts.contact_id IN "
, table, CTS_TABLE_CONTACTS, table);
}
/* len += snprintf(query+len, sizeof(query)-len, "FROM %s, "CTS_TABLE_SEARCH_INDEX" "
"ON %s.contact_id = "CTS_TABLE_SEARCH_INDEX".contact_id", table, table);*/
- len += snprintf(query+len, sizeof(query)-len,
- " WHERE temp_contacts.contact_id IN ");
- len += __ctsvc_db_append_search_query(keyword, query + len, sizeof(query) - len);
+ len += __ctsvc_db_append_search_query(keyword, query + len, sizeof(query) - len, range);
if (condition && *condition)
len += snprintf(query+len, sizeof(query)-len, " AND (%s)", condition);
return __ctsvc_db_search_records(view_uri, keyword, offset, limit, out_list);
}
+API int contacts_db_search_records_with_range(const char* view_uri, const char *keyword,
+ int offset, int limit, int range, contacts_list_h* out_list)
+{
+ RETV_IF(NULL == out_list, CONTACTS_ERROR_INVALID_PARAMETER);
+ *out_list = NULL;
+ RETVM_IF(range == 0, CONTACTS_ERROR_INVALID_PARAMETER, "range is 0");
+ RETVM_IF(NULL == view_uri, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+ return __ctsvc_db_search_records_with_range(view_uri, keyword, offset, limit, range, out_list);
+}
+
API int contacts_db_search_records_with_query( contacts_query_h query, const char *keyword,
int offset, int limit, contacts_list_h* out_list)
{