📄 test-transaction.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 <stdlib.h>#include <time.h>#include <glib.h>#include <database.h>#define TEMPL_FNAME "./sample.templ"#define DB_FNAME "./sample.db"#define DB_ELEMENT_NAME "sample"#define MAX_RETRY 5typedef enum { REC_FIELD_UID = 1, REC_FIELD_NAME = 3, REC_FIELD_MOBILE = 6, REC_FIELD_NUM_HOME = 7, REC_FIELD_NUM_OFFICE = 8, REC_FIELD_FAX = 9, REC_FIELD_COMPANY = 10, REC_FIELD_DEPART = 11, REC_FIELD_WEBSITE = 12, REC_FIELD_EMAIL = 13, REC_FIELD_PICTURE = 14, REC_FIELD_RINGTONE = 15, REC_FIELD_ADDRESS = 16, REC_FIELD_CUSTOM_FLOAT = 17, REC_FIELD_CUSTOM_BINARY = 18,} RecordFields;FieldTemplate * templ = NULL;static Record *gen_record (const gchar *prefix, guint32 base, guint32 index){ Record * record = NULL; gchar * name = NULL; guint32 uid = base * 100 + index; gint i; record = record_new(templ); name = g_strdup_printf("%s%03d", prefix, index); record_set_field_default(record, REC_FIELD_NAME, name, FIELD_SIZE_AUTO); g_free(name); /* record_set_field_default(record, REC_FIELD_UID, &uid, FIELD_SIZE_AUTO);*/ record_set_field_default(record, REC_FIELD_MOBILE, "+861391xxxx820", FIELD_SIZE_AUTO); if (TRUE) { gfloat f = 3.1415926; record_set_field_default(record, REC_FIELD_CUSTOM_FLOAT, &f, FIELD_SIZE_AUTO); } if (TRUE) { guint8 bytes[] = { 0x01, 0x05, 0x08, 0x0A, 0x0B, 0x02, 0x06, 0x09, 0x0E, 0x0C, 0x03, 0x07, 0x00, 0x0F, 0x0D, 0x04, }; record_set_field_default(record, REC_FIELD_CUSTOM_BINARY, bytes, sizeof(bytes)); } if (TRUE) { guint32 fid; fid = record_add_field(record, REC_FIELD_MOBILE); record_set_label(record, fid, "Mobile Number 2"); record_set_field(record, fid, "139xxxxxxx", FIELD_SIZE_AUTO); }// record_print(record); return record;}static gpointertransaction_thread_1 (gpointer data){ RecordDB * db = NULL; RecordDBElement * element = NULL; RecordDBError error = DB_ERROR_NONE; gint count; gint i; gint loop = 0; count = *(gint *)data; g_free(data); g_print("%s(): add %d record to database\n", __FUNCTION__, count); db = record_db_new(DB_FNAME); element = record_db_element_new(db, DB_ELEMENT_NAME, templ); record_db_open(db); while (1) { if (error == DB_ERROR_BUSY) { g_print("%s(): BUSY. Try to start DB_TRANS_IMMEDIATE\n", __FUNCTION__); error = record_db_trans_begin_extend(db, DB_TRANS_IMMEDIATE); } else { error = record_db_trans_begin(db); } if (error != DB_ERROR_NONE) { break; } for (i = 0; i < count; i++) { Record * record = NULL; record = gen_record("thread 1", 1, i); error = record_db_element_add_record(element, record); g_print("%s(): generate record %d ... [%s]\n", __FUNCTION__, i, (error == DB_ERROR_NONE ? "Y" : "N")); record_free(record); } record_db_trans_commit(db); if (error == DB_ERROR_NONE) { break; } g_print("%s(): loop %d\n", __FUNCTION__, loop++); if (loop >= MAX_RETRY) { g_print("%s(): many retries. give up!\n", __FUNCTION__); g_print("%s(): try DB_TRANS_IMMEDIATE directly at first time.\n", __FUNCTION__); break; } } record_db_close(db); record_db_element_free(element); record_db_free(db); g_print("%s(): leaving\n", __FUNCTION__); return NULL;}static gpointertransaction_thread_2 (gpointer data){ RecordDB * db = NULL; RecordDBElement * element = NULL; RecordDBError error = DB_ERROR_NONE; gint count; gint i; gint loop = 0; count = *(gint *)data; g_free(data); g_print("%s(): add %d record to database\n", __FUNCTION__, count); db = record_db_new(DB_FNAME); element = record_db_element_new(db, DB_ELEMENT_NAME, templ); record_db_open(db); while (1) { if (error == DB_ERROR_BUSY) { g_print("%s(): BUSY. Try to start DB_TRANS_IMMEDIATE\n", __FUNCTION__); error = record_db_trans_begin_extend(db, DB_TRANS_IMMEDIATE); } else { error = record_db_trans_begin(db); } if (error != DB_ERROR_NONE) { break; } for (i = 0; i < count; i++) { Record * record = NULL; record = gen_record("thread 2", 2, i); error = record_db_element_add_record(element, record); g_print("%s(): generate record %d ... [%s]\n", __FUNCTION__, i, (error == DB_ERROR_NONE ? "Y" : "N")); record_free(record); } record_db_trans_commit(db); if (error == DB_ERROR_NONE) { break; } g_print("%s(): loop %d\n", __FUNCTION__, loop++); if (loop >= MAX_RETRY) { g_print("%s(): many retries. give up!\n", __FUNCTION__); g_print("%s(): try DB_TRANS_IMMEDIATE directly at first time.\n", __FUNCTION__); break; } } record_db_close(db); record_db_element_free(element); record_db_free(db); g_print("%s(): leaving\n", __FUNCTION__); return NULL;}static gpointertransaction_thread_3 (gpointer data){ RecordDB * db = NULL; RecordDBElement * element = NULL; gint count; gint i; gint loop = 0; RecordDBError error = DB_ERROR_NONE; count = 2; db = record_db_new(DB_FNAME); element = record_db_element_new(db, DB_ELEMENT_NAME, templ); record_db_open(db); while (1) { if (error == DB_ERROR_BUSY) { g_print("%s(): BUSY. Try to start DB_TRANS_IMMEDIATE\n", __FUNCTION__); error = record_db_trans_begin_extend(db, DB_TRANS_IMMEDIATE); } else { error = record_db_trans_begin(db); } if (error != DB_ERROR_NONE) { break; } for (i = 0; i < count; i++) { Record * record = NULL; guint32 uid = i + 1; error = record_db_element_get_record(element, &record, uid); g_print("%s(): retrieve record %d ... [%s]\n", __FUNCTION__, i, (error == DB_ERROR_NONE ? "Y" : "N")); record_free(record); } error = record_db_trans_commit(db); if (error == DB_ERROR_NONE) { break; } g_print("%s(): loop %d\n", __FUNCTION__, loop++); if (loop >= MAX_RETRY) { g_print("%s(): many retries. give up!\n", __FUNCTION__); g_print("%s(): try DB_TRANS_IMMEDIATE directly at first time.\n", __FUNCTION__); break; } } record_db_close(db); record_db_element_free(element); record_db_free(db); g_print("%s(): leaving\n", __FUNCTION__); return NULL;}#define DEFAULT_COUNT 10int main (int argc, char *argv[]){ GThread * thread1 = NULL; GThread * thread2 = NULL; GThread * thread3 = NULL; GError * error = NULL; gint * count1 = NULL; gint * count2 = NULL; count1 = g_new0(gint, 1); *count1 = DEFAULT_COUNT; count2 = g_new0(gint, 1); *count2 = DEFAULT_COUNT; if (argc == 2) { *count1 = atoi(argv[1]); } else if (argc == 3) { *count1 = atoi(argv[1]); *count2 = atoi(argv[2]); } templ = field_template_new_from_file(TEMPL_FNAME); if (!g_thread_supported()) { g_thread_init(NULL); } thread1 = g_thread_create(transaction_thread_1, count1, TRUE, &error); if (thread1 == NULL) { g_print("%s(): create trhead error: %s\n", __FUNCTION__, error->message); g_error_free(error); return EXIT_FAILURE; } thread2 = g_thread_create(transaction_thread_2, count2, TRUE, &error); if (thread2 == NULL) { g_print("%s(): create trhead error: %s\n", __FUNCTION__, error->message); g_error_free(error); return EXIT_FAILURE; } thread3 = g_thread_create(transaction_thread_3, NULL, TRUE, &error); if (thread3 == NULL) { g_print("%s(): create trhead error: %s\n", __FUNCTION__, error->message); g_error_free(error); return EXIT_FAILURE; } g_thread_join(thread1); g_thread_join(thread2); g_thread_join(thread3); field_template_free(templ); return EXIT_SUCCESS;}/*vi:ts=2:nowrap:ai:expandtab */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -