Skip to content

Commit

Permalink
Result key order is now sorted by insertion time and not alphabetical (
Browse files Browse the repository at this point in the history
…#60)

* Result object keys are no longer ordered alphabetically, but rather maintain insertion order. The behaviour now matches other libraries.

* Formatting.

* Fixed columnName typo.
  • Loading branch information
Chriztiaan authored Nov 11, 2024
1 parent c60d3de commit 9ac4ce7
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 30 deletions.
5 changes: 5 additions & 0 deletions .changeset/selfish-worms-buy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@journeyapps/react-native-quick-sqlite": patch
---

Result object keys are no longer ordered alphabetically, but rather maintain insertion order. The behaviour now matches other libraries.
60 changes: 32 additions & 28 deletions cpp/JSIHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,40 +143,44 @@ jsi::Value createSequelQueryExecutionResult(jsi::Runtime &rt, SQLiteOPResult sta
// Converting row results into objects
size_t rowCount = results->size();
jsi::Object rows = jsi::Object(rt);
if (rowCount > 0)
if (rowCount > 0 && metadata != NULL)
{
auto array = jsi::Array(rt, rowCount);
for (int i = 0; i < rowCount; i++)
{
jsi::Object rowObject = jsi::Object(rt);
auto row = results->at(i);
for (auto const &entry : row)
auto row = results -> at(i);
// Iterate over metadata to maintain column order
for (const auto &column : *metadata)
{
std::string columnName = entry.first;
QuickValue value = entry.second;
if (value.dataType == TEXT)
std::string columnName = column.columnName;
auto it = row.find(columnName);
if (it != row.end())
{
// using value.textValue (std::string) directly allows jsi::String to use length property of std::string (allowing strings with NULLs in them like SQLite does)
rowObject.setProperty(rt, columnName.c_str(), jsi::String::createFromUtf8(rt, value.textValue));
}
else if (value.dataType == INTEGER)
{
rowObject.setProperty(rt, columnName.c_str(), jsi::Value(value.doubleOrIntValue));
}
else if (value.dataType == DOUBLE)
{
rowObject.setProperty(rt, columnName.c_str(), jsi::Value(value.doubleOrIntValue));
}
else if (value.dataType == ARRAY_BUFFER)
{
jsi::Function array_buffer_ctor = rt.global().getPropertyAsFunction(rt, "ArrayBuffer");
jsi::Object o = array_buffer_ctor.callAsConstructor(rt, (int)value.arrayBufferSize).getObject(rt);
jsi::ArrayBuffer buf = o.getArrayBuffer(rt);
// It's a shame we have to copy here: see https://github.com/facebook/hermes/pull/419 and https://github.com/facebook/hermes/issues/564.
memcpy(buf.data(rt), value.arrayBufferValue.get(), value.arrayBufferSize);
rowObject.setProperty(rt, columnName.c_str(), o);
}
else
QuickValue value = it -> second;
if (value.dataType == TEXT)
{
// using value.textValue (std::string) directly allows jsi::String to use length property of std::string (allowing strings with NULLs in them like SQLite does)
rowObject.setProperty(rt, columnName.c_str(), jsi::String::createFromUtf8(rt, value.textValue));
} else if (value.dataType == INTEGER)
{
rowObject.setProperty(rt, columnName.c_str(), jsi::Value(value.doubleOrIntValue));
} else if (value.dataType == DOUBLE)
{
rowObject.setProperty(rt, columnName.c_str(), jsi::Value(value.doubleOrIntValue));
} else if (value.dataType == ARRAY_BUFFER)
{
jsi::Function array_buffer_ctor = rt.global().getPropertyAsFunction(rt, "ArrayBuffer");
jsi::Object o = array_buffer_ctor.callAsConstructor(rt, (int) value.arrayBufferSize).getObject(rt);
jsi::ArrayBuffer buf = o.getArrayBuffer(rt);
// It's a shame we have to copy here: see https://github.com/facebook/hermes/pull/419 and https://github.com/facebook/hermes/issues/564.
memcpy(buf.data(rt), value.arrayBufferValue.get(), value.arrayBufferSize);
rowObject.setProperty(rt, columnName.c_str(), o);
} else
{
rowObject.setProperty(rt, columnName.c_str(), jsi::Value(nullptr));
}
} else
{
rowObject.setProperty(rt, columnName.c_str(), jsi::Value(nullptr));
}
Expand All @@ -194,7 +198,7 @@ jsi::Value createSequelQueryExecutionResult(jsi::Runtime &rt, SQLiteOPResult sta
for (int i = 0; i < column_count; i++) {
auto column = metadata->at(i);
jsi::Object column_object = jsi::Object(rt);
column_object.setProperty(rt, "columnName", jsi::String::createFromUtf8(rt, column.colunmName.c_str()));
column_object.setProperty(rt, "columnName", jsi::String::createFromUtf8(rt, column.columnName.c_str()));
column_object.setProperty(rt, "columnDeclaredType", jsi::String::createFromUtf8(rt, column.columnDeclaredType.c_str()));
column_object.setProperty(rt, "columnIndex", jsi::Value(column.columnIndex));
column_array.setValueAtIndex(rt, i, move(column_object));
Expand Down
2 changes: 1 addition & 1 deletion cpp/JSIHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ struct SequelBatchOperationResult
*/
struct QuickColumnMetadata
{
string colunmName;
string columnName;
int columnIndex;
string columnDeclaredType;
};
Expand Down
2 changes: 1 addition & 1 deletion cpp/sqliteExecute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ sqliteExecuteWithDB(sqlite3 *db, std::string const &query,
const char *tp = sqlite3_column_decltype(statement, i);
column_declared_type = tp != NULL ? tp : "UNKNOWN";
QuickColumnMetadata meta = {
.colunmName = column_name,
.columnName = column_name,
.columnIndex = i,
.columnDeclaredType = column_declared_type,
};
Expand Down

0 comments on commit 9ac4ce7

Please sign in to comment.