整个电子词典是分块做的:包含的Dic_Server.c,Dic_Client.c,db.c,query.c,xprtcl.c,dict.h,xprtcl.h,dict.txt(单词文件)
下面是db.c代码:主要用创建子进程实现服务器端的并发操作
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>
#include "dict.h"
#include "xprtcl.h"
#define DATABASE "dict.db"
#define T_USERS "users" /* table name for login users */
#define T_HISTORY "history" /* table name for query history */
#define MAXLEN_SQL 256
sqlite3 *g_db = NULL;
const char *login_name;
const char *login_passwd;
void db_close()
{
if (sqlite3_close(g_db) != SQLITE_OK) {
fprintf(stderr,
"error: close database: %s\n",
sqlite3_errmsg(g_db));
}
}
static int cb_tbl_isexist(
void* arg,
int count,
char** column_value,
char** column_name)
{
dprintf("cb_tbl_isexist was called once\n");
*((int*)arg) = 1; /* set existence flag as 1 */
return 0;
}
static int tbl_isexist(sqlite3 *db, const char *table_name)
{
char sqlstr[MAXLEN_SQL];
int exist;
char *errmsg;
if (snprintf(sqlstr, MAXLEN_SQL,
"select name from sqlite_master "
"where type='table' and name='%s'", table_name) < 0) {
dprintf("snprintf SQL error");
return 0;
}
dprintf("SQL: %s\n", sqlstr);
/*
* Note: this flag "exist" will be passed into the callback.
* If the callback occurred, it will be modified by
* the callback internally.
*/
exist = 0;
if (SQLITE_OK != sqlite3_exec(
db,
sqlstr,
cb_tbl_isexist,
&exist,
&errmsg)) {
dprintf("sqlite3_exec error (table[%s] existence): %s\n",
table_name, errmsg);
sqlite3_free(errmsg);
}
return exist;
}
static int tbl_create_usrs(sqlite3 *db) /*在数据库中创建需要的表格:usrs*/
{
char sqlstr[MAXLEN_SQL];
char *errmsg;
if (1 == tbl_isexist(db, T_USERS)) /*如果创建的表存在,退出*/
{
dprintf("table users already exists\n");
return 0;
}
if (snprintf(
sqlstr,
MAXLEN_SQL,
"create table users(usrname text, passwd text, state text);"
) < 0) {
perror("snprintf error");
return -1;
}
dprintf("SQL: %s\n", sqlstr);
if (SQLITE_OK != sqlite3_exec(
db,
sqlstr,
NULL,
NULL,
&errmsg)) {
fprintf(stderr, "error: create users: %s\n", errmsg);
sqlite3_free(errmsg);
return -1;
}
return 0;
}
static int tbl_create_history(sqlite3 *db) /*在数据库中创建需要的表格:usrs*/
{
char sqlstr[MAXLEN_SQL];
char *errmsg;
if (1 == tbl_isexist(db, T_HISTORY)) /*如果创建的表存在,退出*/
{
dprintf("table history already exists\n");
return 0;
}
if (snprintf(
sqlstr,
MAXLEN_SQL,
"create table history(usrname text, word text, time text);"
) < 0) {
perror("snprintf error");
return -1;
}
dprintf("SQL: %s\n", sqlstr);
if (SQLITE_OK != sqlite3_exec(
db,
sqlstr,
NULL,
NULL,
&errmsg)) {
fprintf(stderr, "error: create users: %s\n", errmsg);
sqlite3_free(errmsg);
return -1;
}
return 0;
}
int db_init()
{
int result;
result = sqlite3_open(DATABASE, &g_db);
if (result != SQLITE_OK)
{
if (NULL != g_db)
{
fprintf(stderr, "error: open database: %s\n",
sqlite3_errmsg(g_db));
}
else
{
fprintf(stderr, "error: failed to allocate memory!\n");
}
return -1;
}
if (tbl_create_usrs(g_db) < 0) {
goto _error_exit;
}
if (tbl_create_history(g_db) < 0) {
goto _error_exit;
}
return 0;
_error_exit:
db_close();
return -1;
}
static int cb_user_isexist(
void* arg,
int count,
char** column_value,
char** column_name)
{
dprintf("cb_user_isexist was called once\n");
*((int*)arg) = 1; /* set existence flag as 1 */
return 0;
}
static int user_isexist(sqlite3 *db, const char *user_name,const char *user_passwd)
{
char sqlstr[MAXLEN_SQL];
int exist;
char *errmsg;
if (snprintf(sqlstr, MAXLEN_SQL,
"select * from %s "
"where usrname='%s'", T_USERS, user_name) < 0) {
dprintf("snprintf SQL error");
return 0;
}
dprintf("SQL: %s\n", sqlstr);
/*
* Note: this flag "exist" will be passed into the callback.
* If the callback occurred, it will be modified by
* the callback internally.
*/
exist = 0;
if (SQLITE_OK != sqlite3_exec(
db,
sqlstr,
cb_user_isexist,
&exist,
&errmsg)) {
dprintf("sqlite3_exec error (user[%s] existence): %s\n",
user_name, errmsg);
sqlite3_free(errmsg);
}
return exist;
}
/*注册的账号*/
int tbl_insert_users(const char *name, const char *passwd)
{
char sqlstr[MAXLEN_SQL];
char *errmsg;
/* validating syntax of username and passwd ...... */
/* checking if user exists with the input name */
if (user_isexist(g_db, name, passwd)) /*账号已存在,退出*/
{
return -1;
}
/* in case passed checking */ /*账号不存在,向数据库中录入账号和密码*/
if (snprintf(sqlstr, MAXLEN_SQL, "insert into users values('%s', '%s', '0')",
name, passwd)< 0)
{
perror("snprintf error");
return -1;
}
dprintf("SQL: %s\n", sqlstr);
if (SQLITE_OK != sqlite3_exec(g_db, sqlstr, NULL, NULL, &errmsg))
{
fprintf(stderr, "error: insert users: %s\n", errmsg);
sqlite3_free(errmsg);
return -1;
}
return 0;
}
/*登录验证的回调函数*/
static int login_user_isexist(
void* arg,
int count,
char** column_value,
char** column_name)
{
//int i=0;
char sqlstr[MAXLEN_SQL];
char *errmsg;
dprintf("cb_user_isexist was called once\n");
if((*column_value[0] == *login_name) && (*column_value[1] == *login_passwd))
{
if((*column_value[2])== '0') /*验证账号是否已登录*/
{
//printf("entry this function\n");
if (snprintf(sqlstr, MAXLEN_SQL,
"update users set state = 1 where usrname = '%s'",
column_value[0])< 0)
{
perror("snprintf error");
return -1;
}
dprintf("SQL: %s\n", sqlstr);
if (SQLITE_OK != sqlite3_exec(g_db, sqlstr, NULL, NULL, &errmsg))
{
fprintf(stderr, "error: insert users: %s\n", errmsg);
sqlite3_free(errmsg);
return -1;
}
*((int*)arg) = 1;/*set existence flag as 1 */
}
if((*column_value[2])== '1')
{
*((int*)arg) = 2;
}
}
return 0;
}
static int login_user_true(sqlite3 *db, const char *user_name,const char *user_passwd)
{
char sqlstr[MAXLEN_SQL];
int exist;
char *errmsg;
if (snprintf(sqlstr, MAXLEN_SQL,
"select * from %s "
"where usrname='%s'", T_USERS, user_name) < 0) {
dprintf("snprintf SQL error");
return 0;
}
dprintf("SQL: %s\n", sqlstr);
/*
* Note: this flag "exist" will be passed into the callback.
* If the callback occurred, it will be modified by
* the callback internally.
*/
exist = 0;
if (SQLITE_OK != sqlite3_exec(
db,
sqlstr,
login_user_isexist,
&exist,
&errmsg)) {
dprintf("sqlite3_exec error (user[%s] existence): %s\n",
user_name, errmsg);
sqlite3_free(errmsg);
}
return exist;
}
/*验证登陆账号是否注册*/
int login_users(const char *name, const char *passwd)
{
//char sqlstr[MAXLEN_SQL];
//char *errmsg;
int login_flag;
login_name = name;
login_passwd = passwd;
/* validating syntax of username and passwd ...... */
/* checking if user exists with the input name */
login_flag = login_user_true(g_db, name, passwd);
if (login_flag==1) /*账号是否已注册和登录*/
{
printf("login successfuly\n");
return 0;
}
if(login_flag==2) /*账号已登录*/
{
printf("Accounts have been online\n");
return 1;
}
return -1;
}