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