| 75 | } |
| 76 | |
| 77 | NODE_METHOD(Statement::JS_new) { |
| 78 | UseAddon; |
| 79 | if (!addon->privileged_info) { |
| 80 | return ThrowTypeError(info.Env(), "Statements can only be constructed by the db.prepare() method"); |
| 81 | } |
| 82 | assert(info.IsConstructCall()); |
| 83 | const Napi::CallbackInfo& pinfo = *addon->privileged_info; |
| 84 | UNWRAP_OR_RETURN(Database, db, pinfo.This()); |
| 85 | REQUIRE_DATABASE_OPEN(db->GetState()); |
| 86 | REQUIRE_DATABASE_NOT_BUSY(db->GetState()); |
| 87 | |
| 88 | Napi::String source = pinfo[0].As<Napi::String>(); |
| 89 | Napi::Object database = pinfo[1].As<Napi::Object>(); |
| 90 | bool pragmaMode = pinfo[2].As<Napi::Boolean>().Value(); |
| 91 | bool explainMode = pinfo[3].As<Napi::Boolean>().Value(); |
| 92 | int flags = SQLITE_PREPARE_PERSISTENT; |
| 93 | |
| 94 | if (pragmaMode) { |
| 95 | REQUIRE_DATABASE_NO_ITERATORS_UNLESS_UNSAFE(db->GetState()); |
| 96 | flags = 0; |
| 97 | } |
| 98 | if (explainMode) { |
| 99 | flags = 0; |
| 100 | } |
| 101 | |
| 102 | UseIsolate; |
| 103 | std::string utf8 = source.Utf8Value(); |
| 104 | sqlite3_stmt* handle; |
| 105 | const char* tail; |
| 106 | |
| 107 | if (sqlite3_prepare_v3(db->GetHandle(), utf8.c_str(), utf8.length() + 1, flags, &handle, &tail) != SQLITE_OK) { |
| 108 | db->ThrowDatabaseError(env); |
| 109 | return env.Undefined(); |
| 110 | } |
| 111 | if (handle == NULL) { |
| 112 | return ThrowRangeError(env, "The supplied SQL string contains no statements"); |
| 113 | } |
| 114 | // https://github.com/WiseLibs/better-sqlite3/issues/975#issuecomment-1520934678 |
| 115 | for (char c; (c = *tail); ) { |
| 116 | if (IS_SKIPPED(c)) { |
| 117 | ++tail; |
| 118 | continue; |
| 119 | } |
| 120 | if (c == '/' && tail[1] == '*') { |
| 121 | tail += 2; |
| 122 | for (char c; (c = *tail); ++tail) { |
| 123 | if (c == '*' && tail[1] == '/') { |
| 124 | tail += 2; |
| 125 | break; |
| 126 | } |
| 127 | } |
| 128 | } else if (c == '-' && tail[1] == '-') { |
| 129 | tail += 2; |
| 130 | for (char c; (c = *tail); ++tail) { |
| 131 | if (c == '\n') { |
| 132 | ++tail; |
| 133 | break; |
| 134 | } |
nothing calls this directly
no test coverage detected