📄 dbrelation.c
字号:
/* librecord2 - Record Object manipulation and storage library 2 * * Authors: YE Nan <nan.ye@orange-ftgroup.com> * * This software and associated documentation files (the "Software") * are copyright (C) 2005 LiPS Linux Phone Standards Forum [FranceTelecom] * All Rights Reserved. * * A copyright license is hereby granted for redistribution and use of * the Software in source and binary forms, with or without modification, * provided that the following conditions are met: * - Redistributions of source code must retain the above copyright notice, * this copyright license and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this copyright license and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - Neither the name of LiPS nor the names of its Members may be used * to endorse or promote products derived from the Software without * specific prior written permission. * * A patent license for any Necessary Claims owned by Members of LiPS Forum * to make, have made, use, import, offer to sell, lease and sell or otherwise * distribute any implementation compliant with the any specification adopted * by the LiPS Forumcan be obtained from the respective Members on reasonable * and non-discriminatory terms and conditions and under reciprocity, as * regulated in more detail in the Internal Policy of the LiPS Forum. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER, ITS MEMBERS AND CONTRIBUTORS * "AS IS", AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER, * ITS MEMBERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */#include <stdio.h>#include <glib.h>#include <sqlite3.h>#include <database.h>#include <utils.h>#include "internal.h"static char * ftstrs [DB_FIELDS_NTYPES] = { "INTEGER", "REAL", "TEXT", "BLOB",};static gboolean _record_db_relation_create_tables (RecordDBRelation *relation){ GString * sql_str = NULL; gchar * errmsg = NULL; g_return_val_if_fail(relation, FALSE); sql_str = g_string_new(""); g_string_append_printf(sql_str, "CREATE TABLE IF NOT EXISTS %s ( ", relation->db_rel_table_name); g_string_append_printf(sql_str, "prival1 %s, ", ftstrs[relation->db_rel_pri_type1]); g_string_append_printf(sql_str, "prival2 %s, ", ftstrs[relation->db_rel_pri_type2]); g_string_append(sql_str, "PRIMARY KEY ( prival1, prival2 ) );");/* g_print("CREATE REL TABLE sql:\n%s\n", sql_str->str);*/ if (record_db_open(relation->db) != DB_ERROR_NONE) { goto failure; } while (record_db_inner_trans_begin(relation->db, DB_TRANS_DEFERRED) != DB_ERROR_NONE); if (sqlite3_exec(relation->db->database, sql_str->str, NULL, NULL, &errmsg) != SQLITE_OK) { g_print("%s(): create table failed: %s.\n", __FUNCTION__, errmsg); goto failure; } record_db_inner_trans_commit(relation->db); record_db_close(relation->db); g_string_free(sql_str, TRUE); return TRUE;failure: record_db_close(relation->db); g_string_free(sql_str, TRUE); g_free(errmsg); return FALSE;}RecordDBRelation * record_db_relation_new (RecordDB *db, const gchar *element_name1, const gchar *element_name2){ RecordDBRelation * relation = NULL; RecordDBElement * element1 = NULL; RecordDBElement * element2 = NULL; g_return_val_if_fail(db, NULL); g_return_val_if_fail(element_name1, NULL); g_return_val_if_fail(element_name2, NULL); relation = g_new0(RecordDBRelation, 1); if (relation == NULL) { return NULL; } element1 = g_hash_table_lookup(db->elements, (gpointer)element_name1); if (element1 == NULL) { g_print("%s(): element %s is NOT exists.\n", __FUNCTION__, element_name1); record_db_relation_free(relation); return NULL; } element2 = g_hash_table_lookup(db->elements, (gpointer)element_name2); if (element2 == NULL) { g_print("%s(): element %s is NOT exists.\n", __FUNCTION__, element_name2); record_db_relation_free(relation); return NULL; } relation->db = db; relation->db_rel_pri_ftid1 = element1->db_elm_id_ftid; relation->db_rel_pri_type1 = element1->db_elm_id_type; relation->db_rel_pri_ftid2 = element2->db_elm_id_ftid; relation->db_rel_pri_type2 = element2->db_elm_id_type; relation->db_rel_table_name = g_strdup_printf("%s_ftid%d_rel_%s_ftid%d", element_name1, relation->db_rel_pri_ftid1, element_name2, relation->db_rel_pri_ftid2); _record_db_relation_create_tables(relation); return relation;}voidrecord_db_relation_free (RecordDBRelation *relation){ g_return_if_fail(relation); g_free(relation->db_rel_table_name); g_free(relation); return;}RecordDBErrorrecord_db_relation_add (RecordDBRelation *relation, guint32 prival1, guint32 prival2){ GString * sql_str = NULL; sqlite3_stmt * pStmt = NULL; gint ret; g_return_val_if_fail(relation, DB_ERROR_ARG_NULL); sql_str = g_string_new(""); g_string_append_printf(sql_str, "INSERT INTO %s ( prival1, prival2 ) values ( :001, :002 );", relation->db_rel_table_name);/* g_print("%s(): INSERT sql:\n%s\n", __FUNCTION__, sql_str->str);*/ record_db_inner_trans_begin(relation->db, DB_TRANS_DEFERRED); do { gint para_index = -1; ret = sqlite3_prepare(relation->db->database, sql_str->str, -1, &pStmt, 0); if (ret != SQLITE_OK) { g_print("%s(): sqlite3_prepare() failed: %s.\n", __FUNCTION__, sqlite3_errmsg(relation->db->database)); goto failure; } para_index = sqlite3_bind_parameter_index(pStmt, ":001");/* g_print("%s(): index = %d, value = %d\n", __FUNCTION__, para_index, prival1);*/ sqlite3_bind_int(pStmt, para_index, prival1); para_index = sqlite3_bind_parameter_index(pStmt, ":002");/* g_print("%s(): index = %d, value = %d\n", __FUNCTION__, para_index, prival2);*/ sqlite3_bind_int(pStmt, para_index, prival2); ret = sqlite3_step(pStmt); if (ret == SQLITE_ROW) { goto failure; } if (ret != SQLITE_DONE) { g_print("%s(): sqlite3_step() WARNING: rel, %d[%s].\n", __FUNCTION__, sqlite3_errcode(relation->db->database), sqlite3_errmsg(relation->db->database)); if (ret == SQLITE_BUSY) { sqlite3_finalize(pStmt); goto failure; } } ret = sqlite3_finalize(pStmt); } while (ret == SQLITE_SCHEMA); record_db_inner_trans_commit(relation->db); g_string_free(sql_str, TRUE); return DB_ERROR_NONE; failure: g_string_free(sql_str, TRUE); if (ret == SQLITE_BUSY) { return DB_ERROR_BUSY; } return DB_ERROR_FAILED;}RecordDBError record_db_relation_get (RecordDBRelation *relation, Iterator **iter, guint32 prival, gboolean isprival1){ GString * sql_str = NULL; sqlite3_stmt * pStmt = NULL; gint ret; g_return_val_if_fail(relation, DB_ERROR_ARG_NULL); sql_str = g_string_new(""); if (isprival1 == TRUE) { g_string_append_printf(sql_str, "SELECT prival2 FROM %s where ( prival1 = :001 );", relation->db_rel_table_name); } else { g_string_append_printf(sql_str, "SELECT prival1 FROM %s where ( prival2 = :001 );", relation->db_rel_table_name); }/* g_print("%s(): SELECT sql: %s\n", __FUNCTION__, sql_str->str);*/ record_db_inner_trans_begin(relation->db, DB_TRANS_DEFERRED); do { gint para_index = -1; ret = sqlite3_prepare(relation->db->database, sql_str->str, -1, &pStmt, 0); if (ret != SQLITE_OK) { g_print("%s(): sqlite3_prepare() failed: %s.\n", __FUNCTION__, sqlite3_errmsg(relation->db->database)); goto failure; } para_index = sqlite3_bind_parameter_index(pStmt, ":001");/* g_print("%s(): index = %d, value = %d\n", __FUNCTION__, para_index, prival1);*/ sqlite3_bind_int(pStmt, para_index, prival); *iter = NULL; while ((ret = sqlite3_step(pStmt)) == SQLITE_ROW) { guint32 * uid = NULL; if (*iter == NULL) { *iter = iterator_new(); } uid = g_new0(guint32, 1); *uid = sqlite3_column_int(pStmt, 0); iterator_insert(*iter, (gpointer)uid); } if (ret == SQLITE_BUSY) { sqlite3_finalize(pStmt); goto failure; } ret = sqlite3_finalize(pStmt); } while (ret == SQLITE_SCHEMA); record_db_inner_trans_commit(relation->db); g_string_free(sql_str, TRUE); return DB_ERROR_NONE; failure: g_string_free(sql_str, TRUE); if (ret == SQLITE_BUSY) { return DB_ERROR_BUSY; } if (*iter == NULL) { return DB_ERROR_RESULT_NULL; } return DB_ERROR_FAILED;}RecordDBErrorrecord_db_relation_remove (RecordDBRelation *relation, guint32 prival1, guint32 prival2){ GString * sql_str = NULL; sqlite3_stmt * pStmt = NULL; gint ret; g_return_val_if_fail(relation, DB_ERROR_ARG_NULL); sql_str = g_string_new(""); g_string_append_printf(sql_str, "DELETE FROM %s where ( ", relation->db_rel_table_name); if (prival1 != PRIMARY_ID_INVALID) { g_string_append(sql_str, "prival1 = :001 AND "); } if (prival2 != PRIMARY_ID_INVALID) { g_string_append(sql_str, "prival2 = :002 AND "); } g_string_append_printf(sql_str, "prival1 NOT NULL );");/* g_print("%s(): DELETE sql:\n%s\n", __FUNCTION__, sql_str->str);*/ record_db_inner_trans_begin(relation->db, DB_TRANS_DEFERRED); do { gint para_index = -1; ret = sqlite3_prepare(relation->db->database, sql_str->str, -1, &pStmt, 0); if (ret != SQLITE_OK) { g_print("%s(): sqlite3_prepare() failed: %s.\n", __FUNCTION__, sqlite3_errmsg(relation->db->database)); goto failure; } if (prival1 != PRIMARY_ID_INVALID) { para_index = sqlite3_bind_parameter_index(pStmt, ":001"); /* g_print("%s(): index = %d, value = %d\n", __FUNCTION__, para_index, prival1); */ sqlite3_bind_int(pStmt, para_index, prival1); } if (prival2 != PRIMARY_ID_INVALID) { para_index = sqlite3_bind_parameter_index(pStmt, ":002"); /* g_print("%s(): index = %d, value = %d\n", __FUNCTION__, para_index, prival1); */ sqlite3_bind_int(pStmt, para_index, prival2); } ret = sqlite3_step(pStmt); if (ret == SQLITE_ROW) { goto failure; } if (ret != SQLITE_DONE) { g_print("%s(): sqlite3_step() WARNING: rel, %d[%s].\n", __FUNCTION__, sqlite3_errcode(relation->db->database), sqlite3_errmsg(relation->db->database)); if (ret == SQLITE_BUSY) { sqlite3_finalize(pStmt); goto failure; } } ret = sqlite3_finalize(pStmt); } while (ret == SQLITE_SCHEMA); record_db_inner_trans_commit(relation->db); g_string_free(sql_str, TRUE); return DB_ERROR_NONE; failure: g_string_free(sql_str, TRUE); if (ret == SQLITE_BUSY) { return DB_ERROR_BUSY; } return DB_ERROR_FAILED;}/*vi:ts=2:nowrap:ai:expandtab*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -