bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2017-2018 Dovecot authors, see the included COPYING file */
b5ab29780f74cf88212a547ebbe3b6bc0cb867c5Stephan Bosch
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi#include "lib.h"
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi#include "test-lib.h"
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi#include "str.h"
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi#include "buffer.h"
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi#include "sql-api-private.h"
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi#include "driver-test.h"
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi#include "array.h"
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi#include "hex-binary.h"
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistruct test_sql_db {
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct sql_db api;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi pool_t pool;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi ARRAY(struct test_driver_result) expected;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi const char *error;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi bool failed:1;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi};
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistruct test_sql_result {
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct sql_result api;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_driver_result *result;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi const char *error;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi};
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic struct sql_db *driver_test_mysql_init(const char *connect_string);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic struct sql_db *driver_test_cassandra_init(const char *connect_string);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic struct sql_db *driver_test_sqlite_init(const char *connect_string);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic void driver_test_deinit(struct sql_db *_db);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic int driver_test_connect(struct sql_db *_db);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic void driver_test_disconnect(struct sql_db *_db);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic const char *
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_mysql_escape_string(struct sql_db *_db, const char *string);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic const char *
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_escape_string(struct sql_db *_db, const char *string);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic void driver_test_exec(struct sql_db *_db, const char *query);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic void driver_test_query(struct sql_db *_db, const char *query,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi sql_query_callback_t *callback, void *context);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic struct sql_result *
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_query_s(struct sql_db *_db, const char *query);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic struct sql_transaction_context *
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_transaction_begin(struct sql_db *_db);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic void driver_test_transaction_commit(struct sql_transaction_context *ctx,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi sql_commit_callback_t *callback,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi void *context);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic int
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_transaction_commit_s(struct sql_transaction_context *ctx,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi const char **error_r);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic void
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_transaction_rollback(struct sql_transaction_context *ctx);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic void
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_update(struct sql_transaction_context *ctx, const char *query,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi unsigned int *affected_rows);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic const char *
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_mysql_escape_blob(struct sql_db *_db, const unsigned char *data,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi size_t size);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic const char *
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_escape_blob(struct sql_db *_db, const unsigned char *data,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi size_t size);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic void driver_test_result_free(struct sql_result *result);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic int driver_test_result_next_row(struct sql_result *result);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic unsigned int
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_result_get_fields_count(struct sql_result *result);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic const char *
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_result_get_field_name(struct sql_result *result, unsigned int idx);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic int
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_result_find_field(struct sql_result *result, const char *field_name);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic const char *
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_result_get_field_value(struct sql_result *result, unsigned int idx);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic const unsigned char *
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_result_get_field_value_binary(struct sql_result *result,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi unsigned int idx, size_t *size_r);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic const char *
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_result_find_field_value(struct sql_result *result,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi const char *field_name);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic const char *const *
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_result_get_values(struct sql_result *result);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomiconst char *driver_test_result_get_error(struct sql_result *result);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomiconst struct sql_db driver_test_mysql_db = {
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi .name = "mysql",
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi .v = {
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .init = driver_test_mysql_init,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .deinit = driver_test_deinit,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .connect = driver_test_connect,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .disconnect = driver_test_disconnect,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .escape_string = driver_test_mysql_escape_string,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .exec = driver_test_exec,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .query = driver_test_query,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .query_s = driver_test_query_s,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .transaction_begin = driver_test_transaction_begin,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .transaction_commit = driver_test_transaction_commit,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .transaction_commit_s = driver_test_transaction_commit_s,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .transaction_rollback = driver_test_transaction_rollback,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .update = driver_test_update,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .escape_blob = driver_test_mysql_escape_blob,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi }
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi};
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomiconst struct sql_db driver_test_cassandra_db = {
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi .name = "cassandra",
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi .v = {
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .init = driver_test_cassandra_init,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .deinit = driver_test_deinit,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .connect = driver_test_connect,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .disconnect = driver_test_disconnect,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .escape_string = driver_test_escape_string,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .exec = driver_test_exec,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .query = driver_test_query,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .query_s = driver_test_query_s,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .transaction_begin = driver_test_transaction_begin,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .transaction_commit = driver_test_transaction_commit,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .transaction_commit_s = driver_test_transaction_commit_s,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .transaction_rollback = driver_test_transaction_rollback,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .update = driver_test_update,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .escape_blob = driver_test_escape_blob,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi }
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi};
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomiconst struct sql_db driver_test_sqlite_db = {
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi .name = "sqlite",
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi .v = {
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .init = driver_test_sqlite_init,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .deinit = driver_test_deinit,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .connect = driver_test_connect,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .disconnect = driver_test_disconnect,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .escape_string = driver_test_escape_string,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .exec = driver_test_exec,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .query = driver_test_query,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .query_s = driver_test_query_s,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .transaction_begin = driver_test_transaction_begin,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .transaction_commit = driver_test_transaction_commit,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .transaction_commit_s = driver_test_transaction_commit_s,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .transaction_rollback = driver_test_transaction_rollback,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .update = driver_test_update,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .escape_blob = driver_test_escape_blob,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi }
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi};
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomiconst struct sql_result driver_test_result = {
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi .v = {
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .free = driver_test_result_free,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .next_row = driver_test_result_next_row,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .get_fields_count = driver_test_result_get_fields_count,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .get_field_name = driver_test_result_get_field_name,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .find_field = driver_test_result_find_field,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .get_field_value = driver_test_result_get_field_value,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .get_field_value_binary = driver_test_result_get_field_value_binary,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .find_field_value = driver_test_result_find_field_value,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .get_values = driver_test_result_get_values,
ef597c4619eb021563f659b886c67762fce7a817Timo Sirainen .get_error = driver_test_result_get_error,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi }
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi};
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomivoid sql_driver_test_register(void)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi sql_driver_register(&driver_test_mysql_db);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi sql_driver_register(&driver_test_cassandra_db);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi sql_driver_register(&driver_test_sqlite_db);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomivoid sql_driver_test_unregister(void)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi sql_driver_unregister(&driver_test_mysql_db);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi sql_driver_unregister(&driver_test_cassandra_db);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi sql_driver_unregister(&driver_test_sqlite_db);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic struct sql_db *driver_test_init(const struct sql_db *driver,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi const char *connect_string ATTR_UNUSED)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi pool_t pool = pool_alloconly_create(MEMPOOL_GROWING" test sql driver", 2048);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_sql_db *ret = p_new(pool, struct test_sql_db, 1);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi ret->pool = pool;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi ret->api = *driver;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi p_array_init(&ret->expected, pool, 8);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return &ret->api;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic struct sql_db *driver_test_mysql_init(const char *connect_string)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return driver_test_init(&driver_test_mysql_db, connect_string);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic struct sql_db *driver_test_cassandra_init(const char *connect_string)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return driver_test_init(&driver_test_cassandra_db, connect_string);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic struct sql_db *driver_test_sqlite_init(const char *connect_string)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return driver_test_init(&driver_test_sqlite_db, connect_string);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic void driver_test_deinit(struct sql_db *_db ATTR_UNUSED)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_sql_db *db = (struct test_sql_db*)_db;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi array_free(&_db->module_contexts);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi pool_unref(&db->pool);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic int driver_test_connect(struct sql_db *_db ATTR_UNUSED)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi /* nix */
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return 0;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic void driver_test_disconnect(struct sql_db *_db ATTR_UNUSED)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{ }
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic const char *
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_mysql_escape_string(struct sql_db *_db ATTR_UNUSED,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi const char *string)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi string_t *esc = t_str_new(strlen(string));
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi for(const char *ptr = string; *ptr != '\0'; ptr++) {
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi if (*ptr == '\n' || *ptr == '\r' || *ptr == '\\' ||
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi *ptr == '\'' || *ptr == '\"' || *ptr == '\x1a')
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi str_append_c(esc, '\\');
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi str_append_c(esc, *ptr);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi }
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return str_c(esc);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic const char *
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_escape_string(struct sql_db *_db ATTR_UNUSED, const char *string)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return string;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic void driver_test_exec(struct sql_db *_db, const char *query)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_sql_db *db = (struct test_sql_db*)_db;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_driver_result *result =
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi array_idx_modifiable(&db->expected, 0);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi i_assert(result->cur < result->nqueries);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi/* i_debug("DUMMY EXECUTE: %s", query);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi i_debug("DUMMY EXPECT : %s", result->queries[result->cur]); */
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi test_assert(strcmp(result->queries[result->cur], query)==0);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi if (strcmp(result->queries[result->cur], query) != 0) {
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi db->error = "Invalid query";
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi db->failed = TRUE;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi }
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi result->cur++;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic void
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_query(struct sql_db *_db, const char *query,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi sql_query_callback_t *callback, void *context)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct sql_result *result = driver_test_query_s(_db, query);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi if (callback != NULL)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi callback(result, context);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic struct sql_result *
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_query_s(struct sql_db *_db, const char *query)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_sql_db *db = (struct test_sql_db*)_db;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_driver_result *result =
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi array_idx_modifiable(&db->expected, 0);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_sql_result *res = i_new(struct test_sql_result, 1);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi driver_test_exec(_db, query);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi if (db->failed) {
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi res->api.failed = TRUE;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi }
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi res->api.v = driver_test_result.v;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi res->api.db = _db;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi if (result->result != NULL) {
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi res->result = i_new(struct test_driver_result, 1);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi memcpy(res->result, result, sizeof(*result));
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi }
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi res->api.refcount = 1;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi /* drop it from array if it's used up */
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi if (result->cur == result->nqueries)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi array_delete(&db->expected, 0, 1);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return &res->api;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic struct sql_transaction_context *
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_transaction_begin(struct sql_db *_db)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct sql_transaction_context *ctx =
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi i_new(struct sql_transaction_context, 1);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi ctx->db = _db;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return ctx;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic void
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_transaction_commit(struct sql_transaction_context *ctx,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi sql_commit_callback_t *callback, void *context)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct sql_commit_result res;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi res.error_type = driver_test_transaction_commit_s(ctx, &res.error);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi callback(&res, context);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic int
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_transaction_commit_s(struct sql_transaction_context *ctx,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi const char **error_r)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_sql_db *db = (struct test_sql_db*)ctx->db;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi int ret = 0;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi if (db->error != NULL) {
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi *error_r = db->error;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi ret = -1;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi }
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi i_free(ctx);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi db->error = NULL;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi db->failed = FALSE;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return ret;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic void
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_transaction_rollback(struct sql_transaction_context *ctx)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_sql_db *db = (struct test_sql_db*)ctx->db;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi i_free(ctx);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi db->error = NULL;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi db->failed = FALSE;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic void
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_update(struct sql_transaction_context *ctx, const char *query,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi unsigned int *affected_rows)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_sql_db *db= (struct test_sql_db*)ctx->db;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_driver_result *result =
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi array_idx_modifiable(&db->expected, 0);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi driver_test_exec(ctx->db, query);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi if (affected_rows != NULL)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi *affected_rows = result->affected_rows;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi /* drop it from array if it's used up */
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi if (result->cur == result->nqueries)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi array_delete(&db->expected, 0, 1);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic const char *
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_mysql_escape_blob(struct sql_db *_db ATTR_UNUSED,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi const unsigned char *data, size_t size)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return t_strdup_printf("X'%s'", binary_to_hex(data,size));
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic const char *
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_escape_blob(struct sql_db *_db ATTR_UNUSED,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi const unsigned char *data, size_t size)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return t_strdup_printf("X'%s'", binary_to_hex(data,size));
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic void driver_test_result_free(struct sql_result *result)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_sql_result *tsr =
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi (struct test_sql_result *)result;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi if (tsr->result != NULL)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi i_free(tsr->result);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi i_free(result);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic int driver_test_result_next_row(struct sql_result *result)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_sql_result *tsr =
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi (struct test_sql_result *)result;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_driver_result *r = tsr->result;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi if (r == NULL) return 0;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_driver_result_set *rs =
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi &(r->result[r->cur-1]);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi if (rs->cur <= rs->rows) {
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi rs->cur++;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi }
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return rs->cur <= rs->rows ? 1 : 0;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic unsigned int
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_result_get_fields_count(struct sql_result *result)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_sql_result *tsr =
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi (struct test_sql_result *)result;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_driver_result *r = tsr->result;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_driver_result_set *rs =
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi &(r->result[r->cur-1]);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return rs->cols;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic const char *
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_result_get_field_name(struct sql_result *result, unsigned int idx)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_sql_result *tsr =
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi (struct test_sql_result *)result;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_driver_result *r = tsr->result;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_driver_result_set *rs =
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi &(r->result[r->cur-1]);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi i_assert(idx < rs->cols);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return rs->col_names[idx];
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic int
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_result_find_field(struct sql_result *result, const char *field_name)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_sql_result *tsr =
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi (struct test_sql_result *)result;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_driver_result *r = tsr->result;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_driver_result_set *rs =
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi &(r->result[r->cur-1]);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi for(size_t i = 0; i < rs->cols; i++) {
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi if (strcmp(field_name, rs->col_names[i])==0)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return i;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi }
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return -1;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic const char *
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_result_get_field_value(struct sql_result *result, unsigned int idx)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_sql_result *tsr =
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi (struct test_sql_result *)result;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_driver_result *r = tsr->result;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_driver_result_set *rs =
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi &(r->result[r->cur-1]);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi i_assert(idx < rs->cols);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi i_assert(rs->cur <= rs->rows);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return rs->row_data[rs->cur-1][idx];
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic const unsigned char *
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_result_get_field_value_binary(struct sql_result *result,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi unsigned int idx, size_t *size_r)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
c147bff818798a979d93537f72f5c1f68f5d5ba8Aki Tuomi buffer_t *buf = t_buffer_create(64);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi const char *value = driver_test_result_get_field_value(result, idx);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi /* expect it hex encoded */
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi if (hex_to_binary(value, buf) < 0) {
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi *size_r = 0;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return NULL;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi }
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi *size_r = buf->used;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return buf->data;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic const char *
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_result_find_field_value(struct sql_result *result,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi const char *field_name)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi int idx = driver_test_result_find_field(result, field_name);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi if (idx < 0) return NULL;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return driver_test_result_get_field_value(result, idx);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomistatic const char *const *
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomidriver_test_result_get_values(struct sql_result *result)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_sql_result *tsr =
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi (struct test_sql_result *)result;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_driver_result *r = tsr->result;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_driver_result_set *rs =
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi &(r->result[r->cur-1]);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi i_assert(rs->cur <= rs->rows);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return rs->row_data[rs->cur-1];
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomiconst char *driver_test_result_get_error(struct sql_result *result)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_sql_result *tsr =
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi (struct test_sql_result *)result;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi return tsr->error;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomivoid sql_driver_test_add_expected_result(struct sql_db *_db,
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi const struct test_driver_result *result)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_sql_db *db = (struct test_sql_db*)_db;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi array_append(&db->expected, result, 1);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomivoid sql_driver_test_clear_expected_results(struct sql_db *_db)
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi{
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi struct test_sql_db *db = (struct test_sql_db*)_db;
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi array_clear(&db->expected);
7b1ce34143ee2c47bf4d2bff73f9cd6e763fadc0Aki Tuomi}