int insert( std::string table, std::vector<boost::optional<const char*>> fields, const CONTAINER& values, connection& conn ) { std::string query_str = detail::insert_query_string(table, fields); sqlite3_stmt *stmt = nullptr; if( sqlite3_prepare(conn.handle(), query_str.c_str(), -1, &stmt, nullptr) != SQLITE_OK ) { std::ostringstream oss; oss << "error in SQLite insert (preparing); query: " << query_str << " SQLite error: " << sqlite3_errmsg(conn.handle()); throw std::runtime_error(oss.str()); } bind_values(fields, values, stmt); sqlite::step(stmt, conn); if(sqlite3_finalize(stmt) != SQLITE_OK) { std::ostringstream oss; oss << "error in SQLite insert (finalising); query: " << query_str << " SQLite error: " << sqlite3_errmsg(conn.handle()); throw std::runtime_error(oss.str()); } return detail::last_insert_rowid(conn); }
void insert( std::string table, std::vector<boost::optional<const char*>> fields, json::list& values, connection& conn ) { std::string query_str = detail::insert_query_string(table, fields); sqlite3_stmt *stmt = nullptr; sqlite3_prepare(conn.handle(), query_str.c_str(), -1, &stmt, nullptr); for(json::object& obj : values.objects) { sqlite3_reset(stmt); sqlite3_clear_bindings(stmt); bind_values(fields, CONTAINER(obj), stmt); sqlite::step(stmt); } }
static mrb_value mrb_sqlite3_database_execute(mrb_state *mrb, mrb_value self) { int argc = 0; mrb_value* argv = NULL; mrb_value b = mrb_nil_value(); mrb_value value_context; mrb_sqlite3_database* db = NULL; mrb_value fields; int i, r, count; sqlite3_stmt* stmt = NULL; mrb_value args[2]; mrb_value query; mrb_get_args(mrb, "&S*", &b, &query, &argv, &argc); value_context = mrb_iv_get(mrb, self, mrb_intern(mrb, "context")); db = NULL; Data_Get_Struct(mrb, value_context, &mrb_sqlite3_database_type, db); if (!db) { mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument"); } r = sqlite3_prepare_v2(db->db, RSTRING_PTR(query), RSTRING_LEN(query), &stmt, NULL); if (r != SQLITE_OK) { if (stmt) { sqlite3_finalize(stmt); sqlite3_reset(stmt); } mrb_raise(mrb, E_RUNTIME_ERROR, sqlite3_errmsg(db->db)); } if (!stmt) { return mrb_nil_value(); } if (argc > 0) { const char* error = bind_values(mrb, db->db, stmt, argc, argv); if (error) { mrb_raise(mrb, E_ARGUMENT_ERROR, error); } } fields = mrb_ary_new(mrb); count = sqlite3_column_count(stmt); for (i = 0; i < count; i++) { const char* name = sqlite3_column_name(stmt, i); mrb_ary_push(mrb, fields, mrb_str_new_cstr(mrb, name)); } if (mrb_nil_p(b)) { struct RClass* _class_sqlite3; struct RClass* _class_sqlite3_resultset; mrb_value c; mrb_sqlite3_resultset* rs = (mrb_sqlite3_resultset*) malloc(sizeof(mrb_sqlite3_resultset)); if (!rs) { mrb_raise(mrb, E_RUNTIME_ERROR, "can't memory alloc"); } memset(rs, 0, sizeof(mrb_sqlite3_resultset)); rs->mrb = mrb; rs->stmt = stmt; _class_sqlite3 = mrb_class_get(mrb, "SQLite3"); _class_sqlite3_resultset = mrb_class_ptr(mrb_const_get(mrb, mrb_obj_value(_class_sqlite3), mrb_intern(mrb, "ResultSet"))); c = mrb_class_new_instance(mrb, 0, NULL, _class_sqlite3_resultset); mrb_iv_set(mrb, c, mrb_intern(mrb, "context"), mrb_obj_value( Data_Wrap_Struct(mrb, mrb->object_class, &mrb_sqlite3_resultset_type, (void*) rs))); mrb_iv_set(mrb, c, mrb_intern(mrb, "fields"), fields); mrb_iv_set(mrb, c, mrb_intern(mrb, "db"), self); mrb_iv_set(mrb, c, mrb_intern(mrb, "eof"), mrb_false_value()); return c; } while ((r = sqlite3_step(stmt)) == SQLITE_ROW) { int ai = mrb_gc_arena_save(mrb); args[0] = row_to_value(mrb, stmt); args[1] = fields; mrb_yield_argv(mrb, b, 2, args); mrb_gc_arena_restore(mrb, ai); } sqlite3_finalize(stmt); if (r != SQLITE_OK && r != SQLITE_DONE) { mrb_raise(mrb, E_RUNTIME_ERROR, sqlite3_errmsg(db->db)); } return mrb_nil_value(); }
static mrb_value mrb_sqlite3_database_execute_batch(mrb_state *mrb, mrb_value self) { int argc = 0; mrb_value *argv; mrb_value value_context; mrb_sqlite3_database* db = NULL; mrb_value query; int len; char* top; const char *tail, *sql; mrb_get_args(mrb, "*", &argv, &argc); if (argc == 0) { mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument"); } value_context = mrb_iv_get(mrb, self, mrb_intern(mrb, "context")); Data_Get_Struct(mrb, value_context, &mrb_sqlite3_database_type, db); if (!db) { mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument"); } query = argv[0]; len = RSTRING_LEN(query); top = malloc(len + 1); if (!top) { mrb_raise(mrb, E_RUNTIME_ERROR, "can't memory alloc"); } memcpy(top, RSTRING_PTR(query), len); top[len] = 0; tail = (const char*) top; while (*(sql = tail)) { sqlite3_stmt* stmt = NULL; int r = sqlite3_prepare_v2(db->db, sql, -1, &stmt, &tail); if (argc > 1) { const char* error = bind_values(mrb, db->db, stmt, argc-1, &argv[1]); argc = 0; if (error) { free(top); mrb_raise(mrb, E_ARGUMENT_ERROR, error); } } if (r != SQLITE_OK) { if (stmt) { sqlite3_finalize(stmt); sqlite3_reset(stmt); } free(top); mrb_raise(mrb, E_RUNTIME_ERROR, sqlite3_errmsg(db->db)); } if (stmt) { r = sqlite3_step(stmt); sqlite3_finalize(stmt); if (r != SQLITE_OK && r != SQLITE_DONE) { free(top); mrb_raise(mrb, E_RUNTIME_ERROR, sqlite3_errmsg(db->db)); } } } free(top); return mrb_fixnum_value(sqlite3_changes(db->db)); }
void update( std::string table, std::vector<boost::optional<const char*>> fields, T& values, connection& db ) { std::ostringstream query; query << "UPDATE " << table << " SET "; auto query_fields = fields; query_fields.erase( std::remove_if( query_fields.begin(), query_fields.end(), [](const boost::optional<const char*>& field) -> bool { return !field; } ), query_fields.end() ); json::serialise( query_fields, [](const boost::optional<const char*>& field, std::ostream& os) { os << field.get() << " = ?"; }, ", ", query ); // ID field query << " WHERE " << T::id_field() << " = " << values.id(); sqlite3_stmt *stmt = nullptr; if( sqlite3_prepare( db.handle(), query.str().c_str(), -1, &stmt, nullptr ) != SQLITE_OK ) { std::cerr << "Query: " << query.str() << std::endl; throw std::runtime_error("Preparing SQLite statement for update"); } bind_values(fields, values, stmt); int step_ret = sqlite3_step(stmt); if( step_ret != SQLITE_OK && step_ret != SQLITE_DONE ) { std::ostringstream oss; oss << "Stepping SQLite update " << sqlite3_errmsg(db.handle()); throw std::runtime_error(oss.str()); } int finalise_ret = sqlite3_finalize(stmt); if( finalise_ret != SQLITE_OK && finalise_ret != SQLITE_DONE) { std::ostringstream oss; oss << "SQLite finalise " << sqlite3_errmsg(db.handle()); throw std::runtime_error(oss.str()); } }