dba_db3.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Copyright (c) The PHP Group |
  4. +----------------------------------------------------------------------+
  5. | This source file is subject to version 3.01 of the PHP license, |
  6. | that is bundled with this package in the file LICENSE, and is |
  7. | available through the world-wide-web at the following url: |
  8. | https://www.php.net/license/3_01.txt |
  9. | If you did not receive a copy of the PHP license and are unable to |
  10. | obtain it through the world-wide-web, please send a note to |
  11. | license@php.net so we can mail you a copy immediately. |
  12. +----------------------------------------------------------------------+
  13. | Author: Sascha Schumann <sascha@schumann.cx> |
  14. +----------------------------------------------------------------------+
  15. */
  16. #ifdef HAVE_CONFIG_H
  17. #include "config.h"
  18. #endif
  19. #include "php.h"
  20. #if DBA_DB3
  21. #include "php_db3.h"
  22. #include <sys/stat.h>
  23. #include <string.h>
  24. #ifdef DB3_INCLUDE_FILE
  25. #include DB3_INCLUDE_FILE
  26. #else
  27. #include <db.h>
  28. #endif
  29. static void php_dba_db3_errcall_fcn(
  30. #if (DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3))
  31. const DB_ENV *dbenv,
  32. #endif
  33. const char *errpfx, const char *msg)
  34. {
  35. php_error_docref(NULL, E_NOTICE, "%s%s", errpfx?errpfx:"", msg);
  36. }
  37. #define DB3_DATA dba_db3_data *dba = info->dbf
  38. #define DB3_GKEY \
  39. DBT gkey; \
  40. memset(&gkey, 0, sizeof(gkey)); \
  41. gkey.data = (char *) key; gkey.size = keylen
  42. typedef struct {
  43. DB *dbp;
  44. DBC *cursor;
  45. } dba_db3_data;
  46. DBA_OPEN_FUNC(db3)
  47. {
  48. DB *dbp = NULL;
  49. DBTYPE type;
  50. int gmode = 0, err;
  51. int filemode = 0644;
  52. struct stat check_stat;
  53. int s = VCWD_STAT(info->path, &check_stat);
  54. if (!s && !check_stat.st_size) {
  55. info->mode = DBA_TRUNC; /* force truncate */
  56. }
  57. type = info->mode == DBA_READER ? DB_UNKNOWN :
  58. info->mode == DBA_TRUNC ? DB_BTREE :
  59. s ? DB_BTREE : DB_UNKNOWN;
  60. gmode = info->mode == DBA_READER ? DB_RDONLY :
  61. (info->mode == DBA_CREAT && s) ? DB_CREATE :
  62. (info->mode == DBA_CREAT && !s) ? 0 :
  63. info->mode == DBA_WRITER ? 0 :
  64. info->mode == DBA_TRUNC ? DB_CREATE | DB_TRUNCATE : -1;
  65. if (gmode == -1) {
  66. return FAILURE; /* not possible */
  67. }
  68. if (info->argc > 0) {
  69. filemode = zval_get_long(&info->argv[0]);
  70. }
  71. #ifdef DB_FCNTL_LOCKING
  72. gmode |= DB_FCNTL_LOCKING;
  73. #endif
  74. if ((err=db_create(&dbp, NULL, 0)) == 0) {
  75. dbp->set_errcall(dbp, php_dba_db3_errcall_fcn);
  76. if(
  77. #if (DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1))
  78. (err=dbp->open(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) {
  79. #else
  80. (err=dbp->open(dbp, info->path, NULL, type, gmode, filemode)) == 0) {
  81. #endif
  82. dba_db3_data *data;
  83. data = pemalloc(sizeof(*data), info->flags&DBA_PERSISTENT);
  84. data->dbp = dbp;
  85. data->cursor = NULL;
  86. info->dbf = data;
  87. return SUCCESS;
  88. } else {
  89. dbp->close(dbp, 0);
  90. *error = db_strerror(err);
  91. }
  92. } else {
  93. *error = db_strerror(err);
  94. }
  95. return FAILURE;
  96. }
  97. DBA_CLOSE_FUNC(db3)
  98. {
  99. DB3_DATA;
  100. if (dba->cursor) dba->cursor->c_close(dba->cursor);
  101. dba->dbp->close(dba->dbp, 0);
  102. pefree(dba, info->flags&DBA_PERSISTENT);
  103. }
  104. DBA_FETCH_FUNC(db3)
  105. {
  106. DBT gval;
  107. char *new = NULL;
  108. DB3_DATA;
  109. DB3_GKEY;
  110. memset(&gval, 0, sizeof(gval));
  111. if (!dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) {
  112. if (newlen) *newlen = gval.size;
  113. new = estrndup(gval.data, gval.size);
  114. }
  115. return new;
  116. }
  117. DBA_UPDATE_FUNC(db3)
  118. {
  119. DBT gval;
  120. DB3_DATA;
  121. DB3_GKEY;
  122. memset(&gval, 0, sizeof(gval));
  123. gval.data = (char *) val;
  124. gval.size = vallen;
  125. if (!dba->dbp->put(dba->dbp, NULL, &gkey, &gval,
  126. mode == 1 ? DB_NOOVERWRITE : 0)) {
  127. return SUCCESS;
  128. }
  129. return FAILURE;
  130. }
  131. DBA_EXISTS_FUNC(db3)
  132. {
  133. DBT gval;
  134. DB3_DATA;
  135. DB3_GKEY;
  136. memset(&gval, 0, sizeof(gval));
  137. if (!dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) {
  138. return SUCCESS;
  139. }
  140. return FAILURE;
  141. }
  142. DBA_DELETE_FUNC(db3)
  143. {
  144. DB3_DATA;
  145. DB3_GKEY;
  146. return dba->dbp->del(dba->dbp, NULL, &gkey, 0) ? FAILURE : SUCCESS;
  147. }
  148. DBA_FIRSTKEY_FUNC(db3)
  149. {
  150. DB3_DATA;
  151. if (dba->cursor) {
  152. dba->cursor->c_close(dba->cursor);
  153. }
  154. dba->cursor = NULL;
  155. if (dba->dbp->cursor(dba->dbp, NULL, &dba->cursor, 0) != 0) {
  156. return NULL;
  157. }
  158. /* we should introduce something like PARAM_PASSTHRU... */
  159. return dba_nextkey_db3(info, newlen);
  160. }
  161. DBA_NEXTKEY_FUNC(db3)
  162. {
  163. DB3_DATA;
  164. DBT gkey, gval;
  165. char *nkey = NULL;
  166. memset(&gkey, 0, sizeof(gkey));
  167. memset(&gval, 0, sizeof(gval));
  168. if (dba->cursor->c_get(dba->cursor, &gkey, &gval, DB_NEXT) == 0) {
  169. if (gkey.data) {
  170. nkey = estrndup(gkey.data, gkey.size);
  171. if (newlen) *newlen = gkey.size;
  172. }
  173. }
  174. return nkey;
  175. }
  176. DBA_OPTIMIZE_FUNC(db3)
  177. {
  178. return SUCCESS;
  179. }
  180. DBA_SYNC_FUNC(db3)
  181. {
  182. DB3_DATA;
  183. return dba->dbp->sync(dba->dbp, 0) ? FAILURE : SUCCESS;
  184. }
  185. DBA_INFO_FUNC(db3)
  186. {
  187. return estrdup(DB_VERSION_STRING);
  188. }
  189. #endif