1 /*************************************************************************************************
2 * The skeleton database library working as a directory database
3 * Copyright (C) 2006-2010 FAL Labs
4 * This file is part of Tokyo Tyrant.
5 * Tokyo Tyrant is free software; you can redistribute it and/or modify it under the terms of
6 * the GNU Lesser General Public License as published by the Free Software Foundation; either
7 * version 2.1 of the License or any later version. Tokyo Tyrant is distributed in the hope
8 * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
10 * License for more details.
11 * You should have received a copy of the GNU Lesser General Public License along with Tokyo
12 * Tyrant; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
13 * Boston, MA 02111-1307 USA.
14 *************************************************************************************************/
15
16
17 #include <tcutil.h>
18 #include <tcadb.h>
19 #include <stdlib.h>
20 #include <stdbool.h>
21 #include <stdint.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25 #include <pthread.h>
26
27
28 typedef struct { /* type of structure for a directory database */
29 char *name; /* name of the directory */
30 } TCDDB;
31
32
33 /* private funciton prototypes */
34 static TCDDB *tcddbnew(void);
35 static void tcddbdel(TCDDB *ddb);
36 static bool tcddbopen(TCDDB *ddb, const char *name);
37 static bool tcddbclose(TCDDB *ddb);
38 static bool tcddbput(TCDDB *ddb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
39 static bool tcddbout(TCDDB *ddb, const void *kbuf, int ksiz);
40 static void *tcddbget(TCDDB *ddb, const void *kbuf, int ksiz, int *sp);
41 static char *makepath(TCDDB *ddb, const void *kbuf, int ksiz);
42
43
44
45 /*************************************************************************************************
46 * API
47 *************************************************************************************************/
48
49
initialize(ADBSKEL * skel)50 bool initialize(ADBSKEL *skel){
51 skel->opq = tcddbnew();
52 skel->del = (void (*)(void *))tcddbdel;
53 skel->open = (bool (*)(void *, const char *))tcddbopen;
54 skel->close = (bool (*)(void *))tcddbclose;
55 skel->put = (bool (*)(void *, const void *, int, const void *, int))tcddbput;
56 skel->out = (bool (*)(void *, const void *, int))tcddbout;
57 skel->get = (void *(*)(void *, const void *, int, int *))tcddbget;
58 return true;
59 }
60
61
62
63 /*************************************************************************************************
64 * private features
65 *************************************************************************************************/
66
67
tcddbnew(void)68 static TCDDB *tcddbnew(void){
69 TCDDB *ddb = tcmalloc(sizeof(*ddb));
70 ddb->name = NULL;
71 return ddb;
72 }
73
74
tcddbdel(TCDDB * ddb)75 static void tcddbdel(TCDDB *ddb){
76 if(ddb->name) tcddbclose(ddb);
77 tcfree(ddb);
78 }
79
80
tcddbopen(TCDDB * ddb,const char * name)81 static bool tcddbopen(TCDDB *ddb, const char *name){
82 if(ddb->name) return false;
83 struct stat sbuf;
84 if(stat(name, &sbuf) == 0){
85 if(!S_ISDIR(sbuf.st_mode)) return false;
86 } else {
87 if(mkdir(name, 0755) != 0) return false;
88 }
89 ddb->name = tcstrdup(name);
90 return true;
91 }
92
93
tcddbclose(TCDDB * ddb)94 static bool tcddbclose(TCDDB *ddb){
95 if(!ddb->name) return false;
96 tcfree(ddb->name);
97 ddb->name = NULL;
98 return true;
99 }
100
101
tcddbput(TCDDB * ddb,const void * kbuf,int ksiz,const void * vbuf,int vsiz)102 static bool tcddbput(TCDDB *ddb, const void *kbuf, int ksiz, const void *vbuf, int vsiz){
103 if(!ddb->name) return false;
104 bool err = false;
105 char *path = makepath(ddb, kbuf, ksiz);
106 if(!tcwritefile(path, vbuf, vsiz)) err = true;
107 tcfree(path);
108 return !err;
109 }
110
111
tcddbout(TCDDB * ddb,const void * kbuf,int ksiz)112 static bool tcddbout(TCDDB *ddb, const void *kbuf, int ksiz){
113 if(!ddb->name) return false;
114 bool err = false;
115 char *path = makepath(ddb, kbuf, ksiz);
116 if(unlink(path) != 0) err = true;
117 tcfree(path);
118 return !err;
119 }
120
121
tcddbget(TCDDB * ddb,const void * kbuf,int ksiz,int * sp)122 static void *tcddbget(TCDDB *ddb, const void *kbuf, int ksiz, int *sp){
123 if(!ddb->name) return false;
124 void *vbuf;
125 char *path = makepath(ddb, kbuf, ksiz);
126 vbuf = tcreadfile(path, -1, sp);
127 tcfree(path);
128 return vbuf;
129 }
130
131
makepath(TCDDB * ddb,const void * kbuf,int ksiz)132 static char *makepath(TCDDB *ddb, const void *kbuf, int ksiz){
133 char *uenc = tcurlencode(kbuf, ksiz);
134 char *path = tcsprintf("%s/%s", ddb->name, uenc);
135 tcfree(uenc);
136 return path;
137 }
138
139
140
141 // END OF FILE
142