summaryrefslogtreecommitdiffstats
path: root/src/rccdb4.c
blob: 5e0894a989712759a21db931df7e1cf552ad3262 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <stdio.h>

#include "internal.h"
#include "rccdb4.h"

#define DATABASE "autolearn.db"
#define MIN_CHARS 3

int rccInitDb4(rcc_context ctx, const char *name, rcc_db4_flags flags) {
    size_t size;
    char *dbname;
    
    if (!ctx) {
	if (rcc_default_ctx) ctx = rcc_default_ctx;
	else return -1;
    }

    if (!name) name = "default";

    size = strlen(rcc_home_dir) + strlen(name) + 32;
    dbname = (char*)malloc(size*sizeof(char));
    if (!dbname) return -1;

    sprintf(dbname,"%s/.rcc/",rcc_home_dir);
    mkdir(dbname, 00644);
    
    sprintf(dbname,"%s/.rcc/%s.db/",rcc_home_dir,name);
    mkdir(dbname, 00644);

    ctx->db4ctx = rccDb4CreateContext(dbname, flags);
    free(dbname);	
    
    if (!ctx->db4ctx) return -1;

    return 0;
}

db4_context rccDb4CreateContext(const char *dbpath, rcc_db4_flags flags) {
    int err;
    db4_context ctx;
    DB_ENV *dbe;
    DB *db;
    
    err = db_env_create(&dbe, 0);
    if (err) return NULL;
    
    err = dbe->open(dbe, dbpath, DB_CREATE|DB_INIT_CDB|DB_INIT_MPOOL, 0);
    if (err) {
	dbe->close(dbe, 0);
	return NULL;
    }
    
    err = db_create(&db, dbe, 0);
    if (err) {
	dbe->close(dbe, 0);
	return NULL;
    }
    
    err = db->open(db, NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0);
    if (err) {
	db->close(db, 0);
	dbe->close(dbe, 0);
	return NULL;
    } 

    ctx = (db4_context)malloc(sizeof(db4_context_s));
    if (!ctx) {
    	db->close(db, 0);
	dbe->close(dbe, 0);
	return NULL;
    }
    
    ctx->db = db;
    ctx->dbe = dbe;
    ctx->flags = flags;
    return ctx;
}

void rccDb4FreeContext(db4_context ctx) {
    if (ctx) {
	ctx->db->close(ctx->db, 0);
	ctx->dbe->close(ctx->dbe, 0);
	free(ctx);
    }
}

int rccDb4SetKey(db4_context ctx, const char *orig, size_t olen, const rcc_string string) {
    int err;
    DBT key, data;

    if ((!ctx)||(!orig)||(!string)) return -1;
    
    memset(&key, 0, sizeof(key));
    memset(&data, 0, sizeof(data));
    
    key.data = (char*)orig;
    key.size = STRNLEN(orig, olen); /* No ending zero */
    data.data = (char*)string;
    data.size = strlen(string)+1;
    
    if (key.size < MIN_CHARS) return -1;
    
    err = ctx->db->put(ctx->db, NULL, &key, &data, 0);
    return err;
}

rcc_string rccDb4GetKey(db4_context ctx, const char *orig, size_t olen) {
    int err;
    DBT key, data;

    if ((!ctx)||(!orig)) return NULL;

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

    key.data = (char*)orig;
    key.size = STRNLEN(orig, olen); /* No ending zero */

    data.flags = DB_DBT_REALLOC;
    
    err = ctx->db->get(ctx->db, NULL, &key, &data, 0);
    if (err) return NULL;
    return data.data;
}