1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 6 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2009 The PHP Group |
6 : +----------------------------------------------------------------------+
7 : | This source file is subject to version 3.01 of the PHP license, |
8 : | that is bundled with this package in the file LICENSE, and is |
9 : | available through the world-wide-web at the following url: |
10 : | http://www.php.net/license/3_01.txt |
11 : | If you did not receive a copy of the PHP license and are unable to |
12 : | obtain it through the world-wide-web, please send a note to |
13 : | license@php.net so we can mail you a copy immediately. |
14 : +----------------------------------------------------------------------+
15 : | Author: Sascha Schumann <sascha@schumann.cx> |
16 : +----------------------------------------------------------------------+
17 : */
18 :
19 : /* $Id: dba_gdbm.c 276986 2009-03-10 23:40:06Z helly $ */
20 :
21 : #ifdef HAVE_CONFIG_H
22 : #include "config.h"
23 : #endif
24 :
25 : #include "php.h"
26 :
27 : #if DBA_GDBM
28 : #include "php_gdbm.h"
29 :
30 : #ifdef GDBM_INCLUDE_FILE
31 : #include GDBM_INCLUDE_FILE
32 : #endif
33 :
34 : #define GDBM_DATA dba_gdbm_data *dba = info->dbf
35 : #define GDBM_GKEY datum gkey; gkey.dptr = (char *) key; gkey.dsize = keylen
36 :
37 : typedef struct {
38 : GDBM_FILE dbf;
39 : datum nextkey;
40 : } dba_gdbm_data;
41 :
42 : DBA_OPEN_FUNC(gdbm)
43 5 : {
44 : GDBM_FILE dbf;
45 5 : int gmode = 0;
46 5 : int filemode = 0644;
47 :
48 5 : gmode = info->mode == DBA_READER ? GDBM_READER :
49 : info->mode == DBA_WRITER ? GDBM_WRITER :
50 : info->mode == DBA_CREAT ? GDBM_WRCREAT :
51 : info->mode == DBA_TRUNC ? GDBM_NEWDB : -1;
52 :
53 5 : if(gmode == -1)
54 0 : return FAILURE; /* not possible */
55 :
56 5 : if(info->argc > 0) {
57 0 : convert_to_long_ex(info->argv[0]);
58 0 : filemode = Z_LVAL_PP(info->argv[0]);
59 : }
60 :
61 5 : dbf = gdbm_open(info->path, 0, gmode, filemode, NULL);
62 :
63 5 : if(dbf) {
64 4 : info->dbf = pemalloc(sizeof(dba_gdbm_data), info->flags&DBA_PERSISTENT);
65 4 : memset(info->dbf, 0, sizeof(dba_gdbm_data));
66 4 : ((dba_gdbm_data *) info->dbf)->dbf = dbf;
67 4 : return SUCCESS;
68 : }
69 1 : *error = gdbm_strerror(gdbm_errno);
70 1 : return FAILURE;
71 : }
72 :
73 : DBA_CLOSE_FUNC(gdbm)
74 4 : {
75 4 : GDBM_DATA;
76 :
77 4 : if(dba->nextkey.dptr) free(dba->nextkey.dptr);
78 4 : gdbm_close(dba->dbf);
79 4 : pefree(dba, info->flags&DBA_PERSISTENT);
80 4 : }
81 :
82 : DBA_FETCH_FUNC(gdbm)
83 7 : {
84 7 : GDBM_DATA;
85 : datum gval;
86 7 : char *new = NULL;
87 :
88 7 : GDBM_GKEY;
89 7 : gval = gdbm_fetch(dba->dbf, gkey);
90 7 : if(gval.dptr) {
91 7 : if(newlen) *newlen = gval.dsize;
92 7 : new = estrndup(gval.dptr, gval.dsize);
93 7 : free(gval.dptr);
94 : }
95 7 : return new;
96 : }
97 :
98 : DBA_UPDATE_FUNC(gdbm)
99 9 : {
100 : datum gval;
101 9 : GDBM_DATA;
102 :
103 9 : GDBM_GKEY;
104 9 : gval.dptr = (char *) val;
105 9 : gval.dsize = vallen;
106 :
107 9 : if(gdbm_store(dba->dbf, gkey, gval,
108 : mode == 1 ? GDBM_INSERT : GDBM_REPLACE) == 0)
109 8 : return SUCCESS;
110 1 : php_error_docref2(NULL TSRMLS_CC, key, val, E_WARNING, "%s", gdbm_strerror(gdbm_errno));
111 1 : return FAILURE;
112 : }
113 :
114 : DBA_EXISTS_FUNC(gdbm)
115 5 : {
116 5 : GDBM_DATA;
117 5 : GDBM_GKEY;
118 :
119 5 : return gdbm_exists(dba->dbf, gkey) ? SUCCESS : FAILURE;
120 : }
121 :
122 : DBA_DELETE_FUNC(gdbm)
123 3 : {
124 3 : GDBM_DATA;
125 3 : GDBM_GKEY;
126 :
127 3 : return gdbm_delete(dba->dbf, gkey) == -1 ? FAILURE : SUCCESS;
128 : }
129 :
130 : DBA_FIRSTKEY_FUNC(gdbm)
131 2 : {
132 2 : GDBM_DATA;
133 : datum gkey;
134 2 : char *key = NULL;
135 :
136 2 : if(dba->nextkey.dptr) {
137 0 : free(dba->nextkey.dptr);
138 : }
139 :
140 2 : gkey = gdbm_firstkey(dba->dbf);
141 2 : if(gkey.dptr) {
142 2 : key = estrndup(gkey.dptr, gkey.dsize);
143 2 : if(newlen) *newlen = gkey.dsize;
144 2 : dba->nextkey = gkey;
145 : } else {
146 0 : dba->nextkey.dptr = NULL;
147 : }
148 2 : return key;
149 : }
150 :
151 : DBA_NEXTKEY_FUNC(gdbm)
152 6 : {
153 6 : GDBM_DATA;
154 6 : char *nkey = NULL;
155 : datum gkey;
156 :
157 6 : if(!dba->nextkey.dptr) return NULL;
158 :
159 6 : gkey = gdbm_nextkey(dba->dbf, dba->nextkey);
160 6 : free(dba->nextkey.dptr);
161 6 : if(gkey.dptr) {
162 4 : nkey = estrndup(gkey.dptr, gkey.dsize);
163 4 : if(newlen) *newlen = gkey.dsize;
164 4 : dba->nextkey = gkey;
165 : } else {
166 2 : dba->nextkey.dptr = NULL;
167 : }
168 6 : return nkey;
169 : }
170 :
171 : DBA_OPTIMIZE_FUNC(gdbm)
172 0 : {
173 0 : GDBM_DATA;
174 0 : gdbm_reorganize(dba->dbf);
175 0 : return SUCCESS;
176 : }
177 :
178 : DBA_SYNC_FUNC(gdbm)
179 0 : {
180 0 : GDBM_DATA;
181 :
182 0 : gdbm_sync(dba->dbf);
183 0 : return SUCCESS;
184 : }
185 :
186 : DBA_INFO_FUNC(gdbm)
187 0 : {
188 0 : return estrdup(gdbm_version);
189 : }
190 :
191 : #endif
192 :
193 : /*
194 : * Local variables:
195 : * tab-width: 4
196 : * c-basic-offset: 4
197 : * End:
198 : * vim600: sw=4 ts=4 fdm=marker
199 : * vim<600: sw=4 ts=4
200 : */
|