xref: /PHP-5.3/ext/dba/dba_gdbm.c (revision a2045ff3)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 5                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2013 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$ */
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 
DBA_OPEN_FUNC(gdbm)42 DBA_OPEN_FUNC(gdbm)
43 {
44 	GDBM_FILE dbf;
45 	int gmode = 0;
46 	int filemode = 0644;
47 
48 	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 	if(gmode == -1)
54 		return FAILURE; /* not possible */
55 
56 	if(info->argc > 0) {
57 		convert_to_long_ex(info->argv[0]);
58 		filemode = Z_LVAL_PP(info->argv[0]);
59 	}
60 
61 	dbf = gdbm_open(info->path, 0, gmode, filemode, NULL);
62 
63 	if(dbf) {
64 		info->dbf = pemalloc(sizeof(dba_gdbm_data), info->flags&DBA_PERSISTENT);
65 		memset(info->dbf, 0, sizeof(dba_gdbm_data));
66 		((dba_gdbm_data *) info->dbf)->dbf = dbf;
67 		return SUCCESS;
68 	}
69 	*error = gdbm_strerror(gdbm_errno);
70 	return FAILURE;
71 }
72 
DBA_CLOSE_FUNC(gdbm)73 DBA_CLOSE_FUNC(gdbm)
74 {
75 	GDBM_DATA;
76 
77 	if(dba->nextkey.dptr) free(dba->nextkey.dptr);
78 	gdbm_close(dba->dbf);
79 	pefree(dba, info->flags&DBA_PERSISTENT);
80 }
81 
DBA_FETCH_FUNC(gdbm)82 DBA_FETCH_FUNC(gdbm)
83 {
84 	GDBM_DATA;
85 	datum gval;
86 	char *new = NULL;
87 
88 	GDBM_GKEY;
89 	gval = gdbm_fetch(dba->dbf, gkey);
90 	if(gval.dptr) {
91 		if(newlen) *newlen = gval.dsize;
92 		new = estrndup(gval.dptr, gval.dsize);
93 		free(gval.dptr);
94 	}
95 	return new;
96 }
97 
DBA_UPDATE_FUNC(gdbm)98 DBA_UPDATE_FUNC(gdbm)
99 {
100 	datum gval;
101 	GDBM_DATA;
102 
103 	GDBM_GKEY;
104 	gval.dptr = (char *) val;
105 	gval.dsize = vallen;
106 
107 	if(gdbm_store(dba->dbf, gkey, gval,
108 				mode == 1 ? GDBM_INSERT : GDBM_REPLACE) == 0)
109 		return SUCCESS;
110 	php_error_docref2(NULL TSRMLS_CC, key, val, E_WARNING, "%s", gdbm_strerror(gdbm_errno));
111 	return FAILURE;
112 }
113 
DBA_EXISTS_FUNC(gdbm)114 DBA_EXISTS_FUNC(gdbm)
115 {
116 	GDBM_DATA;
117 	GDBM_GKEY;
118 
119 	return gdbm_exists(dba->dbf, gkey) ? SUCCESS : FAILURE;
120 }
121 
DBA_DELETE_FUNC(gdbm)122 DBA_DELETE_FUNC(gdbm)
123 {
124 	GDBM_DATA;
125 	GDBM_GKEY;
126 
127 	return gdbm_delete(dba->dbf, gkey) == -1 ? FAILURE : SUCCESS;
128 }
129 
DBA_FIRSTKEY_FUNC(gdbm)130 DBA_FIRSTKEY_FUNC(gdbm)
131 {
132 	GDBM_DATA;
133 	datum gkey;
134 	char *key = NULL;
135 
136 	if(dba->nextkey.dptr) {
137 		free(dba->nextkey.dptr);
138 	}
139 
140 	gkey = gdbm_firstkey(dba->dbf);
141 	if(gkey.dptr) {
142 		key = estrndup(gkey.dptr, gkey.dsize);
143 		if(newlen) *newlen = gkey.dsize;
144 		dba->nextkey = gkey;
145 	} else {
146 		dba->nextkey.dptr = NULL;
147 	}
148 	return key;
149 }
150 
DBA_NEXTKEY_FUNC(gdbm)151 DBA_NEXTKEY_FUNC(gdbm)
152 {
153 	GDBM_DATA;
154 	char *nkey = NULL;
155 	datum gkey;
156 
157 	if(!dba->nextkey.dptr) return NULL;
158 
159 	gkey = gdbm_nextkey(dba->dbf, dba->nextkey);
160 	free(dba->nextkey.dptr);
161 	if(gkey.dptr) {
162 		nkey = estrndup(gkey.dptr, gkey.dsize);
163 		if(newlen) *newlen = gkey.dsize;
164 		dba->nextkey = gkey;
165 	} else {
166 		dba->nextkey.dptr = NULL;
167 	}
168 	return nkey;
169 }
170 
DBA_OPTIMIZE_FUNC(gdbm)171 DBA_OPTIMIZE_FUNC(gdbm)
172 {
173 	GDBM_DATA;
174 	gdbm_reorganize(dba->dbf);
175 	return SUCCESS;
176 }
177 
DBA_SYNC_FUNC(gdbm)178 DBA_SYNC_FUNC(gdbm)
179 {
180 	GDBM_DATA;
181 
182 	gdbm_sync(dba->dbf);
183 	return SUCCESS;
184 }
185 
DBA_INFO_FUNC(gdbm)186 DBA_INFO_FUNC(gdbm)
187 {
188 	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  */
201