Пример #1
0
static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options)
{
	pdo_dblib_db_handle *H;
	int i, nvars, nvers, ret = 0;

	const pdo_dblib_keyval tdsver[] = {
		 {"4.2",DBVERSION_42}
		,{"4.6",DBVERSION_46}
		,{"5.0",DBVERSION_70} /* FIXME: This does not work with Sybase, but environ will */
		,{"6.0",DBVERSION_70}
		,{"7.0",DBVERSION_70}
#ifdef DBVERSION_71
		,{"7.1",DBVERSION_71}
#endif
#ifdef DBVERSION_72
		,{"7.2",DBVERSION_72}
		,{"8.0",DBVERSION_72}
#endif
#ifdef DBVERSION_73
		,{"7.3",DBVERSION_73}
#endif
#ifdef DBVERSION_74
		,{"7.4",DBVERSION_74}
#endif
		,{"10.0",DBVERSION_100}
		,{"auto",0} /* Only works with FreeTDS. Other drivers will bork */

	};
	
	struct pdo_data_src_parser vars[] = {
		{ "charset",	NULL,	0 }
		,{ "appname",	"PHP " PDO_DBLIB_FLAVOUR,	0 }
		,{ "host",		"127.0.0.1", 0 }
		,{ "dbname",	NULL,	0 }
		,{ "secure",	NULL,	0 } /* DBSETLSECURE */
		,{ "version",	NULL,	0 } /* DBSETLVERSION */
	};

	nvars = sizeof(vars)/sizeof(vars[0]);
	nvers = sizeof(tdsver)/sizeof(tdsver[0]);
	
	php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, nvars);

	H = pecalloc(1, sizeof(*H), dbh->is_persistent);
	H->login = dblogin();
	H->err.sqlstate = dbh->error_code;
	H->stringify_uniqueidentifier = 0;

	if (!H->login) {
		goto cleanup;
	}

	if (driver_options) {
		int connect_timeout = pdo_attr_lval(driver_options, PDO_DBLIB_ATTR_CONNECTION_TIMEOUT, -1);
		int query_timeout = pdo_attr_lval(driver_options, PDO_DBLIB_ATTR_QUERY_TIMEOUT, -1);
		int timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, 30);

		if (connect_timeout == -1) {
			connect_timeout = timeout;
		}
		if (query_timeout == -1) {
			query_timeout = timeout;
		}

		dbsetlogintime(connect_timeout); /* Connection/Login Timeout */
		dbsettime(query_timeout); /* Statement Timeout */

		H->stringify_uniqueidentifier = pdo_attr_lval(driver_options, PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, 0);
	}

	DBERRHANDLE(H->login, (EHANDLEFUNC) pdo_dblib_error_handler);
	DBMSGHANDLE(H->login, (MHANDLEFUNC) pdo_dblib_msg_handler);

	if(vars[5].optval) {
		for(i=0;i<nvers;i++) {
			if(strcmp(vars[5].optval,tdsver[i].key) == 0) {
				if(FAIL==dbsetlversion(H->login, tdsver[i].value)) {
					pdo_raise_impl_error(dbh, NULL, "HY000", "PDO_DBLIB: Failed to set version specified in connection string.");
					goto cleanup;
				}
				break;
			}
		}

		if (i==nvers) {
			printf("Invalid version '%s'\n", vars[5].optval);
			pdo_raise_impl_error(dbh, NULL, "HY000", "PDO_DBLIB: Invalid version specified in connection string.");
			goto cleanup; /* unknown version specified */
		}
	}

	if (dbh->username) {
		if(FAIL == DBSETLUSER(H->login, dbh->username)) {
			goto cleanup;
		}
	}

	if (dbh->password) {
		if(FAIL == DBSETLPWD(H->login, dbh->password)) {
			goto cleanup;
		}
	}

#if !PHP_DBLIB_IS_MSSQL
	if (vars[0].optval) {
		DBSETLCHARSET(H->login, vars[0].optval);
	}
#endif

	DBSETLAPP(H->login, vars[1].optval);

/* DBSETLDBNAME is only available in FreeTDS 0.92 or above */
#ifdef DBSETLDBNAME
	if (vars[3].optval) {
		if(FAIL == DBSETLDBNAME(H->login, vars[3].optval)) goto cleanup;
	}
#endif

	H->link = dbopen(H->login, vars[2].optval);

	if (!H->link) {
		goto cleanup;
	}

/*
 * FreeTDS < 0.92 does not support the DBSETLDBNAME option
 * Send use database here after login (Will not work with SQL Azure)
 */
#ifndef DBSETLDBNAME
	if (vars[3].optval) {
		if(FAIL == dbuse(H->link, vars[3].optval)) goto cleanup;
	}
#endif

#if PHP_DBLIB_IS_MSSQL
	/* dblib do not return more than this length from text/image */
	DBSETOPT(H->link, DBTEXTLIMIT, "2147483647");
#endif

	/* limit text/image from network */
	DBSETOPT(H->link, DBTEXTSIZE, "2147483647");

	/* allow double quoted indentifiers */
	DBSETOPT(H->link, DBQUOTEDIDENT, "1");

	ret = 1;
	dbh->max_escaped_char_length = 2;
	dbh->alloc_own_columns = 1;

cleanup:
	for (i = 0; i < nvars; i++) {
		if (vars[i].freeme) {
			efree(vars[i].optval);
		}
	}

	dbh->methods = &dblib_methods;
	dbh->driver_data = H;

	if (!ret) {
		zend_throw_exception_ex(php_pdo_get_exception(), DBLIB_G(err).dberr,
			"SQLSTATE[%s] %s (severity %d)",
			DBLIB_G(err).sqlstate,
			DBLIB_G(err).dberrstr,
			DBLIB_G(err).severity);
	}

	return ret;
}
Пример #2
0
static int pdo_sqlite_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
		enum pdo_param_event event_type)
{
	pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
	zval *parameter;

	switch (event_type) {
		case PDO_PARAM_EVT_EXEC_PRE:
			if (stmt->executed && !S->done) {
				sqlite3_reset(S->stmt);
				S->done = 1;
			}

			if (param->is_param) {

				if (param->paramno == -1) {
					param->paramno = sqlite3_bind_parameter_index(S->stmt, ZSTR_VAL(param->name)) - 1;
				}

				switch (PDO_PARAM_TYPE(param->param_type)) {
					case PDO_PARAM_STMT:
						return 0;

					case PDO_PARAM_NULL:
						if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
							return 1;
						}
						pdo_sqlite_error_stmt(stmt);
						return 0;

					case PDO_PARAM_INT:
					case PDO_PARAM_BOOL:
						if (Z_ISREF(param->parameter)) {
							parameter = Z_REFVAL(param->parameter);
						} else {
							parameter = &param->parameter;
						}
						if (Z_TYPE_P(parameter) == IS_NULL) {
							if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
								return 1;
							}
						} else {
							convert_to_long(parameter);
#if ZEND_LONG_MAX > 2147483647
							if (SQLITE_OK == sqlite3_bind_int64(S->stmt, param->paramno + 1, Z_LVAL_P(parameter))) {
								return 1;
							}
#else
							if (SQLITE_OK == sqlite3_bind_int(S->stmt, param->paramno + 1, Z_LVAL_P(parameter))) {
								return 1;
							}
#endif
						}
						pdo_sqlite_error_stmt(stmt);
						return 0;

					case PDO_PARAM_LOB:
						if (Z_ISREF(param->parameter)) {
							parameter = Z_REFVAL(param->parameter);
						} else {
							parameter = &param->parameter;
						}
						if (Z_TYPE_P(parameter) == IS_RESOURCE) {
							php_stream *stm = NULL;
							php_stream_from_zval_no_verify(stm, parameter);
							if (stm) {
								zend_string *mem = php_stream_copy_to_mem(stm, PHP_STREAM_COPY_ALL, 0);
								zval_ptr_dtor(parameter);
								ZVAL_STR(parameter, mem ? mem : ZSTR_EMPTY_ALLOC());
							} else {
								pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource");
								return 0;
							}
						} else if (Z_TYPE_P(parameter) == IS_NULL) {
							if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
								return 1;
							}
							pdo_sqlite_error_stmt(stmt);
							return 0;
						} else {
							convert_to_string(parameter);
						}

						if (SQLITE_OK == sqlite3_bind_blob(S->stmt, param->paramno + 1,
								Z_STRVAL_P(parameter),
								Z_STRLEN_P(parameter),
								SQLITE_STATIC)) {
							return 1;
						}
						return 0;

					case PDO_PARAM_STR:
					default:
						if (Z_ISREF(param->parameter)) {
							parameter = Z_REFVAL(param->parameter);
						} else {
							parameter = &param->parameter;
						}
						if (Z_TYPE_P(parameter) == IS_NULL) {
							if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
								return 1;
							}
						} else {
							convert_to_string(parameter);
							if (SQLITE_OK == sqlite3_bind_text(S->stmt, param->paramno + 1,
									Z_STRVAL_P(parameter),
									Z_STRLEN_P(parameter),
									SQLITE_STATIC)) {
								return 1;
							}
						}
						pdo_sqlite_error_stmt(stmt);
						return 0;
				}
			}
			break;

		default:
			;
	}
	return 1;
}
Пример #3
0
static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
		enum pdo_param_event event_type)
{
	pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;

	if (stmt->supports_placeholders == PDO_PLACEHOLDER_NAMED && param->is_param) {
		switch (event_type) {
			case PDO_PARAM_EVT_FREE:
				if (param->driver_data) {
					efree(param->driver_data);
				}
				break;

			case PDO_PARAM_EVT_NORMALIZE:
				/* decode name from $1, $2 into 0, 1 etc. */
				if (param->name) {
					if (ZSTR_VAL(param->name)[0] == '$') {
						ZEND_ATOL(param->paramno, ZSTR_VAL(param->name) + 1);
					} else {
						/* resolve parameter name to rewritten name */
						char *namevar;

						if (stmt->bound_param_map && (namevar = zend_hash_find_ptr(stmt->bound_param_map,
								param->name)) != NULL) {
							ZEND_ATOL(param->paramno, namevar + 1);
							param->paramno--;
						} else {
							pdo_raise_impl_error(stmt->dbh, stmt, "HY093", ZSTR_VAL(param->name));
							return 0;
						}
					}
				}
				break;

			case PDO_PARAM_EVT_ALLOC:
			case PDO_PARAM_EVT_EXEC_POST:
			case PDO_PARAM_EVT_FETCH_PRE:
			case PDO_PARAM_EVT_FETCH_POST:
				/* work is handled by EVT_NORMALIZE */
				return 1;

			case PDO_PARAM_EVT_EXEC_PRE:
				if (!stmt->bound_param_map) {
					return 0;
				}
				if (!S->param_values) {
					S->param_values = ecalloc(
							zend_hash_num_elements(stmt->bound_param_map),
							sizeof(char*));
					S->param_lengths = ecalloc(
							zend_hash_num_elements(stmt->bound_param_map),
							sizeof(int));
					S->param_formats = ecalloc(
							zend_hash_num_elements(stmt->bound_param_map),
							sizeof(int));
					S->param_types = ecalloc(
							zend_hash_num_elements(stmt->bound_param_map),
							sizeof(Oid));
				}
				if (param->paramno >= 0) {
					zval *parameter;

					if (param->paramno >= zend_hash_num_elements(stmt->bound_params)) {
						pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "parameter was not defined");
						return 0;
					}

					if (Z_ISREF(param->parameter)) {
						parameter = Z_REFVAL(param->parameter);
					} else {
						parameter = &param->parameter;
					}

					if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB &&
							Z_TYPE_P(parameter) == IS_RESOURCE) {
						php_stream *stm;
						php_stream_from_zval_no_verify(stm, parameter);
						if (stm) {
							if (php_stream_is(stm, &pdo_pgsql_lob_stream_ops)) {
								struct pdo_pgsql_lob_self *self = (struct pdo_pgsql_lob_self*)stm->abstract;
								pdo_pgsql_bound_param *P = param->driver_data;

								if (P == NULL) {
									P = ecalloc(1, sizeof(*P));
									param->driver_data = P;
								}
								P->oid = htonl(self->oid);
								S->param_values[param->paramno] = (char*)&P->oid;
								S->param_lengths[param->paramno] = sizeof(P->oid);
								S->param_formats[param->paramno] = 1;
								S->param_types[param->paramno] = OIDOID;
								return 1;
							} else {
								zend_string *str = php_stream_copy_to_mem(stm, PHP_STREAM_COPY_ALL, 0);
								if (str != NULL) {
									//??SEPARATE_ZVAL_IF_NOT_REF(&param->parameter);
									ZVAL_STR(parameter, str);
								} else {
									ZVAL_EMPTY_STRING(parameter);
								}
							}
						} else {
							/* expected a stream resource */
							pdo_pgsql_error_stmt(stmt, PGRES_FATAL_ERROR, "HY105");
							return 0;
						}
					}

					if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_NULL ||
							Z_TYPE_P(parameter) == IS_NULL) {
						S->param_values[param->paramno] = NULL;
						S->param_lengths[param->paramno] = 0;
					} else if (Z_TYPE_P(parameter) == IS_FALSE || Z_TYPE_P(parameter) == IS_TRUE) {
						S->param_values[param->paramno] = Z_TYPE_P(parameter) == IS_TRUE ? "t" : "f";
						S->param_lengths[param->paramno] = 1;
						S->param_formats[param->paramno] = 0;
					} else {
						//SEPARATE_ZVAL_IF_NOT_REF(&param->parameter);
						convert_to_string_ex(parameter);
						S->param_values[param->paramno] = Z_STRVAL_P(parameter);
						S->param_lengths[param->paramno] = Z_STRLEN_P(parameter);
						S->param_formats[param->paramno] = 0;
					}

					if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) {
						S->param_types[param->paramno] = 0;
						S->param_formats[param->paramno] = 1;
					} else {
						S->param_types[param->paramno] = 0;
					}
				}
				break;
		}
	} else if (param->is_param) {
		/* We need to manually convert to a pg native boolean value */
		if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL &&
			((param->param_type & PDO_PARAM_INPUT_OUTPUT) != PDO_PARAM_INPUT_OUTPUT)) {
			SEPARATE_ZVAL(&param->parameter);
			param->param_type = PDO_PARAM_STR;
			convert_to_boolean(&param->parameter);
			ZVAL_STRINGL(&param->parameter, Z_TYPE_P(&param->parameter) == IS_TRUE ? "t" : "f", 1);
		}
	}
	return 1;
}
Пример #4
0
bool PDOSqliteStatement::paramHook(PDOBoundParam *param,
                                   PDOParamEvent event_type) {
  switch (event_type) {
  case PDO_PARAM_EVT_EXEC_PRE:
    if (executed && !m_done) {
      sqlite3_reset(m_stmt);
      m_done = 1;
    }

    if (param->is_param) {
      if (param->paramno == -1) {
        param->paramno = sqlite3_bind_parameter_index(m_stmt,
                                                      param->name.c_str()) - 1;
      }

      switch (PDO_PARAM_TYPE(param->param_type)) {
      case PDO_PARAM_STMT:
        return false;

      case PDO_PARAM_NULL:
        if (sqlite3_bind_null(m_stmt, param->paramno + 1) == SQLITE_OK) {
          return true;
        }
        handleError(__FILE__, __LINE__);
        return false;

      case PDO_PARAM_INT:
      case PDO_PARAM_BOOL:
        if (param->parameter.isNull()) {
          if (sqlite3_bind_null(m_stmt, param->paramno + 1) == SQLITE_OK) {
            return true;
          }
        } else {
          if (SQLITE_OK == sqlite3_bind_int(m_stmt, param->paramno + 1,
                                            param->parameter.toInt64())) {
            return true;
          }
        }
        handleError(__FILE__, __LINE__);
        return false;

      case PDO_PARAM_LOB:
        if (param->parameter.isResource()) {
          Variant buf = f_stream_get_contents(param->parameter);
          if (!same(buf, false)) {
            param->parameter = buf;
          } else {
            pdo_raise_impl_error(dbh, this, "HY105",
                                 "Expected a stream resource");
            return false;
          }
        } else if (param->parameter.isNull()) {
          if (sqlite3_bind_null(m_stmt, param->paramno + 1) == SQLITE_OK) {
            return true;
          }
          handleError(__FILE__, __LINE__);
          return false;
        }

        {
          String sparam = param->parameter.toString();
          if (SQLITE_OK == sqlite3_bind_blob(m_stmt, param->paramno + 1,
                                             sparam.data(), sparam.size(),
                                             SQLITE_STATIC)) {
            return true;
          }
        }
        handleError(__FILE__, __LINE__);
        return false;

      case PDO_PARAM_STR:
      default:
        if (param->parameter.isNull()) {
          if (sqlite3_bind_null(m_stmt, param->paramno + 1) == SQLITE_OK) {
            return true;
          }
        } else {
          String sparam = param->parameter.toString();
          if (SQLITE_OK == sqlite3_bind_text(m_stmt, param->paramno + 1,
                                             sparam.data(), sparam.size(),
                                             SQLITE_STATIC)) {
            return true;
          }
        }
        handleError(__FILE__, __LINE__);
        return false;
      }
    }
    break;

  default:;
  }
  return true;
}