欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

database.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"/** * @brief		Create a #RecordDB object, initialized with * 					the given information. * * @param		db_fname				database filename * @param		db_table_prefix	database tables prefix * @param		db_template			database template * * @return	newly-created #RecordDB object or NULL if failed. */RecordDB * record_db_new (const gchar	*db_fname){	RecordDB *db = NULL;	g_return_val_if_fail(db_fname, NULL);	db = g_new0(RecordDB, 1);	if (db == NULL)	{		return NULL;	}	db->db_fname				= g_strdup(db_fname);	db->db_trans_status	= TRANS_NONE;	db->database				= NULL;	if (g_file_test(db->db_fname,									G_FILE_TEST_IS_REGULAR) == FALSE)	{		g_print("%s(): db file NOT exists.[%s]\n",						__FUNCTION__,						db->db_fname);    FILE *file = fopen(db->db_fname, "wb");    g_print("%s(): file_handle = %d\n",                 __FUNCTION__,                 db->db_fname);    fclose(file);							}		db->elements = g_hash_table_new_full(g_str_hash,																			 g_str_equal,																			 g_free,																			 NULL);	return db;}/** * @brief		Frees the memory allocated for  * 					the #RecordDB object. * * @param		db		the #RecordDB object */voidrecord_db_free (RecordDB	*db){	g_return_if_fail(db);	g_hash_table_destroy(db->elements);	g_free(db->db_fname);		g_free(db);	return;}/** * @brief		Open the database of #RecordDB object * * @param		db		the #RecordDB object */RecordDBErrorrecord_db_open (RecordDB	*db){	g_return_val_if_fail(db, DB_ERROR_ARG_NULL);		if (db->database != NULL)	{		g_print("%s(): database already opened.\n",						__FUNCTION__);								return DB_ERROR_FAILED;	}	if (!g_file_test(db->db_fname,			 G_FILE_TEST_IS_REGULAR))	{		g_print("%s(): database file NOT exists: %s.\n",						__FUNCTION__,						db->db_fname);		return DB_ERROR_NOT_EXIST;	}	if (sqlite3_open(db->db_fname,									 &db->database) != SQLITE_OK)	{		g_print("%s(): open database failed: %s.\n",						__FUNCTION__,						sqlite3_errmsg(db->database));		sqlite3_close(db->database);		db->database = NULL;		return DB_ERROR_FAILED;	}		/*	 * sets a busy timeout that sleeps for a while 	 * when a database/table is locked. 	 */	sqlite3_busy_timeout(db->database, 10000);		return DB_ERROR_NONE;}/** * @brief		Close the database of #RecordDB object * * @param		db		the #RecordDB object */RecordDBErrorrecord_db_close (RecordDB	*db){	g_return_val_if_fail(db, DB_ERROR_ARG_NULL);		if (db->database)	{		sqlite3_close(db->database);		db->database = NULL;	}	return DB_ERROR_NONE;}static gbooleanrecord_db_trans_begin_real (RecordDB					*db,														RecordDBTransType	 type,														TransactionStatus	 status){	gchar * errmsg = NULL;	GString * sql_str = NULL;		/*	 * Transactions can be deferred, immediate, or exclusive. 	 * Deferred means that no locks are acquired on the database 	 * until the database is first accessed. Thus with a deferred 	 * transaction, the BEGIN statement itself does nothing. 	 * Locks are not acquired until the first read or write 	 * operation. The first read operation against a database 	 * creates a SHARED lock and the first write operation creates 	 * a RESERVED lock. Because the acquisition of locks is 	 * deferred until they are needed, it is possible that another 	 * thread or process could create a separate transaction and 	 * write to the database after the BEGIN on the current thread 	 * has executed. If the transaction is immediate, then RESERVED 	 * locks are acquired on all databases as soon as the BEGIN 	 * command is executed, without waiting for the database to be 	 * used. After a BEGIN IMMEDIATE, you are guaranteed that no other	 * thread or process will be able to write to the database or 	 * do a BEGIN IMMEDIATE or BEGIN EXCLUSIVE. Other processes can 	 * ontinue to read from the database, however. An exclusive 	 * transaction causes EXCLUSIVE locks to be acquired on all 	 * databases. After a BEGIN EXCLUSIVE, you are guaranteed that 	 * no other thread or process will be able to read or write the 	 * database until the transaction is complete.	 */	sql_str = g_string_new("BEGIN ");	switch (type)	{		case DB_TRANS_IMMEDIATE:			g_string_append(sql_str, "IMMEDIATE");			break;					case DB_TRANS_EXCLUSIVE:			g_string_append(sql_str, "EXCLUSIVE");			break;					default:			g_string_append(sql_str, "DEFERRED");			break;	}	//	g_return_val_if_fail(db, DB_ERROR_ARG_NULL);	if (sqlite3_exec(db->database,									 sql_str->str,									 NULL,									 NULL,									 &errmsg) != SQLITE_OK)	{		g_print("%s(): %s error: %s.\n",						__FUNCTION__,						sql_str->str,						errmsg);		g_free(errmsg);		return FALSE;	}		g_string_free(sql_str, TRUE);		db->db_trans_status = status;		return TRUE;}gbooleanrecord_db_inner_trans_begin (RecordDB						*db,														 RecordDBTransType	 type){	g_return_val_if_fail(db, DB_ERROR_ARG_NULL);	if (db->db_trans_status != TRANS_NONE)	{		return DB_ERROR_NONE;	}		if (record_db_trans_begin_real(db,																 type,																 TRANS_INNER) == FALSE)	{		return DB_ERROR_FAILED;	}		return DB_ERROR_NONE;}RecordDBErrorrecord_db_trans_begin (RecordDB	*db){	g_return_val_if_fail(db, DB_ERROR_ARG_NULL);	if (db->db_trans_status != TRANS_NONE)	{		return DB_ERROR_NONE;	}	if (record_db_trans_begin_real(db,																 DB_TRANS_DEFERRED,																 TRANS_OUTER) == FALSE)	{		return DB_ERROR_FAILED;	}		return DB_ERROR_NONE;}RecordDBErrorrecord_db_trans_begin_extend (RecordDB					*db,															RecordDBTransType	 type){	g_return_val_if_fail(db, DB_ERROR_ARG_NULL);	if (db->db_trans_status != TRANS_NONE)	{		return DB_ERROR_NONE;	}	if (record_db_trans_begin_real(db,																 type,																 TRANS_OUTER) == FALSE)	{		return DB_ERROR_FAILED;	}		return DB_ERROR_NONE;}static gbooleanrecord_db_trans_commit_real (RecordDB	*db){	gchar * errmsg = NULL;		if (sqlite3_exec(db->database,									 "COMMIT",									 NULL,									 NULL,									 &errmsg) != SQLITE_OK)	{		g_print("%s(): COMMIT TRANS error: %s.\n",						__FUNCTION__,						errmsg);		g_free(errmsg);		return FALSE;	}		db->db_trans_status = TRANS_NONE;		return TRUE;}gbooleanrecord_db_inner_trans_commit (RecordDB	*db){	g_return_val_if_fail(db, DB_ERROR_ARG_NULL);	if (db->db_trans_status != TRANS_INNER)	{		return DB_ERROR_NONE;	}	if (record_db_trans_commit_real(db) == FALSE)	{		return DB_ERROR_FAILED;	}	return DB_ERROR_NONE;}RecordDBErrorrecord_db_trans_commit (RecordDB	*db){	g_return_val_if_fail(db, DB_ERROR_ARG_NULL);	if (db->db_trans_status != TRANS_OUTER)	{		return DB_ERROR_NONE;	}	if (record_db_trans_commit_real(db) == FALSE)	{		return DB_ERROR_FAILED;	}	return DB_ERROR_NONE;}/*vi:ts=2:nowrap:ai:expandtab */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -