Return to sqlite_statement.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / pdo_sqlite |
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: */