react-native-nitro-sqlite 9.2.2 → 9.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/CMakeLists.txt +1 -1
- package/cpp/NitroSQLiteException.hpp +1 -2
- package/cpp/{specs → hybridObjects}/HybridNitroSQLite.cpp +64 -16
- package/cpp/{specs → hybridObjects}/HybridNitroSQLite.hpp +6 -6
- package/cpp/hybridObjects/HybridNitroSQLiteQueryResult.cpp +93 -0
- package/cpp/hybridObjects/HybridNitroSQLiteQueryResult.hpp +47 -0
- package/cpp/operations.cpp +16 -12
- package/cpp/operations.hpp +3 -1
- package/cpp/sqliteExecuteBatch.cpp +2 -2
- package/cpp/sqliteExecuteBatch.hpp +2 -2
- package/cpp/types.hpp +4 -14
- package/ios/NitroSQLite.xcodeproj/project.pbxproj +2 -2
- package/lib/commonjs/index.js +0 -25
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/operations/execute.js +19 -32
- package/lib/commonjs/operations/execute.js.map +1 -1
- package/lib/commonjs/operations/executeBatch.js +2 -19
- package/lib/commonjs/operations/executeBatch.js.map +1 -1
- package/lib/commonjs/specs/{NativeQueryResult.nitro.js → NitroSQLiteQueryResult.nitro.js} +1 -1
- package/lib/commonjs/specs/NitroSQLiteQueryResult.nitro.js.map +1 -0
- package/lib/commonjs/types.js +1 -8
- package/lib/commonjs/types.js.map +1 -1
- package/lib/module/index.js +0 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/operations/execute.js +19 -33
- package/lib/module/operations/execute.js.map +1 -1
- package/lib/module/operations/executeBatch.js +2 -19
- package/lib/module/operations/executeBatch.js.map +1 -1
- package/lib/module/specs/NitroSQLiteQueryResult.nitro.js +4 -0
- package/lib/module/specs/NitroSQLiteQueryResult.nitro.js.map +1 -0
- package/lib/module/types.js +0 -12
- package/lib/module/types.js.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +0 -1
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/operations/execute.d.ts +1 -1
- package/lib/typescript/commonjs/operations/execute.d.ts.map +1 -1
- package/lib/typescript/commonjs/operations/executeBatch.d.ts +1 -1
- package/lib/typescript/commonjs/operations/executeBatch.d.ts.map +1 -1
- package/lib/typescript/commonjs/operations/transaction.d.ts.map +1 -1
- package/lib/typescript/commonjs/specs/NitroSQLite.nitro.d.ts +6 -6
- package/lib/typescript/commonjs/specs/NitroSQLite.nitro.d.ts.map +1 -1
- package/lib/typescript/{module/specs/NativeQueryResult.nitro.d.ts → commonjs/specs/NitroSQLiteQueryResult.nitro.d.ts} +7 -13
- package/lib/typescript/commonjs/specs/NitroSQLiteQueryResult.nitro.d.ts.map +1 -0
- package/lib/typescript/commonjs/typeORM.d.ts +1 -1
- package/lib/typescript/commonjs/typeORM.d.ts.map +1 -1
- package/lib/typescript/commonjs/types.d.ts +21 -37
- package/lib/typescript/commonjs/types.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +0 -1
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/operations/execute.d.ts +1 -1
- package/lib/typescript/module/operations/execute.d.ts.map +1 -1
- package/lib/typescript/module/operations/executeBatch.d.ts +1 -1
- package/lib/typescript/module/operations/executeBatch.d.ts.map +1 -1
- package/lib/typescript/module/operations/transaction.d.ts.map +1 -1
- package/lib/typescript/module/specs/NitroSQLite.nitro.d.ts +6 -6
- package/lib/typescript/module/specs/NitroSQLite.nitro.d.ts.map +1 -1
- package/lib/typescript/{commonjs/specs/NativeQueryResult.nitro.d.ts → module/specs/NitroSQLiteQueryResult.nitro.d.ts} +7 -13
- package/lib/typescript/module/specs/NitroSQLiteQueryResult.nitro.d.ts.map +1 -0
- package/lib/typescript/module/typeORM.d.ts +1 -1
- package/lib/typescript/module/typeORM.d.ts.map +1 -1
- package/lib/typescript/module/types.d.ts +21 -37
- package/lib/typescript/module/types.d.ts.map +1 -1
- package/nitrogen/generated/android/RNNitroSQLite+autolinking.cmake +9 -6
- package/nitrogen/generated/android/RNNitroSQLite+autolinking.gradle +1 -1
- package/nitrogen/generated/android/RNNitroSQLiteOnLoad.cpp +2 -4
- package/nitrogen/generated/android/RNNitroSQLiteOnLoad.hpp +1 -1
- package/nitrogen/generated/android/c++/JHybridNitroSQLiteOnLoadSpec.cpp +14 -1
- package/nitrogen/generated/android/c++/JHybridNitroSQLiteOnLoadSpec.hpp +4 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rnnitrosqlite/HybridNitroSQLiteOnLoadSpec.kt +8 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rnnitrosqlite/RNNitroSQLiteOnLoad.kt +1 -1
- package/nitrogen/generated/ios/RNNitroSQLite+autolinking.rb +2 -2
- package/nitrogen/generated/ios/RNNitroSQLite-Swift-Cxx-Bridge.cpp +1 -1
- package/nitrogen/generated/ios/RNNitroSQLite-Swift-Cxx-Bridge.hpp +1 -1
- package/nitrogen/generated/ios/RNNitroSQLite-Swift-Cxx-Umbrella.hpp +1 -1
- package/nitrogen/generated/ios/RNNitroSQLiteAutolinking.mm +1 -1
- package/nitrogen/generated/ios/RNNitroSQLiteAutolinking.swift +5 -1
- package/nitrogen/generated/shared/c++/BatchQueryCommand.hpp +92 -0
- package/nitrogen/generated/shared/c++/BatchQueryResult.hpp +25 -11
- package/nitrogen/generated/shared/c++/ColumnType.hpp +5 -7
- package/nitrogen/generated/shared/c++/FileLoadResult.hpp +28 -14
- package/nitrogen/generated/shared/c++/HybridNitroSQLiteOnLoadSpec.cpp +1 -1
- package/nitrogen/generated/shared/c++/HybridNitroSQLiteOnLoadSpec.hpp +1 -1
- package/nitrogen/generated/shared/c++/HybridNitroSQLiteQueryResultSpec.cpp +24 -0
- package/nitrogen/generated/shared/c++/HybridNitroSQLiteQueryResultSpec.hpp +73 -0
- package/nitrogen/generated/shared/c++/HybridNitroSQLiteSpec.cpp +1 -1
- package/nitrogen/generated/shared/c++/HybridNitroSQLiteSpec.hpp +12 -16
- package/nitrogen/generated/shared/c++/NitroSQLiteQueryColumnMetadata.hpp +93 -0
- package/package.json +5 -5
- package/src/index.ts +0 -6
- package/src/operations/execute.ts +23 -58
- package/src/operations/executeBatch.ts +3 -41
- package/src/operations/session.ts +1 -1
- package/src/operations/transaction.ts +1 -1
- package/src/specs/NitroSQLite.nitro.ts +9 -12
- package/src/specs/{NativeQueryResult.nitro.ts → NitroSQLiteQueryResult.nitro.ts} +15 -17
- package/src/typeORM.ts +1 -1
- package/src/types.ts +28 -45
- package/cpp/specs/HybridNativeQueryResult.cpp +0 -21
- package/cpp/specs/HybridNativeQueryResult.hpp +0 -27
- package/lib/commonjs/nullHandling.js +0 -33
- package/lib/commonjs/nullHandling.js.map +0 -1
- package/lib/commonjs/specs/NativeQueryResult.nitro.js.map +0 -1
- package/lib/module/nullHandling.js +0 -25
- package/lib/module/nullHandling.js.map +0 -1
- package/lib/module/specs/NativeQueryResult.nitro.js +0 -4
- package/lib/module/specs/NativeQueryResult.nitro.js.map +0 -1
- package/lib/typescript/commonjs/nullHandling.d.ts +0 -8
- package/lib/typescript/commonjs/nullHandling.d.ts.map +0 -1
- package/lib/typescript/commonjs/specs/NativeQueryResult.nitro.d.ts.map +0 -1
- package/lib/typescript/module/nullHandling.d.ts +0 -8
- package/lib/typescript/module/nullHandling.d.ts.map +0 -1
- package/lib/typescript/module/specs/NativeQueryResult.nitro.d.ts.map +0 -1
- package/nitrogen/generated/shared/c++/HybridNativeQueryResultSpec.cpp +0 -24
- package/nitrogen/generated/shared/c++/HybridNativeQueryResultSpec.hpp +0 -77
- package/nitrogen/generated/shared/c++/NativeBatchQueryCommand.hpp +0 -81
- package/nitrogen/generated/shared/c++/SQLiteNullValue.hpp +0 -69
- package/nitrogen/generated/shared/c++/SQLiteQueryColumnMetadata.hpp +0 -79
- package/src/nullHandling.ts +0 -35
package/android/CMakeLists.txt
CHANGED
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
#include <exception>
|
|
4
4
|
#include <iostream>
|
|
5
|
-
#include <string>
|
|
6
5
|
#include <optional>
|
|
6
|
+
#include <string>
|
|
7
7
|
|
|
8
8
|
const std::string NITRO_SQLITE_EXCEPTION_PREFIX = "[NativeNitroSQLiteException]";
|
|
9
9
|
|
|
10
|
-
|
|
11
10
|
enum NitroSQLiteExceptionType {
|
|
12
11
|
UnknownError,
|
|
13
12
|
DatabaseCannotBeOpened,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#include "HybridNitroSQLite.hpp"
|
|
2
|
-
#include "
|
|
2
|
+
#include "HybridNitroSQLiteQueryResult.hpp"
|
|
3
3
|
#include "NitroSQLiteException.hpp"
|
|
4
4
|
#include "importSqlFile.hpp"
|
|
5
5
|
#include "logs.hpp"
|
|
@@ -8,11 +8,54 @@
|
|
|
8
8
|
#include "sqliteExecuteBatch.hpp"
|
|
9
9
|
#include <iostream>
|
|
10
10
|
#include <map>
|
|
11
|
+
#include <optional>
|
|
11
12
|
#include <string>
|
|
13
|
+
#include <variant>
|
|
12
14
|
#include <vector>
|
|
13
15
|
|
|
14
16
|
namespace margelo::nitro::rnnitrosqlite {
|
|
15
17
|
|
|
18
|
+
// Copy any JS-backed ArrayBuffers on the JS thread so they can be safely
|
|
19
|
+
// accessed from the background thread used by Promise::async.
|
|
20
|
+
static std::optional<SQLiteQueryParams> copyArrayBufferParamsForBackground(const std::optional<SQLiteQueryParams>& params) {
|
|
21
|
+
if (!params) {
|
|
22
|
+
return std::nullopt;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
SQLiteQueryParams copiedParams;
|
|
26
|
+
copiedParams.reserve(params->size());
|
|
27
|
+
|
|
28
|
+
for (const auto& value : *params) {
|
|
29
|
+
if (std::holds_alternative<std::shared_ptr<ArrayBuffer>>(value)) {
|
|
30
|
+
const auto& buffer = std::get<std::shared_ptr<ArrayBuffer>>(value);
|
|
31
|
+
const auto copiedBuffer = ArrayBuffer::copy(buffer);
|
|
32
|
+
copiedParams.push_back(copiedBuffer);
|
|
33
|
+
} else {
|
|
34
|
+
copiedParams.push_back(value);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return copiedParams;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Overload for batch execution: copy ArrayBuffer params inside each BatchQuery.
|
|
42
|
+
static std::vector<BatchQuery> copyArrayBufferParamsForBackground(const std::vector<BatchQuery>& commands) {
|
|
43
|
+
std::vector<BatchQuery> copiedCommands;
|
|
44
|
+
copiedCommands.reserve(commands.size());
|
|
45
|
+
|
|
46
|
+
for (const auto& command : commands) {
|
|
47
|
+
BatchQuery copiedCommand = command;
|
|
48
|
+
|
|
49
|
+
if (command.params) {
|
|
50
|
+
copiedCommand.params = copyArrayBufferParamsForBackground(command.params);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
copiedCommands.push_back(std::move(copiedCommand));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return copiedCommands;
|
|
57
|
+
}
|
|
58
|
+
|
|
16
59
|
const std::string getDocPath(const std::optional<std::string>& location) {
|
|
17
60
|
std::string tempDocPath = std::string(HybridNitroSQLite::docPath);
|
|
18
61
|
if (location) {
|
|
@@ -50,23 +93,23 @@ void HybridNitroSQLite::detach(const std::string& mainDbName, const std::string&
|
|
|
50
93
|
sqliteDetachDb(mainDbName, alias);
|
|
51
94
|
};
|
|
52
95
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const std::optional<SQLiteQueryParams>& params) {
|
|
57
|
-
SQLiteExecuteQueryResult result = sqliteExecute(dbName, query, params);
|
|
58
|
-
return std::make_shared<HybridNativeQueryResult>(std::move(result));
|
|
96
|
+
std::shared_ptr<HybridNitroSQLiteQueryResultSpec> HybridNitroSQLite::execute(const std::string& dbName, const std::string& query,
|
|
97
|
+
const std::optional<SQLiteQueryParams>& params) {
|
|
98
|
+
return sqliteExecute(dbName, query, params);
|
|
59
99
|
};
|
|
60
100
|
|
|
61
|
-
std::shared_ptr<Promise<std::shared_ptr<
|
|
101
|
+
std::shared_ptr<Promise<std::shared_ptr<HybridNitroSQLiteQueryResultSpec>>>
|
|
62
102
|
HybridNitroSQLite::executeAsync(const std::string& dbName, const std::string& query, const std::optional<SQLiteQueryParams>& params) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
103
|
+
const auto copiedParams = copyArrayBufferParamsForBackground(params);
|
|
104
|
+
|
|
105
|
+
return Promise<std::shared_ptr<HybridNitroSQLiteQueryResultSpec>>::async(
|
|
106
|
+
[=, this]() -> std::shared_ptr<HybridNitroSQLiteQueryResultSpec> {
|
|
107
|
+
auto result = sqliteExecute(dbName, query, copiedParams);
|
|
108
|
+
return result;
|
|
109
|
+
});
|
|
67
110
|
};
|
|
68
111
|
|
|
69
|
-
BatchQueryResult HybridNitroSQLite::executeBatch(const std::string& dbName, const std::vector<
|
|
112
|
+
BatchQueryResult HybridNitroSQLite::executeBatch(const std::string& dbName, const std::vector<BatchQueryCommand>& batchParams) {
|
|
70
113
|
const auto commands = batchParamsToCommands(batchParams);
|
|
71
114
|
|
|
72
115
|
auto result = sqliteExecuteBatch(dbName, commands);
|
|
@@ -74,10 +117,15 @@ BatchQueryResult HybridNitroSQLite::executeBatch(const std::string& dbName, cons
|
|
|
74
117
|
};
|
|
75
118
|
|
|
76
119
|
std::shared_ptr<Promise<BatchQueryResult>> HybridNitroSQLite::executeBatchAsync(const std::string& dbName,
|
|
77
|
-
const std::vector<
|
|
120
|
+
const std::vector<BatchQueryCommand>& batchParams) {
|
|
121
|
+
// Convert BatchQueryCommand objects on the JS thread and copy any JS-backed
|
|
122
|
+
// ArrayBuffers into native buffers before going off-thread.
|
|
123
|
+
const auto commands = batchParamsToCommands(batchParams);
|
|
124
|
+
const auto copiedCommands = copyArrayBufferParamsForBackground(commands);
|
|
125
|
+
|
|
78
126
|
return Promise<BatchQueryResult>::async([=, this]() -> BatchQueryResult {
|
|
79
|
-
auto result =
|
|
80
|
-
return result;
|
|
127
|
+
auto result = sqliteExecuteBatch(dbName, copiedCommands);
|
|
128
|
+
return BatchQueryResult(result.rowsAffected);
|
|
81
129
|
});
|
|
82
130
|
};
|
|
83
131
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
-
#include "
|
|
3
|
+
#include "HybridNitroSQLiteQueryResultSpec.hpp"
|
|
4
4
|
#include "HybridNitroSQLiteSpec.hpp"
|
|
5
5
|
#include "types.hpp"
|
|
6
6
|
|
|
@@ -28,15 +28,15 @@ public:
|
|
|
28
28
|
|
|
29
29
|
void detach(const std::string& mainDbName, const std::string& alias) override;
|
|
30
30
|
|
|
31
|
-
std::shared_ptr<
|
|
32
|
-
|
|
31
|
+
std::shared_ptr<HybridNitroSQLiteQueryResultSpec> execute(const std::string& dbName, const std::string& query,
|
|
32
|
+
const std::optional<SQLiteQueryParams>& params) override;
|
|
33
33
|
|
|
34
|
-
std::shared_ptr<Promise<std::shared_ptr<
|
|
34
|
+
std::shared_ptr<Promise<std::shared_ptr<HybridNitroSQLiteQueryResultSpec>>>
|
|
35
35
|
executeAsync(const std::string& dbName, const std::string& query, const std::optional<SQLiteQueryParams>& params) override;
|
|
36
36
|
|
|
37
|
-
BatchQueryResult executeBatch(const std::string& dbName, const std::vector<
|
|
37
|
+
BatchQueryResult executeBatch(const std::string& dbName, const std::vector<BatchQueryCommand>& commands) override;
|
|
38
38
|
std::shared_ptr<Promise<BatchQueryResult>> executeBatchAsync(const std::string& dbName,
|
|
39
|
-
const std::vector<
|
|
39
|
+
const std::vector<BatchQueryCommand>& commands) override;
|
|
40
40
|
|
|
41
41
|
FileLoadResult loadFile(const std::string& dbName, const std::string& location) override;
|
|
42
42
|
std::shared_ptr<Promise<FileLoadResult>> loadFileAsync(const std::string& dbName, const std::string& location) override;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#include "HybridNitroSQLiteQueryResult.hpp"
|
|
2
|
+
#include <NitroModules/ArrayBuffer.hpp>
|
|
3
|
+
#include <NitroModules/Null.hpp>
|
|
4
|
+
#include <NitroModules/Promise.hpp>
|
|
5
|
+
#include <unordered_map>
|
|
6
|
+
#include <variant>
|
|
7
|
+
#include <vector>
|
|
8
|
+
|
|
9
|
+
namespace margelo::nitro::rnnitrosqlite {
|
|
10
|
+
|
|
11
|
+
namespace {
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Compute the approximate external memory size of a single result row.
|
|
15
|
+
* This includes:
|
|
16
|
+
* - Column name string capacities,
|
|
17
|
+
* - Heap usage for the actual SQLiteValue contents.
|
|
18
|
+
*/
|
|
19
|
+
size_t getRowExternalMemorySize(const SQLiteQueryResultRow& row) {
|
|
20
|
+
size_t bucketMemory = row.bucket_count() * sizeof(void*);
|
|
21
|
+
constexpr size_t nodePadding = 24;
|
|
22
|
+
size_t nodesMemory = row.size() * (sizeof(std::pair<std::string, SQLiteValue>) * nodePadding);
|
|
23
|
+
return bucketMemory + nodesMemory;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Compute the approximate external memory size of the full result set.
|
|
28
|
+
* We add:
|
|
29
|
+
* - The vector's backing storage,
|
|
30
|
+
* - All rows (column names + values).
|
|
31
|
+
*/
|
|
32
|
+
size_t getResultsExternalMemorySize(const SQLiteQueryResults& results) {
|
|
33
|
+
size_t size = sizeof(SQLiteQueryResults);
|
|
34
|
+
|
|
35
|
+
const auto resultCapacity = results.capacity();
|
|
36
|
+
size += resultCapacity * sizeof(SQLiteQueryResultRow);
|
|
37
|
+
|
|
38
|
+
for (const auto& row : results) {
|
|
39
|
+
size += getRowExternalMemorySize(row);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return size;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Compute the approximate external memory size of the table metadata.
|
|
47
|
+
* We include:
|
|
48
|
+
* - Column name string capacities (map keys),
|
|
49
|
+
* - Metadata contents, especially the `name` string on each metadata entry.
|
|
50
|
+
*/
|
|
51
|
+
size_t getMetadataExternalMemorySize(const SQLiteQueryTableMetadata& metadata) {
|
|
52
|
+
size_t size = 0;
|
|
53
|
+
|
|
54
|
+
for (const auto& [columnName, columnMeta] : metadata) {
|
|
55
|
+
|
|
56
|
+
size += columnName.capacity();
|
|
57
|
+
size += columnMeta.name.capacity();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return size;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
} // namespace
|
|
64
|
+
|
|
65
|
+
std::optional<double> HybridNitroSQLiteQueryResult::getInsertId() {
|
|
66
|
+
return _insertId;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
double HybridNitroSQLiteQueryResult::getRowsAffected() {
|
|
70
|
+
return _rowsAffected;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
SQLiteQueryResults HybridNitroSQLiteQueryResult::getResults() {
|
|
74
|
+
return _results;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
std::optional<SQLiteQueryTableMetadata> HybridNitroSQLiteQueryResult::getMetadata() {
|
|
78
|
+
return _metadata;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
size_t HybridNitroSQLiteQueryResult::getExternalMemorySize() noexcept {
|
|
82
|
+
size_t size = sizeof(*this);
|
|
83
|
+
|
|
84
|
+
size += getResultsExternalMemorySize(_results);
|
|
85
|
+
|
|
86
|
+
if (_metadata) {
|
|
87
|
+
size += getMetadataExternalMemorySize(*_metadata);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return size;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
} // namespace margelo::nitro::rnnitrosqlite
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "HybridNitroSQLiteQueryResultSpec.hpp"
|
|
4
|
+
#include "types.hpp"
|
|
5
|
+
#include <map>
|
|
6
|
+
|
|
7
|
+
using namespace margelo::rnnitrosqlite;
|
|
8
|
+
|
|
9
|
+
namespace margelo::nitro::rnnitrosqlite {
|
|
10
|
+
|
|
11
|
+
class HybridNitroSQLiteQueryResult : public HybridNitroSQLiteQueryResultSpec {
|
|
12
|
+
public:
|
|
13
|
+
HybridNitroSQLiteQueryResult() : HybridObject(TAG) {}
|
|
14
|
+
HybridNitroSQLiteQueryResult(SQLiteQueryResults results, std::optional<double> insertId, double rowsAffected,
|
|
15
|
+
std::optional<SQLiteQueryTableMetadata> metadata)
|
|
16
|
+
: HybridObject(TAG), _insertId(insertId), _rowsAffected(rowsAffected), _results(std::move(results)), _metadata(metadata) {}
|
|
17
|
+
|
|
18
|
+
private:
|
|
19
|
+
std::optional<double> _insertId;
|
|
20
|
+
double _rowsAffected;
|
|
21
|
+
SQLiteQueryResults _results;
|
|
22
|
+
std::optional<SQLiteQueryTableMetadata> _metadata;
|
|
23
|
+
|
|
24
|
+
public:
|
|
25
|
+
// Properties
|
|
26
|
+
std::optional<double> getInsertId() override;
|
|
27
|
+
double getRowsAffected() override;
|
|
28
|
+
SQLiteQueryResults getResults() override;
|
|
29
|
+
std::optional<SQLiteQueryTableMetadata> getMetadata() override;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Approximate the native memory used by this query result.
|
|
33
|
+
*
|
|
34
|
+
* We account for:
|
|
35
|
+
* - The size of this C++ object (`sizeof(*this)`),
|
|
36
|
+
* - All rows and columns (including column name strings),
|
|
37
|
+
* - String values stored in the result set,
|
|
38
|
+
* - ArrayBuffers used for BLOB columns (object overhead + raw byte size),
|
|
39
|
+
* - Column metadata strings.
|
|
40
|
+
*
|
|
41
|
+
* This is a best-effort estimate and intentionally focuses on external
|
|
42
|
+
* heap allocations that can put pressure on the JS GC.
|
|
43
|
+
*/
|
|
44
|
+
size_t getExternalMemorySize() noexcept override;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
} // namespace margelo::nitro::rnnitrosqlite
|
package/cpp/operations.cpp
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#include "operations.hpp"
|
|
2
2
|
#include "NitroSQLiteException.hpp"
|
|
3
|
+
#include "hybridObjects/HybridNitroSQLiteQueryResult.hpp"
|
|
3
4
|
#include "logs.hpp"
|
|
4
5
|
#include "utils.hpp"
|
|
5
6
|
#include <NitroModules/ArrayBuffer.hpp>
|
|
@@ -105,7 +106,7 @@ void bindStatement(sqlite3_stmt* statement, const SQLiteQueryParams& values) {
|
|
|
105
106
|
for (int valueIndex = 0; valueIndex < values.size(); valueIndex++) {
|
|
106
107
|
int sqliteIndex = valueIndex + 1;
|
|
107
108
|
SQLiteValue value = values.at(valueIndex);
|
|
108
|
-
if (std::holds_alternative<
|
|
109
|
+
if (std::holds_alternative<NullType>(value)) {
|
|
109
110
|
sqlite3_bind_null(statement, sqliteIndex);
|
|
110
111
|
} else if (std::holds_alternative<bool>(value)) {
|
|
111
112
|
sqlite3_bind_int(statement, sqliteIndex, std::get<bool>(value));
|
|
@@ -121,8 +122,8 @@ void bindStatement(sqlite3_stmt* statement, const SQLiteQueryParams& values) {
|
|
|
121
122
|
}
|
|
122
123
|
}
|
|
123
124
|
|
|
124
|
-
|
|
125
|
-
|
|
125
|
+
std::shared_ptr<HybridNitroSQLiteQueryResult> sqliteExecute(const std::string& dbName, const std::string& query,
|
|
126
|
+
const std::optional<SQLiteQueryParams>& params) {
|
|
126
127
|
if (dbMap.count(dbName) == 0) {
|
|
127
128
|
throw NitroSQLiteException::DatabaseNotOpen(dbName);
|
|
128
129
|
}
|
|
@@ -183,15 +184,21 @@ SQLiteExecuteQueryResult sqliteExecute(const std::string& dbName, const std::str
|
|
|
183
184
|
case SQLITE_BLOB: {
|
|
184
185
|
int blob_size = sqlite3_column_bytes(statement, i);
|
|
185
186
|
const void* blob = sqlite3_column_blob(statement, i);
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
187
|
+
// Copy the SQLite BLOB into a new native ArrayBuffer.
|
|
188
|
+
// This avoids manual memory management and unsafe pointer handling.
|
|
189
|
+
if (blob_size > 0) {
|
|
190
|
+
const auto* blob_data = reinterpret_cast<const uint8_t*>(blob);
|
|
191
|
+
row[column_name] = ArrayBuffer::copy(blob_data, static_cast<size_t>(blob_size));
|
|
192
|
+
} else {
|
|
193
|
+
// Represent empty BLOBs as an empty, but valid, ArrayBuffer.
|
|
194
|
+
row[column_name] = ArrayBuffer::allocate(0);
|
|
195
|
+
}
|
|
189
196
|
break;
|
|
190
197
|
}
|
|
191
198
|
case SQLITE_NULL:
|
|
192
199
|
// Intentionally left blank to switch to default case
|
|
193
200
|
default:
|
|
194
|
-
row[column_name] =
|
|
201
|
+
row[column_name] = NullType::null;
|
|
195
202
|
break;
|
|
196
203
|
}
|
|
197
204
|
i++;
|
|
@@ -205,7 +212,7 @@ SQLiteExecuteQueryResult sqliteExecute(const std::string& dbName, const std::str
|
|
|
205
212
|
column_name = sqlite3_column_name(statement, i);
|
|
206
213
|
const char* tp = sqlite3_column_decltype(statement, i);
|
|
207
214
|
column_declared_type = mapSQLiteTypeToColumnType(tp);
|
|
208
|
-
auto columnMeta =
|
|
215
|
+
auto columnMeta = NitroSQLiteQueryColumnMetadata(std::move(column_name), std::move(column_declared_type), i);
|
|
209
216
|
|
|
210
217
|
if (!metadata) {
|
|
211
218
|
metadata = std::make_optional<SQLiteQueryTableMetadata>();
|
|
@@ -229,10 +236,7 @@ SQLiteExecuteQueryResult sqliteExecute(const std::string& dbName, const std::str
|
|
|
229
236
|
|
|
230
237
|
int rowsAffected = sqlite3_changes(db);
|
|
231
238
|
long long latestInsertRowId = sqlite3_last_insert_rowid(db);
|
|
232
|
-
return
|
|
233
|
-
.insertId = static_cast<double>(latestInsertRowId),
|
|
234
|
-
.results = std::move(results),
|
|
235
|
-
.metadata = std::move(metadata)};
|
|
239
|
+
return std::make_shared<HybridNitroSQLiteQueryResult>(results, static_cast<double>(latestInsertRowId), rowsAffected, metadata);
|
|
236
240
|
}
|
|
237
241
|
|
|
238
242
|
SQLiteOperationResult sqliteExecuteLiteral(const std::string& dbName, const std::string& query) {
|
package/cpp/operations.hpp
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
+
#include "hybridObjects/HybridNitroSQLiteQueryResult.hpp"
|
|
3
4
|
#include "types.hpp"
|
|
4
5
|
|
|
5
6
|
namespace margelo::rnnitrosqlite {
|
|
@@ -15,7 +16,8 @@ void sqliteAttachDb(const std::string& mainDBName, const std::string& docPath, c
|
|
|
15
16
|
|
|
16
17
|
void sqliteDetachDb(const std::string& mainDBName, const std::string& alias);
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
std::shared_ptr<HybridNitroSQLiteQueryResult> sqliteExecute(const std::string& dbName, const std::string& query,
|
|
20
|
+
const std::optional<SQLiteQueryParams>& params);
|
|
19
21
|
|
|
20
22
|
SQLiteOperationResult sqliteExecuteLiteral(const std::string& dbName, const std::string& query);
|
|
21
23
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
namespace margelo::rnnitrosqlite {
|
|
10
10
|
|
|
11
|
-
std::vector<BatchQuery> batchParamsToCommands(const std::vector<
|
|
11
|
+
std::vector<BatchQuery> batchParamsToCommands(const std::vector<BatchQueryCommand>& batchParams) {
|
|
12
12
|
auto commands = std::vector<BatchQuery>();
|
|
13
13
|
|
|
14
14
|
for (auto& command : batchParams) {
|
|
@@ -49,7 +49,7 @@ SQLiteOperationResult sqliteExecuteBatch(const std::string& dbName, const std::v
|
|
|
49
49
|
auto metadata = std::optional<SQLiteQueryTableMetadata>(std::nullopt);
|
|
50
50
|
try {
|
|
51
51
|
auto result = sqliteExecute(dbName, command.sql, command.params);
|
|
52
|
-
rowsAffected += result
|
|
52
|
+
rowsAffected += result->getRowsAffected();
|
|
53
53
|
} catch (NitroSQLiteException& e) {
|
|
54
54
|
sqliteExecuteLiteral(dbName, "ROLLBACK");
|
|
55
55
|
throw e;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
#pragma once
|
|
5
5
|
|
|
6
|
-
#include "
|
|
6
|
+
#include "BatchQueryCommand.hpp"
|
|
7
7
|
#include "types.hpp"
|
|
8
8
|
|
|
9
9
|
using namespace facebook;
|
|
@@ -20,7 +20,7 @@ struct BatchQuery {
|
|
|
20
20
|
* Local Helper method to translate JSI objects BatchQuery datastructure
|
|
21
21
|
* MUST be called in the JavaScript Thread
|
|
22
22
|
*/
|
|
23
|
-
std::vector<BatchQuery> batchParamsToCommands(const std::vector<
|
|
23
|
+
std::vector<BatchQuery> batchParamsToCommands(const std::vector<BatchQueryCommand>& batchParams);
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Execute a batch of commands in a exclusive transaction
|
package/cpp/types.hpp
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
3
|
#include "ColumnType.hpp"
|
|
4
|
-
#include "
|
|
5
|
-
#include "SQLiteQueryColumnMetadata.hpp"
|
|
4
|
+
#include "NitroSQLiteQueryColumnMetadata.hpp"
|
|
6
5
|
#include <NitroModules/ArrayBuffer.hpp>
|
|
7
6
|
#include <string>
|
|
8
7
|
|
|
@@ -11,24 +10,15 @@ using namespace margelo::nitro::rnnitrosqlite;
|
|
|
11
10
|
|
|
12
11
|
namespace margelo::rnnitrosqlite {
|
|
13
12
|
|
|
14
|
-
using SQLiteValue = std::variant<
|
|
13
|
+
using SQLiteValue = std::variant<nitro::NullType, bool, std::shared_ptr<ArrayBuffer>, std::string, double>;
|
|
15
14
|
using SQLiteQueryParams = std::vector<SQLiteValue>;
|
|
16
15
|
using SQLiteQueryResultRow = std::unordered_map<std::string, SQLiteValue>;
|
|
17
16
|
using SQLiteQueryResults = std::vector<SQLiteQueryResultRow>;
|
|
18
|
-
using SQLiteQueryTableMetadata = std::unordered_map<std::string,
|
|
17
|
+
using SQLiteQueryTableMetadata = std::unordered_map<std::string, NitroSQLiteQueryColumnMetadata>;
|
|
19
18
|
|
|
20
19
|
struct SQLiteOperationResult {
|
|
21
20
|
int rowsAffected;
|
|
22
|
-
|
|
23
|
-
int commands;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
struct SQLiteExecuteQueryResult {
|
|
27
|
-
int rowsAffected;
|
|
28
|
-
double insertId;
|
|
29
|
-
|
|
30
|
-
SQLiteQueryResults results;
|
|
31
|
-
std::optional<SQLiteQueryTableMetadata> metadata;
|
|
21
|
+
int commands = 0;
|
|
32
22
|
};
|
|
33
23
|
|
|
34
24
|
// constexpr function that maps SQLiteColumnType to string literals
|
|
@@ -173,7 +173,7 @@
|
|
|
173
173
|
path = ../nitrogen;
|
|
174
174
|
sourceTree = "<group>";
|
|
175
175
|
};
|
|
176
|
-
83BC6E5F2C8F78A200B954D2 /*
|
|
176
|
+
83BC6E5F2C8F78A200B954D2 /* hybridObjects */ = {
|
|
177
177
|
isa = PBXGroup;
|
|
178
178
|
children = (
|
|
179
179
|
83BC6E5A2C8F78A200B954D2 /* HybridNitroSQLite.cpp */,
|
|
@@ -188,7 +188,7 @@
|
|
|
188
188
|
83BC6E702C8F78A200B954D2 /* cpp */ = {
|
|
189
189
|
isa = PBXGroup;
|
|
190
190
|
children = (
|
|
191
|
-
83BC6E5F2C8F78A200B954D2 /*
|
|
191
|
+
83BC6E5F2C8F78A200B954D2 /* hybridObjects */,
|
|
192
192
|
83BC6E602C8F78A200B954D2 /* JSIHelper.cpp */,
|
|
193
193
|
83BC6E612C8F78A200B954D2 /* JSIHelper.h */,
|
|
194
194
|
83BC6E622C8F78A200B954D2 /* logs.h */,
|
package/lib/commonjs/index.js
CHANGED
|
@@ -3,12 +3,6 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
Object.defineProperty(exports, "NITRO_SQLITE_NULL", {
|
|
7
|
-
enumerable: true,
|
|
8
|
-
get: function () {
|
|
9
|
-
return _nullHandling.NITRO_SQLITE_NULL;
|
|
10
|
-
}
|
|
11
|
-
});
|
|
12
6
|
exports.NitroSQLite = void 0;
|
|
13
7
|
Object.defineProperty(exports, "NitroSQLiteError", {
|
|
14
8
|
enumerable: true,
|
|
@@ -16,24 +10,6 @@ Object.defineProperty(exports, "NitroSQLiteError", {
|
|
|
16
10
|
return _NitroSQLiteError.default;
|
|
17
11
|
}
|
|
18
12
|
});
|
|
19
|
-
Object.defineProperty(exports, "enableSimpleNullHandling", {
|
|
20
|
-
enumerable: true,
|
|
21
|
-
get: function () {
|
|
22
|
-
return _nullHandling.enableSimpleNullHandling;
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
Object.defineProperty(exports, "isNitroSQLiteNull", {
|
|
26
|
-
enumerable: true,
|
|
27
|
-
get: function () {
|
|
28
|
-
return _nullHandling.isNitroSQLiteNull;
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
Object.defineProperty(exports, "isSimpleNullHandlingEnabled", {
|
|
32
|
-
enumerable: true,
|
|
33
|
-
get: function () {
|
|
34
|
-
return _nullHandling.isSimpleNullHandlingEnabled;
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
13
|
Object.defineProperty(exports, "open", {
|
|
38
14
|
enumerable: true,
|
|
39
15
|
get: function () {
|
|
@@ -52,7 +28,6 @@ var _session = require("./operations/session.js");
|
|
|
52
28
|
var _execute = require("./operations/execute.js");
|
|
53
29
|
var _OnLoad = require("./OnLoad");
|
|
54
30
|
var _executeBatch = require("./operations/executeBatch.js");
|
|
55
|
-
var _nullHandling = require("./nullHandling.js");
|
|
56
31
|
var _NitroSQLiteError = _interopRequireDefault(require("./NitroSQLiteError.js"));
|
|
57
32
|
var _typeORM = require("./typeORM.js");
|
|
58
33
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_transaction","require","_nitro","_session","_execute","_OnLoad","_executeBatch","
|
|
1
|
+
{"version":3,"names":["_transaction","require","_nitro","_session","_execute","_OnLoad","_executeBatch","_NitroSQLiteError","_interopRequireDefault","_typeORM","e","__esModule","default","init","NitroSQLite","exports","HybridNitroSQLite","native","open","transaction","execute","executeAsync","executeBatch","executeBatchAsync"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AACA,IAAAC,MAAA,GAAAD,OAAA;AACA,IAAAE,QAAA,GAAAF,OAAA;AACA,IAAAG,QAAA,GAAAH,OAAA;AACA,IAAAI,OAAA,GAAAJ,OAAA;AACA,IAAAK,aAAA,GAAAL,OAAA;AAmBA,IAAAM,iBAAA,GAAAC,sBAAA,CAAAP,OAAA;AAEA,IAAAQ,QAAA,GAAAR,OAAA;AAAyC,SAAAO,uBAAAE,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAnBzC,IAAAG,YAAI,EAAC,CAAC;AAEC,MAAMC,WAAW,GAAAC,OAAA,CAAAD,WAAA,GAAG;EACzB,GAAGE,wBAAiB;EACpBC,MAAM,EAAED,wBAAiB;EACzB;EACA;EACAE,IAAI,EAAJA,aAAI;EACJ;EACAC,WAAW,EAAXA,wBAAW;EACXC,OAAO,EAAPA,gBAAO;EACPC,YAAY,EAAZA,qBAAY;EACZC,YAAY,EAAZA,0BAAY;EACZC,iBAAiB,EAAjBA;AACF,CAAC","ignoreList":[]}
|
|
@@ -5,53 +5,40 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.execute = execute;
|
|
7
7
|
exports.executeAsync = executeAsync;
|
|
8
|
-
var _nullHandling = require("../nullHandling.js");
|
|
9
8
|
var _nitro = require("../nitro.js");
|
|
10
9
|
var _NitroSQLiteError = _interopRequireDefault(require("../NitroSQLiteError.js"));
|
|
11
10
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
11
|
function execute(dbName, query, params) {
|
|
13
|
-
const transformedParams = (0, _nullHandling.isSimpleNullHandlingEnabled)() ? toNativeQueryParams(params) : params;
|
|
14
12
|
try {
|
|
15
|
-
const nativeResult = _nitro.HybridNitroSQLite.execute(dbName, query,
|
|
16
|
-
return
|
|
13
|
+
const nativeResult = _nitro.HybridNitroSQLite.execute(dbName, query, params);
|
|
14
|
+
return buildJSQueryResult(nativeResult);
|
|
17
15
|
} catch (error) {
|
|
18
16
|
throw _NitroSQLiteError.default.fromError(error);
|
|
19
17
|
}
|
|
20
18
|
}
|
|
21
19
|
async function executeAsync(dbName, query, params) {
|
|
22
|
-
const transformedParams = (0, _nullHandling.isSimpleNullHandlingEnabled)() ? toNativeQueryParams(params) : params;
|
|
23
20
|
try {
|
|
24
|
-
const nativeResult = await _nitro.HybridNitroSQLite.executeAsync(dbName, query,
|
|
25
|
-
return
|
|
21
|
+
const nativeResult = await _nitro.HybridNitroSQLite.executeAsync(dbName, query, params);
|
|
22
|
+
return buildJSQueryResult(nativeResult);
|
|
26
23
|
} catch (error) {
|
|
27
24
|
throw _NitroSQLiteError.default.fromError(error);
|
|
28
25
|
}
|
|
29
26
|
}
|
|
30
|
-
function
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
results
|
|
37
|
-
}) {
|
|
38
|
-
let data = results;
|
|
39
|
-
if ((0, _nullHandling.isSimpleNullHandlingEnabled)()) {
|
|
40
|
-
data = results.map(row => Object.fromEntries(Object.entries(row).map(([key, value]) => {
|
|
41
|
-
if ((0, _nullHandling.isNitroSQLiteNull)(value)) {
|
|
42
|
-
return [key, null];
|
|
43
|
-
}
|
|
44
|
-
return [key, value];
|
|
45
|
-
})));
|
|
46
|
-
}
|
|
47
|
-
return {
|
|
48
|
-
insertId,
|
|
49
|
-
rowsAffected,
|
|
50
|
-
rows: {
|
|
51
|
-
_array: data,
|
|
52
|
-
length: data.length,
|
|
53
|
-
item: idx => data[idx]
|
|
54
|
-
}
|
|
27
|
+
function buildJSQueryResult(result) {
|
|
28
|
+
const resultWithRows = result;
|
|
29
|
+
resultWithRows.rows = {
|
|
30
|
+
_array: result.results,
|
|
31
|
+
length: result.results.length,
|
|
32
|
+
item: idx => result.results[idx]
|
|
55
33
|
};
|
|
34
|
+
return resultWithRows;
|
|
35
|
+
|
|
36
|
+
// return Object.assign(result, {
|
|
37
|
+
// rows: {
|
|
38
|
+
// _array: result.results,
|
|
39
|
+
// length: result.results.length,
|
|
40
|
+
// item: (idx: number) => result.results[idx],
|
|
41
|
+
// },
|
|
42
|
+
// })
|
|
56
43
|
}
|
|
57
44
|
//# sourceMappingURL=execute.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["
|
|
1
|
+
{"version":3,"names":["_nitro","require","_NitroSQLiteError","_interopRequireDefault","e","__esModule","default","execute","dbName","query","params","nativeResult","HybridNitroSQLite","buildJSQueryResult","error","NitroSQLiteError","fromError","executeAsync","result","resultWithRows","rows","_array","results","length","item","idx"],"sourceRoot":"../../../src","sources":["operations/execute.ts"],"mappings":";;;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAEA,IAAAC,iBAAA,GAAAC,sBAAA,CAAAF,OAAA;AAAkD,SAAAE,uBAAAC,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAG3C,SAASG,OAAOA,CACrBC,MAAc,EACdC,KAAa,EACbC,MAA0B,EACR;EAClB,IAAI;IACF,MAAMC,YAAY,GAAGC,wBAAiB,CAACL,OAAO,CAACC,MAAM,EAAEC,KAAK,EAAEC,MAAM,CAAC;IACrE,OAAOG,kBAAkB,CAAMF,YAAY,CAAC;EAC9C,CAAC,CAAC,OAAOG,KAAK,EAAE;IACd,MAAMC,yBAAgB,CAACC,SAAS,CAACF,KAAK,CAAC;EACzC;AACF;AAEO,eAAeG,YAAYA,CAChCT,MAAc,EACdC,KAAa,EACbC,MAA0B,EACC;EAC3B,IAAI;IACF,MAAMC,YAAY,GAAG,MAAMC,wBAAiB,CAACK,YAAY,CACvDT,MAAM,EACNC,KAAK,EACLC,MACF,CAAC;IACD,OAAOG,kBAAkB,CAAMF,YAAY,CAAC;EAC9C,CAAC,CAAC,OAAOG,KAAK,EAAE;IACd,MAAMC,yBAAgB,CAACC,SAAS,CAACF,KAAK,CAAC;EACzC;AACF;AAEA,SAASD,kBAAkBA,CACzBK,MAA8B,EACZ;EAClB,MAAMC,cAAc,GAAGD,MAA0B;EAEjDC,cAAc,CAACC,IAAI,GAAG;IACpBC,MAAM,EAAEH,MAAM,CAACI,OAAgB;IAC/BC,MAAM,EAAEL,MAAM,CAACI,OAAO,CAACC,MAAM;IAC7BC,IAAI,EAAGC,GAAW,IAAKP,MAAM,CAACI,OAAO,CAACG,GAAG;EAC3C,CAAC;EAED,OAAON,cAAc;;EAErB;EACA;EACA;EACA;EACA;EACA;EACA;AACF","ignoreList":[]}
|