dba_db2.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  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_DB2
  21. #include "php_db2.h"
  22. #include <sys/stat.h>
  23. #include <string.h>
  24. #ifdef DB2_INCLUDE_FILE
  25. #include DB2_INCLUDE_FILE
  26. #endif
  27. #define DB2_DATA dba_db2_data *dba = info->dbf
  28. #define DB2_GKEY \
  29. DBT gkey = {0}; \
  30. gkey.data = (char *) key; \
  31. gkey.size = keylen
  32. typedef struct {
  33. DB *dbp;
  34. DBC *cursor;
  35. } dba_db2_data;
  36. DBA_OPEN_FUNC(db2)
  37. {
  38. DB *dbp;
  39. DBTYPE type;
  40. int gmode = 0;
  41. int filemode = 0644;
  42. struct stat check_stat;
  43. int s = VCWD_STAT(info->path, &check_stat);
  44. if (!s && !check_stat.st_size) {
  45. info->mode = DBA_TRUNC; /* force truncate */
  46. }
  47. type = info->mode == DBA_READER ? DB_UNKNOWN :
  48. info->mode == DBA_TRUNC ? DB_BTREE :
  49. s ? DB_BTREE : DB_UNKNOWN;
  50. gmode = info->mode == DBA_READER ? DB_RDONLY :
  51. (info->mode == DBA_CREAT && s) ? DB_CREATE :
  52. (info->mode == DBA_CREAT && !s) ? 0 :
  53. info->mode == DBA_WRITER ? 0 :
  54. info->mode == DBA_TRUNC ? DB_CREATE | DB_TRUNCATE : -1;
  55. if (gmode == -1) {
  56. return FAILURE;/* not possible */
  57. }
  58. if (info->argc > 0) {
  59. filemode = zval_get_long(&info->argv[0]);
  60. }
  61. if (db_open(info->path, type, gmode, filemode, NULL, NULL, &dbp)) {
  62. return FAILURE;
  63. }
  64. info->dbf = pemalloc(sizeof(dba_db2_data), info->flags&DBA_PERSISTENT);
  65. memset(info->dbf, 0, sizeof(dba_db2_data));
  66. ((dba_db2_data *) info->dbf)->dbp = dbp;
  67. return SUCCESS;
  68. }
  69. DBA_CLOSE_FUNC(db2)
  70. {
  71. DB2_DATA;
  72. if (dba->cursor)
  73. dba->cursor->c_close(dba->cursor);
  74. dba->dbp->close(dba->dbp, 0);
  75. pefree(dba, info->flags&DBA_PERSISTENT);
  76. }
  77. DBA_FETCH_FUNC(db2)
  78. {
  79. DBT gval = {0};
  80. DB2_DATA;
  81. DB2_GKEY;
  82. if (dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) {
  83. return NULL;
  84. }
  85. if (newlen) *newlen = gval.size;
  86. return estrndup(gval.data, gval.size);
  87. }
  88. DBA_UPDATE_FUNC(db2)
  89. {
  90. DBT gval = {0};
  91. DB2_DATA;
  92. DB2_GKEY;
  93. gval.data = (char *) val;
  94. gval.size = vallen;
  95. if (dba->dbp->put(dba->dbp, NULL, &gkey, &gval,
  96. mode == 1 ? DB_NOOVERWRITE : 0)) {
  97. return FAILURE;
  98. }
  99. return SUCCESS;
  100. }
  101. DBA_EXISTS_FUNC(db2)
  102. {
  103. DBT gval = {0};
  104. DB2_DATA;
  105. DB2_GKEY;
  106. if (dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) {
  107. return FAILURE;
  108. }
  109. return SUCCESS;
  110. }
  111. DBA_DELETE_FUNC(db2)
  112. {
  113. DB2_DATA;
  114. DB2_GKEY;
  115. return dba->dbp->del(dba->dbp, NULL, &gkey, 0) ? FAILURE : SUCCESS;
  116. }
  117. DBA_FIRSTKEY_FUNC(db2)
  118. {
  119. DB2_DATA;
  120. if (dba->cursor) {
  121. dba->cursor->c_close(dba->cursor);
  122. dba->cursor = NULL;
  123. }
  124. #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)
  125. if (dba->dbp->cursor(dba->dbp, NULL, &dba->cursor, 0)) {
  126. #else
  127. if (dba->dbp->cursor(dba->dbp, NULL, &dba->cursor)) {
  128. #endif
  129. return NULL;
  130. }
  131. /* we should introduce something like PARAM_PASSTHRU... */
  132. return dba_nextkey_db2(info, newlen);
  133. }
  134. DBA_NEXTKEY_FUNC(db2)
  135. {
  136. DB2_DATA;
  137. DBT gkey = {0}, gval = {0};
  138. if (dba->cursor->c_get(dba->cursor, &gkey, &gval, DB_NEXT)
  139. || !gkey.data)
  140. return NULL;
  141. if (newlen) *newlen = gkey.size;
  142. return estrndup(gkey.data, gkey.size);
  143. }
  144. DBA_OPTIMIZE_FUNC(db2)
  145. {
  146. return SUCCESS;
  147. }
  148. DBA_SYNC_FUNC(db2)
  149. {
  150. DB2_DATA;
  151. return dba->dbp->sync(dba->dbp, 0) ? FAILURE : SUCCESS;
  152. }
  153. DBA_INFO_FUNC(db2)
  154. {
  155. return estrdup(DB_VERSION_STRING);
  156. }
  157. #endif