📄 dbelement.c
字号:
{ Iterator * iter = (Iterator *)user_data; g_print("%s(): record(0x%08x), empty(%s)\n", __FUNCTION__, (guint32)value, (record_is_empty((Record *)value) ? "true" : "false")); if (record_is_empty((Record *)value) != TRUE) { iterator_insert(iter, value); } return;}/** * @brief Retrieve a set of #Record objects from * #RecordDBElement database which match the conditions * described in sample #Record objects. * * @param element the #RecordDBElement object * @param iter the #Iterator object holds the results set * @param sample the sample #Record object describes the * search conditions * @param fuzzy does a pattern matching comparison in searching * if this is set TRUE. A percent symbol '%' in the * pattern matches any sequence of zero or more * characters in the string. An underscore '_' in * the pattern matches any single character in the * string. The pattern will only applies on STRING * type fields. * @param intersect all the #Record objects in results set MUST match * every condition described in sample #Record object if * this is set TRUE. Otherwise, the #Record obecjts only * need match one condition at lease. * * @return DB_ERROR_NONE if operation was successfully. * * @note the retrieved #Iteraotr object of results set should be freed * when no longer needed. */RecordDBErrorrecord_db_element_get_records (RecordDBElement *element, Iterator **iter, const Record *sample, gboolean fuzzy, gboolean intersect){ return record_db_element_get_records_extentions(element, iter, sample, fuzzy, intersect, NULL);}/** * @brief Retrieve a set of #Record objects from * #RecordDBElement database which match the conditions * described in sample #Record objects. * * @param element the #RecordDBElement object * @param iter the #Iterator object holds the results set * @param sample the sample #Record object describes the * search conditions * @param fuzzy does a pattern matching comparison in searching * if this is set TRUE. A percent symbol '%' in the * pattern matches any sequence of zero or more * characters in the string. An underscore '_' in * the pattern matches any single character in the * string. The pattern will only applies on STRING * type fields. * @param intersect all the #Record objects in results set MUST match * every condition described in sample #Record object if * this is set TRUE. Otherwise, the #Record obecjts only * need match one condition at lease. * @param ext_sql_str a SQL statement string for extended search condition * * @return DB_ERROR_NONE if operation was successfully. * * @note the retrieved #Iteraotr object of results set should be freed * when no longer needed. */RecordDBErrorrecord_db_element_get_records_extentions (RecordDBElement *element, Iterator **iter, const Record *sample, gboolean fuzzy, gboolean intersect, const gchar *ext_sql_str){ sqlite3_stmt * pStmt = NULL; GString * sql_str = NULL; GString * uids_str = NULL; GString * valid_uids_str = NULL; guint8 field_types = 0x0; GHashTable * results = NULL; gint i; gint ret; g_return_val_if_fail(element, DB_ERROR_ARG_NULL); g_return_val_if_fail(iter, DB_ERROR_ARG_NULL); results = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, NULL); sql_str = g_string_new(""); if (sample) { GString * cond_str = NULL; Iterator * iter_ftids = NULL; gchar * compound_op = NULL; gssize pos; if (record_is_extended(sample)) { g_print("%s(): WARN: extend fields in sample record will be IGNORED.\n", __FUNCTION__); } compound_op = intersect ? " INTERSECT " : " UNION "; cond_str = g_string_new(""); iter_ftids = record_get_ftids(sample); for (iterator_to_first(iter_ftids); !iterator_at_last(iter_ftids); iterator_next(iter_ftids)) { const FieldDescriptor * fdesc = NULL; guint32 ftid = *(guint32 *)iterator_current(iter_ftids); if (ftid == element->db_elm_id_ftid) { continue; } if (record_get_field_default(sample, ftid, NULL) == NULL) { continue; } fdesc = field_template_get(sample->template, ftid); if (fdesc) { DBFieldType type = DB_FIELDS_TEXT; switch (fdesc->type) { case FIELD_TYPE_BOOLEAN: case FIELD_TYPE_DATE: case FIELD_TYPE_INTEGER: type = DB_FIELDS_INTEGER; break; case FIELD_TYPE_FLOAT: type = DB_FIELDS_REAL; break; case FIELD_TYPE_BINARY: type = DB_FIELDS_BLOB; break; case FIELD_TYPE_STRING: default: type = DB_FIELDS_TEXT; break; } g_string_append_printf(cond_str, "SELECT ftid%d FROM ( ", element->db_elm_id_ftid); g_string_append_printf(cond_str, "SELECT ftid%d FROM %s_main WHERE ( ftid%d %s :%03d )", element->db_elm_id_ftid, element->db_elm_name, ftid, (((type == DB_FIELDS_TEXT) && fuzzy)? "LIKE" : "="), ftid); g_string_append_printf(cond_str, " UNION SELECT ftid%d FROM %s_ext_%s WHERE (( value %s :%03d ) & (fid / %d = %d))", element->db_elm_id_ftid, element->db_elm_name, ftstrs[type], (((type == DB_FIELDS_TEXT) && fuzzy)? "LIKE" : "="), ftid, FID_GENERATE_SEED, ftid); g_string_append_printf(cond_str, ")%s", compound_op); } } pos = g_strrstr_len(cond_str->str, cond_str->len, compound_op) - cond_str->str; g_string_erase(cond_str, pos, -1); g_string_append(cond_str, ";"); /* g_print("%s(): cond_str = %s\n", __FUNCTION__, cond_str->str);*/ uids_str = g_string_new(""); record_db_inner_trans_begin(element->db, DB_TRANS_DEFERRED); do { ret = sqlite3_prepare(element->db->database, cond_str->str, -1, &pStmt, 0); if (ret != SQLITE_OK) { g_print("%s(): sqlite3_step() WARNING: %d[%s].\n", __FUNCTION__, sqlite3_errcode(element->db->database), sqlite3_errmsg(element->db->database)); iterator_free(iter_ftids, TRUE); goto failure; } for (iterator_to_first(iter_ftids); !iterator_at_last(iter_ftids); iterator_next(iter_ftids)) { const FieldDescriptor * fdesc = NULL; guint32 ftid = *(guint32 *)iterator_current(iter_ftids); fdesc = field_template_get(element->db_elm_template, ftid); if (fdesc) { gconstpointer value = NULL; FieldSize size = 0; value = record_get_field_default(sample, ftid, &size); if (value == NULL) { continue; }/* g_print("%s(): ftid = %3d, value = 0x%08x, size = %d\n", __FUNCTION__, fdesc->identifier, (guint32)value, size);*/ bind_value_by_fid(pStmt, fdesc->identifier, value, fdesc->type, size); bind_value_by_fid_2(pStmt, fdesc->identifier, value, fdesc->type, size); } } while ((ret = sqlite3_step(pStmt)) == SQLITE_ROW) { gint count; guint32 uid = 0; uid = sqlite3_column_int(pStmt, 0); /* g_print("%s(): uid = %d\n", __FUNCTION__, uid); */ if (g_hash_table_lookup(results, &uid) == NULL) { guint32 * key = NULL; key = g_new0(guint32, 1); *key = uid; g_hash_table_replace(results, key, (gpointer)record_new(element->db_elm_template)); } g_string_append_printf(uids_str, "%d, ", uid); } if (ret == SQLITE_BUSY) { sqlite3_finalize(pStmt); iterator_free(iter_ftids, TRUE); goto failure; } ret = sqlite3_finalize(pStmt); } while (ret == SQLITE_SCHEMA); /* * No match records found */ if (uids_str->len == 0) { goto failure; } pos = g_strrstr_len(uids_str->str, uids_str->len, ", ") - uids_str->str; g_string_erase(uids_str, pos, -1); iterator_free(iter_ftids, TRUE); } g_string_append_printf(sql_str, "SELECT * FROM %s_fidsmap", element->db_elm_name); if (uids_str) { g_string_append_printf(sql_str, " WHERE ftid%d IN ( %s );", element->db_elm_id_ftid, uids_str->str); }/* g_print("%s(): sql_str = %s\n", __FUNCTION__, sql_str->str);*/ record_db_inner_trans_begin(element->db, DB_TRANS_DEFERRED); do { ret = sqlite3_prepare(element->db->database, sql_str->str, -1, &pStmt, 0); if (ret != SQLITE_OK) { g_print("%s(): sqlite3_step() WARNING: %d[%s].\n", __FUNCTION__, sqlite3_errcode(element->db->database), sqlite3_errmsg(element->db->database)); goto failure; } while ((ret = sqlite3_step(pStmt)) == SQLITE_ROW) { guint32 uid = 0; guint32 ftid = FIELD_TEMPLATE_ID_INVALID; guint32 fid = FIELD_ID_INVALID; Record * record = NULL; uid = sqlite3_column_int(pStmt, 0); ftid = sqlite3_column_int(pStmt, 1); fid = sqlite3_column_int(pStmt, 2); record = g_hash_table_lookup(results, &uid); if (record == NULL) { guint32 * key = NULL; key = g_new0(guint32, 1); *key = uid; record = record_new(element->db_elm_template); g_hash_table_replace(results, key, (gpointer)record); } record_add_know_field(record, fid); record_set_default_fid(record, ftid, fid); } if (ret == SQLITE_BUSY) { sqlite3_finalize(pStmt); goto failure; } ret = sqlite3_finalize(pStmt); } while (ret == SQLITE_SCHEMA); g_string_assign(sql_str, ""); g_string_append_printf(sql_str, "SELECT ftid%d,* FROM %s_main", element->db_elm_id_ftid, element->db_elm_name); if (uids_str) { g_string_append_printf(sql_str, " WHERE ftid%d IN ( %s )", element->db_elm_id_ftid, uids_str->str); } g_string_append_printf(sql_str, "%s;", (ext_sql_str ? ext_sql_str : "")); g_print("%s(): sql_str = %s\n", __FUNCTION__, sql_str->str); valid_uids_str = g_string_new(""); do { ret = sqlite3_prepare(element->db->database, sql_str->str, -1, &pStmt, 0); if (ret != SQLITE_OK) { g_print("%s(): sqlite3_step() WARNING: %d[%s].\n", __FUNCTION__, sqlite3_errcode(element->db->database), sqlite3_errmsg(element->db->database)); goto failure; } while ((ret = sqlite3_step(pStmt)) == SQLITE_ROW) { gint count; gint i; guint32 uid = 0; Record * record = NULL; count = sqlite3_column_count(pStmt);/* g_print("%s(): count = %d\n", __FUNCTION__, count);*/ uid = sqlite3_column_int(pStmt, 0); g_string_append_printf(valid_uids_str, "%d, ", uid); record = g_hash_table_lookup(results, &uid); if (record == NULL) { guint32 * key = NULL; key = g_new0(guint32, 1); *key = uid; record = record_new(element->db_elm_template); g_hash_table_replace(results, key, (gpointer)record); } for (i = 1; i < count; i++) { int ftid = FIELD_TEMPLATE_ID_INVALID; const gchar * colname = NULL; colname = sqlite3_column_name(pStmt, i); if (g_strcasecmp(colname, "extflag") == 0) { record->extended = sqlite3_column_int(pStmt, i); continue; } /* g_print("%s(): colname = %s\n", __FUNCTION__, colname); */ sscanf(colname, "ftid%d", &ftid); if (sqlite3_column_type(pStmt, i) == SQLITE_BLOB) { record_set_field_default(record, ftid, sqlite3_column_blob(pStmt, i), sqlite3_column_bytes(pStmt, i)); } else { gpointer value = NULL; value = dump_field_value(pStmt, i); record_set_field_default(record, ftid, value, FIELD_SIZE_AUTO); g_free(value); } } } if (ret == SQLITE_BUSY) { sqlite3_finalize(pStmt); goto failure; } ret = sqlite3_finalize(pStmt); } while (ret == SQLITE_SCHEMA); if (TRUE) { gssize pos; /* * No match records found */ if (valid_uids_str->len == 0) { goto failure; } pos = g_strrstr_len(valid_uids_str->str, valid_uids_str->len, ", ") - valid_uids_str->str; g_string_erase(valid_uids_str, pos, -1); } if (TRUE) { for (i = 0; i < DB_FIELDS_NTYPES; i++) { gchar * ftstr = NULL; if (!(element->db_elm_field_types & (1 << i))) { continue; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -