C语言读写伯克利DB 3

gcc -o channeldb channel.c -db -Wall

# -Wall参数等价于执行lint,即:进行代码的静态分析,它可以指出未初始化的变量,未使用的变量

 

#include <assert.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <db.h>

#include <sys/types.h>

#include <getopt.h>



//define DATABASE "/work/stat/read/newstat/data/userlist/historydb/channel.db"



#define DATABASE "/mnt/disk1/ucshuqi/touch/userlist/historydb/channel.db"

#define YES 1

#define NO  0





/* ViewData Module */



struct ViewData {

        int date;

};



void setDate(struct ViewData *data,char *s)

{

        assert(data!=NULL && s!= NULL && strlen(s) == 8);

        data->date = atoi(s);

}



// the function return YES when query.date >= stored.date

int isHistoryViewInfo(struct ViewData *query , struct ViewData *stored)

{

        assert(query != NULL && stored != NULL);

        printf("query date is %d , stored date is %d \n",query->date, stored->date);



        if(query->date >= stored->date)

        {

                return YES;

        }

        else

        {

                return NO;

        }

}



void printViewData(struct ViewData *data)

{

        printf("print view date : %d\n",data->date);

}





/* string helper module */



char *trim(char *s)

{

        int i = strlen(s);

        for(;i>0;i--)

        {

                if(s[i]==' ' || s[i]=='\n' || s[i]=='\0' || s[i]=='\t')

                {

                        s[i] = '\0';

                }

                else

                {

                        break;

                }

        }

        return s;

}



/* database helper module */



DB *openDb()

{

        int ret;

        DB *dbp = NULL;



        ret = db_create(&dbp, NULL, 0);

        if(ret != 0)

        {

                fprintf(stderr,"create Db error!\n");

                exit(1);

        }



        ret = dbp->open(dbp, NULL, DATABASE, NULL, DB_BTREE, DB_CREATE,0664);



        if(ret != 0)

        {

                fprintf(stderr,"open Db error!\n");

                exit(1);

        }



        return dbp;

}



/* business module */



int saveViewInfo(DB *dbp, char *user, struct ViewData *data)

{

        DBT key,value;



        memset(&key, 0, sizeof(key));

        key.data = user;

        key.size = strlen(user) + 1;



        memset(&value, 0, sizeof(value));

        value.data = data;

        value.size = sizeof(*data);

        if(dbp->put(dbp, NULL, &key, &value, 0) == 0)

        {

                //printf("save ---> %s, %d\n", key.data, key.size);

                printViewData(value.data);

                return YES;

        }

        else

        {

                return NO;

        }

}



int findViewInfo(DB *dbp, char *user, struct ViewData *data)

{

        DBT key,value;



        memset(&key, 0, sizeof(key));

        key.data = user;

        key.size = strlen(user) + 1;



        memset(&value,0,sizeof(value)); // must !!!



        if(dbp->get(dbp, NULL, &key, &value, 0) == 0)

        {

                memcpy((char*)data,(char*)value.data,value.size);

                //printViewData(data);

                return YES; //view in database 

        }

        else

        {

                return NO; //view not in database

        }

}



void recordNewView(FILE *fp, char *user)                                                          

{

        char buffer[1024] = {0};                                                                

        assert(fp != NULL && user != NULL);                                                     



        printf("%s is new view\n", user);

        sprintf(buffer, "%s found\n", user);                                               

        fwrite(buffer, sizeof(char), strlen(buffer), fp);

}



void saveViewFile(char *from, char *to, struct ViewData *writeData)

{

        DB *dbp = openDb();

        struct ViewData stored;

        char buffer[1024 * 4];

        FILE *fp = fopen(from,"r");

        FILE *fpResult = fopen(to,"w");



        assert(fp != NULL && fpResult != NULL && writeData != NULL);



        while(fgets((char*)buffer, 1024*4, fp)!=NULL)

        {

                char *user = trim((char*)buffer);

                memset(&stored, 0, sizeof(stored));



                if(findViewInfo(dbp, user, &stored) == YES)

                {

                        if(isHistoryViewInfo(writeData,&stored) == NO)

                        {

                                recordNewView(fpResult, user);

                        }

                        continue;

                }



                recordNewView(fpResult, user);

                if(saveViewInfo(dbp, user, writeData) == NO)

                {

                        printf("save %s faild\n", user);

                }

                memset(&buffer, 0, 1024 * 4); 

        }

        dbp->close(dbp, 0);

        fclose(fp);

        fclose(fpResult);

}



void hasViewInfo(char *user, struct ViewData *query)

{

        DB *dbp = NULL;

        struct ViewData stored;



        dbp = openDb();

        assert(user != NULL);

        memset(&stored, 0 ,sizeof(stored));

        user = trim(user);



        if(findViewInfo(dbp, user, &stored) == YES)

        {

                if(isHistoryViewInfo(query, &stored) == YES)

                {

                        printf("found %s\n",user);

                }

                else

                {

                        //printf("%s in db\n",user);

                        printf("not found %s\n",user);

                }

        }

        else

        {

                printf("%s not in db\n",user);

                printf("not found %s\n",user);

        }



        dbp->close(dbp, 0);

}





int main (int argc, char *argv[])

{

        int oc;

        extern char *optarg;

        extern int optind, opterr, optopt;



        char *from = NULL;

        char *to = NULL;



        struct ViewData viewData;

        memset(&viewData, 0, sizeof(viewData));



        while((oc=getopt(argc,argv,"f:s:t:")) != -1)

        {

                switch(oc)

                {

                        case 's':

                                setDate(&viewData,argv[optind]);

                                hasViewInfo(optarg, &viewData);

                                break;



                        case 'f':

                                from = optarg;

                                to = argv[optind++];

                                setDate(&viewData,argv[optind]);

                                saveViewFile(from, to, &viewData);

                                break;

                }

        }



        return 0;

}

 

我开始把ViewData写成了这样:

struct ViewData{

    char date[12];    

};



void setDate(char *date, char *s)

{

    assert(date != NULL && s!= NULL);

    strncpy(&date,s,12);

}



//call setDate

struct ViewData viewData;

memset(viewData,0,sizeof(viewData));

setDate(&viewData.date,"20130808");

 

后来还是觉得viewData直接存int更好:

struct ViewData{

    int date;    

};



void setDate(int *date, char *s)

{

    assert(date != NULL && s!= NULL);

    *date = atoi(s);

}



//call setDate

struct ViewData viewData;

memset(viewData,0,sizeof(viewData));

setDate(&viewData.date,"20130808");

 

看似没啥问题,但其实我已经暴露了ViewData的实现!

//call setDate

struct ViewData viewData;

memset(viewData,0,sizeof(viewData));

setDate(&viewData.date,"20130808");

//断言设置之后的日期等于20130808,用户这么写是因为已经暴露了ViewData的date是字符串这个事情!

assert(strcmp(viewData.date,"20130808")==0); 

那你说,不怎么写我想知道是不是设置成功了怎么办?

//call setDate

struct ViewData viewData;

memset(viewData,0,sizeof(viewData));

setDate(&viewData.date,"20130808");

//断言设置之后的日期等于20130808,这个函数由ViewData模块提供

verifyDate(&viewDate,"20130808");

 

你可能感兴趣的:(C语言)