xref: /PHP-7.0/ext/dba/dba_db2.c (revision 478f119a)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 7                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2017 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_DB2
28 #include "php_db2.h"
29 #include <sys/stat.h>
30 
31 #include <string.h>
32 #ifdef DB2_INCLUDE_FILE
33 #include DB2_INCLUDE_FILE
34 #endif
35 
36 #define DB2_DATA dba_db2_data *dba = info->dbf
37 #define DB2_GKEY \
38 	DBT gkey = {0}; \
39 	gkey.data = (char *) key; \
40 	gkey.size = keylen
41 
42 typedef struct {
43 	DB *dbp;
44 	DBC *cursor;
45 } dba_db2_data;
46 
DBA_OPEN_FUNC(db2)47 DBA_OPEN_FUNC(db2)
48 {
49 	DB *dbp;
50 	DBTYPE type;
51 	int gmode = 0;
52 	int filemode = 0644;
53 	struct stat check_stat;
54 	int s = VCWD_STAT(info->path, &check_stat);
55 
56 	if (!s && !check_stat.st_size) {
57 		info->mode = DBA_TRUNC; /* force truncate */
58 	}
59 
60 	type = info->mode == DBA_READER ? DB_UNKNOWN :
61 		info->mode == DBA_TRUNC ? DB_BTREE :
62 		s ? DB_BTREE : DB_UNKNOWN;
63 
64 	gmode = info->mode == DBA_READER ? DB_RDONLY :
65 		(info->mode == DBA_CREAT && s) ? DB_CREATE :
66 		(info->mode == DBA_CREAT && !s) ? 0 :
67 		info->mode == DBA_WRITER ? 0         :
68 		info->mode == DBA_TRUNC ? DB_CREATE | DB_TRUNCATE : -1;
69 
70 	if (gmode == -1) {
71 		return FAILURE;/* not possible */
72 	}
73 
74 	if (info->argc > 0) {
75 		convert_to_long_ex(&info->argv[0]);
76 		filemode = Z_LVAL(info->argv[0]);
77 	}
78 
79 	if (db_open(info->path, type, gmode, filemode, NULL, NULL, &dbp)) {
80 		return FAILURE;
81 	}
82 
83 	info->dbf = pemalloc(sizeof(dba_db2_data), info->flags&DBA_PERSISTENT);
84 	memset(info->dbf, 0, sizeof(dba_db2_data));
85 	((dba_db2_data *) info->dbf)->dbp = dbp;
86 	return SUCCESS;
87 }
88 
DBA_CLOSE_FUNC(db2)89 DBA_CLOSE_FUNC(db2)
90 {
91 	DB2_DATA;
92 
93 	if (dba->cursor)
94 		dba->cursor->c_close(dba->cursor);
95 	dba->dbp->close(dba->dbp, 0);
96 	pefree(dba, info->flags&DBA_PERSISTENT);
97 }
98 
DBA_FETCH_FUNC(db2)99 DBA_FETCH_FUNC(db2)
100 {
101 	DBT gval = {0};
102 	DB2_DATA;
103 	DB2_GKEY;
104 
105 	if (dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) {
106 		return NULL;
107 	}
108 
109 	if (newlen) *newlen = gval.size;
110 	return estrndup(gval.data, gval.size);
111 }
112 
DBA_UPDATE_FUNC(db2)113 DBA_UPDATE_FUNC(db2)
114 {
115 	DBT gval = {0};
116 	DB2_DATA;
117 	DB2_GKEY;
118 
119 	gval.data = (char *) val;
120 	gval.size = vallen;
121 
122 	if (dba->dbp->put(dba->dbp, NULL, &gkey, &gval,
123 				mode == 1 ? DB_NOOVERWRITE : 0)) {
124 		return FAILURE;
125 	}
126 	return SUCCESS;
127 }
128 
DBA_EXISTS_FUNC(db2)129 DBA_EXISTS_FUNC(db2)
130 {
131 	DBT gval = {0};
132 	DB2_DATA;
133 	DB2_GKEY;
134 
135 	if (dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) {
136 		return FAILURE;
137 	}
138 	return SUCCESS;
139 }
140 
DBA_DELETE_FUNC(db2)141 DBA_DELETE_FUNC(db2)
142 {
143 	DB2_DATA;
144 	DB2_GKEY;
145 
146 	return dba->dbp->del(dba->dbp, NULL, &gkey, 0) ? FAILURE : SUCCESS;
147 }
148 
DBA_FIRSTKEY_FUNC(db2)149 DBA_FIRSTKEY_FUNC(db2)
150 {
151 	DB2_DATA;
152 
153 	if (dba->cursor) {
154 		dba->cursor->c_close(dba->cursor);
155 		dba->cursor = NULL;
156 	}
157 
158 #if (DB_VERSION_MAJOR > 2) || (DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR > 6) || (DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR == 6 && DB_VERSION_PATCH >= 4)
159 	if (dba->dbp->cursor(dba->dbp, NULL, &dba->cursor, 0)) {
160 #else
161 	if (dba->dbp->cursor(dba->dbp, NULL, &dba->cursor)) {
162 #endif
163 		return NULL;
164 	}
165 
166 	/* we should introduce something like PARAM_PASSTHRU... */
167 	return dba_nextkey_db2(info, newlen);
168 }
169 
170 DBA_NEXTKEY_FUNC(db2)
171 {
172 	DB2_DATA;
173 	DBT gkey = {0}, gval = {0};
174 
175 	if (dba->cursor->c_get(dba->cursor, &gkey, &gval, DB_NEXT)
176 			|| !gkey.data)
177 		return NULL;
178 
179 	if (newlen) *newlen = gkey.size;
180 	return estrndup(gkey.data, gkey.size);
181 }
182 
183 DBA_OPTIMIZE_FUNC(db2)
184 {
185 	return SUCCESS;
186 }
187 
188 DBA_SYNC_FUNC(db2)
189 {
190 	DB2_DATA;
191 
192 	return dba->dbp->sync(dba->dbp, 0) ? FAILURE : SUCCESS;
193 }
194 
195 DBA_INFO_FUNC(db2)
196 {
197 	return estrdup(DB_VERSION_STRING);
198 }
199 
200 #endif
201 
202 /*
203  * Local variables:
204  * tab-width: 4
205  * c-basic-offset: 4
206  * End:
207  * vim600: sw=4 ts=4 fdm=marker
208  * vim<600: sw=4 ts=4
209  */
210