⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbrelation.c

📁 linux下的电话本的最底层
💻 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 + -