Annotation of embedaddon/php/ext/pdo_sqlite/sqlite_statement.c, revision 1.1
1.1 ! misho 1: /*
! 2: +----------------------------------------------------------------------+
! 3: | PHP Version 5 |
! 4: +----------------------------------------------------------------------+
! 5: | Copyright (c) 1997-2012 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: Wez Furlong <wez@php.net> |
! 16: +----------------------------------------------------------------------+
! 17: */
! 18:
! 19: /* $Id: sqlite_statement.c 321634 2012-01-01 13:15:04Z felipe $ */
! 20:
! 21: #ifdef HAVE_CONFIG_H
! 22: #include "config.h"
! 23: #endif
! 24:
! 25: #include "php.h"
! 26: #include "php_ini.h"
! 27: #include "ext/standard/info.h"
! 28: #include "pdo/php_pdo.h"
! 29: #include "pdo/php_pdo_driver.h"
! 30: #include "php_pdo_sqlite.h"
! 31: #include "php_pdo_sqlite_int.h"
! 32:
! 33:
! 34: static int pdo_sqlite_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
! 35: {
! 36: pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
! 37:
! 38: if (S->stmt) {
! 39: sqlite3_finalize(S->stmt);
! 40: S->stmt = NULL;
! 41: }
! 42: efree(S);
! 43: return 1;
! 44: }
! 45:
! 46: static int pdo_sqlite_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
! 47: {
! 48: pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
! 49:
! 50: if (stmt->executed && !S->done) {
! 51: sqlite3_reset(S->stmt);
! 52: }
! 53:
! 54: S->done = 0;
! 55: switch (sqlite3_step(S->stmt)) {
! 56: case SQLITE_ROW:
! 57: S->pre_fetched = 1;
! 58: stmt->column_count = sqlite3_data_count(S->stmt);
! 59: return 1;
! 60:
! 61: case SQLITE_DONE:
! 62: stmt->column_count = sqlite3_column_count(S->stmt);
! 63: stmt->row_count = sqlite3_changes(S->H->db);
! 64: sqlite3_reset(S->stmt);
! 65: S->done = 1;
! 66: return 1;
! 67:
! 68: case SQLITE_ERROR:
! 69: sqlite3_reset(S->stmt);
! 70: case SQLITE_MISUSE:
! 71: case SQLITE_BUSY:
! 72: default:
! 73: pdo_sqlite_error_stmt(stmt);
! 74: return 0;
! 75: }
! 76: }
! 77:
! 78: static int pdo_sqlite_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
! 79: enum pdo_param_event event_type TSRMLS_DC)
! 80: {
! 81: pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
! 82:
! 83: switch (event_type) {
! 84: case PDO_PARAM_EVT_EXEC_PRE:
! 85: if (stmt->executed && !S->done) {
! 86: sqlite3_reset(S->stmt);
! 87: S->done = 1;
! 88: }
! 89:
! 90: if (param->is_param) {
! 91:
! 92: if (param->paramno == -1) {
! 93: param->paramno = sqlite3_bind_parameter_index(S->stmt, param->name) - 1;
! 94: }
! 95:
! 96: switch (PDO_PARAM_TYPE(param->param_type)) {
! 97: case PDO_PARAM_STMT:
! 98: return 0;
! 99:
! 100: case PDO_PARAM_NULL:
! 101: if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
! 102: return 1;
! 103: }
! 104: pdo_sqlite_error_stmt(stmt);
! 105: return 0;
! 106:
! 107: case PDO_PARAM_INT:
! 108: case PDO_PARAM_BOOL:
! 109: if (Z_TYPE_P(param->parameter) == IS_NULL) {
! 110: if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
! 111: return 1;
! 112: }
! 113: } else {
! 114: convert_to_long(param->parameter);
! 115: if (SQLITE_OK == sqlite3_bind_int(S->stmt, param->paramno + 1, Z_LVAL_P(param->parameter))) {
! 116: return 1;
! 117: }
! 118: }
! 119: pdo_sqlite_error_stmt(stmt);
! 120: return 0;
! 121:
! 122: case PDO_PARAM_LOB:
! 123: if (Z_TYPE_P(param->parameter) == IS_RESOURCE) {
! 124: php_stream *stm;
! 125: php_stream_from_zval_no_verify(stm, ¶m->parameter);
! 126: if (stm) {
! 127: SEPARATE_ZVAL(¶m->parameter);
! 128: Z_TYPE_P(param->parameter) = IS_STRING;
! 129: Z_STRLEN_P(param->parameter) = php_stream_copy_to_mem(stm,
! 130: &Z_STRVAL_P(param->parameter), PHP_STREAM_COPY_ALL, 0);
! 131: } else {
! 132: pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource" TSRMLS_CC);
! 133: return 0;
! 134: }
! 135: } else if (Z_TYPE_P(param->parameter) == IS_NULL) {
! 136: if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
! 137: return 1;
! 138: }
! 139: pdo_sqlite_error_stmt(stmt);
! 140: return 0;
! 141: } else {
! 142: convert_to_string(param->parameter);
! 143: }
! 144:
! 145: if (SQLITE_OK == sqlite3_bind_blob(S->stmt, param->paramno + 1,
! 146: Z_STRVAL_P(param->parameter),
! 147: Z_STRLEN_P(param->parameter),
! 148: SQLITE_STATIC)) {
! 149: return 1;
! 150: }
! 151: pdo_sqlite_error_stmt(stmt);
! 152: return 0;
! 153:
! 154: case PDO_PARAM_STR:
! 155: default:
! 156: if (Z_TYPE_P(param->parameter) == IS_NULL) {
! 157: if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
! 158: return 1;
! 159: }
! 160: } else {
! 161: convert_to_string(param->parameter);
! 162: if(SQLITE_OK == sqlite3_bind_text(S->stmt, param->paramno + 1,
! 163: Z_STRVAL_P(param->parameter),
! 164: Z_STRLEN_P(param->parameter),
! 165: SQLITE_STATIC)) {
! 166: return 1;
! 167: }
! 168: }
! 169: pdo_sqlite_error_stmt(stmt);
! 170: return 0;
! 171: }
! 172: }
! 173: break;
! 174:
! 175: default:
! 176: ;
! 177: }
! 178: return 1;
! 179: }
! 180:
! 181: static int pdo_sqlite_stmt_fetch(pdo_stmt_t *stmt,
! 182: enum pdo_fetch_orientation ori, long offset TSRMLS_DC)
! 183: {
! 184: pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
! 185: int i;
! 186: if (!S->stmt) {
! 187: return 0;
! 188: }
! 189: if (S->pre_fetched) {
! 190: S->pre_fetched = 0;
! 191: return 1;
! 192: }
! 193: if (S->done) {
! 194: return 0;
! 195: }
! 196: i = sqlite3_step(S->stmt);
! 197: switch (i) {
! 198: case SQLITE_ROW:
! 199: return 1;
! 200:
! 201: case SQLITE_DONE:
! 202: S->done = 1;
! 203: sqlite3_reset(S->stmt);
! 204: return 0;
! 205:
! 206: case SQLITE_ERROR:
! 207: sqlite3_reset(S->stmt);
! 208: default:
! 209: pdo_sqlite_error_stmt(stmt);
! 210: return 0;
! 211: }
! 212: }
! 213:
! 214: static int pdo_sqlite_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
! 215: {
! 216: pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
! 217:
! 218: if(colno >= sqlite3_column_count(S->stmt)) {
! 219: /* error invalid column */
! 220: pdo_sqlite_error_stmt(stmt);
! 221: return 0;
! 222: }
! 223:
! 224: stmt->columns[colno].name = estrdup(sqlite3_column_name(S->stmt, colno));
! 225: stmt->columns[colno].namelen = strlen(stmt->columns[colno].name);
! 226: stmt->columns[colno].maxlen = 0xffffffff;
! 227: stmt->columns[colno].precision = 0;
! 228:
! 229: switch (sqlite3_column_type(S->stmt, colno)) {
! 230: case SQLITE_INTEGER:
! 231: case SQLITE_FLOAT:
! 232: case SQLITE3_TEXT:
! 233: case SQLITE_BLOB:
! 234: case SQLITE_NULL:
! 235: default:
! 236: stmt->columns[colno].param_type = PDO_PARAM_STR;
! 237: break;
! 238: }
! 239:
! 240: return 1;
! 241: }
! 242:
! 243: static int pdo_sqlite_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len, int *caller_frees TSRMLS_DC)
! 244: {
! 245: pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
! 246: if (!S->stmt) {
! 247: return 0;
! 248: }
! 249: if(colno >= sqlite3_data_count(S->stmt)) {
! 250: /* error invalid column */
! 251: pdo_sqlite_error_stmt(stmt);
! 252: return 0;
! 253: }
! 254: switch (sqlite3_column_type(S->stmt, colno)) {
! 255: case SQLITE_NULL:
! 256: *ptr = NULL;
! 257: *len = 0;
! 258: return 1;
! 259:
! 260: case SQLITE_BLOB:
! 261: *ptr = (char*)sqlite3_column_blob(S->stmt, colno);
! 262: *len = sqlite3_column_bytes(S->stmt, colno);
! 263: return 1;
! 264:
! 265: default:
! 266: *ptr = (char*)sqlite3_column_text(S->stmt, colno);
! 267: *len = sqlite3_column_bytes(S->stmt, colno);
! 268: return 1;
! 269: }
! 270: }
! 271:
! 272: static int pdo_sqlite_stmt_col_meta(pdo_stmt_t *stmt, long colno, zval *return_value TSRMLS_DC)
! 273: {
! 274: pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
! 275: const char *str;
! 276: zval *flags;
! 277:
! 278: if (!S->stmt) {
! 279: return FAILURE;
! 280: }
! 281: if(colno >= sqlite3_data_count(S->stmt)) {
! 282: /* error invalid column */
! 283: pdo_sqlite_error_stmt(stmt);
! 284: return FAILURE;
! 285: }
! 286:
! 287: array_init(return_value);
! 288: MAKE_STD_ZVAL(flags);
! 289: array_init(flags);
! 290:
! 291: switch (sqlite3_column_type(S->stmt, colno)) {
! 292: case SQLITE_NULL:
! 293: add_assoc_string(return_value, "native_type", "null", 1);
! 294: break;
! 295:
! 296: case SQLITE_FLOAT:
! 297: add_assoc_string(return_value, "native_type", "double", 1);
! 298: break;
! 299:
! 300: case SQLITE_BLOB:
! 301: add_next_index_string(flags, "blob", 1);
! 302: case SQLITE_TEXT:
! 303: add_assoc_string(return_value, "native_type", "string", 1);
! 304: break;
! 305:
! 306: case SQLITE_INTEGER:
! 307: add_assoc_string(return_value, "native_type", "integer", 1);
! 308: break;
! 309: }
! 310:
! 311: str = sqlite3_column_decltype(S->stmt, colno);
! 312: if (str) {
! 313: add_assoc_string(return_value, "sqlite:decl_type", (char *)str, 1);
! 314: }
! 315:
! 316: #ifdef SQLITE_ENABLE_COLUMN_METADATA
! 317: str = sqlite3_column_table_name(S->stmt, colno);
! 318: if (str) {
! 319: add_assoc_string(return_value, "table", (char *)str, 1);
! 320: }
! 321: #endif
! 322:
! 323: add_assoc_zval(return_value, "flags", flags);
! 324:
! 325: return SUCCESS;
! 326: }
! 327:
! 328: static int pdo_sqlite_stmt_cursor_closer(pdo_stmt_t *stmt TSRMLS_DC)
! 329: {
! 330: pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
! 331: sqlite3_reset(S->stmt);
! 332: return 1;
! 333: }
! 334:
! 335: struct pdo_stmt_methods sqlite_stmt_methods = {
! 336: pdo_sqlite_stmt_dtor,
! 337: pdo_sqlite_stmt_execute,
! 338: pdo_sqlite_stmt_fetch,
! 339: pdo_sqlite_stmt_describe,
! 340: pdo_sqlite_stmt_get_col,
! 341: pdo_sqlite_stmt_param_hook,
! 342: NULL, /* set_attr */
! 343: NULL, /* get_attr */
! 344: pdo_sqlite_stmt_col_meta,
! 345: NULL, /* next_rowset */
! 346: pdo_sqlite_stmt_cursor_closer
! 347: };
! 348:
! 349: /*
! 350: * Local variables:
! 351: * tab-width: 4
! 352: * c-basic-offset: 4
! 353: * End:
! 354: * vim600: noet sw=4 ts=4 fdm=marker
! 355: * vim<600: noet sw=4 ts=4
! 356: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>