Skip to content

Commit

Permalink
feat: duckdb v 6fe573 (#74)
Browse files Browse the repository at this point in the history
  • Loading branch information
rprovodenko authored Feb 3, 2021
1 parent 0b306a5 commit 3b5ceca
Show file tree
Hide file tree
Showing 24 changed files with 194 additions and 96 deletions.
63 changes: 63 additions & 0 deletions .github/workflows/auto-release-bleeding-edge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: Auto Release

on: workflow_dispatch

jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
ref: release/duckdb-bleeding-edge
token: ${{secrets.BRANCH_PROTECTION_TOKEN}}
- name: Setup node
uses: actions/setup-node@v1
with:
node-version: 12
registry-url: https://npm.pkg.github.com/
scope: "@deepcrawl"
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Restore keys from cache
uses: actions/cache@v1
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Temporarily disable "include administrators" branch protection
uses: benjefferies/branch-protection-bot@master
if: always()
with:
access-token: ${{ secrets.BRANCH_PROTECTION_TOKEN }}
enforce_admins: false
branch: release/duckdb-bleeding-edge
- name: Install modules with frozen lockfile and build
run: |
echo -e "always-auth=true\n//registry.npmjs.org/:_authToken=$NODE_AUTH_TOKEN" >> ~/.npmrc
cat ~/.npmrc
yarn config set username $USERNAME
yarn config set email $EMAIL
yarn config set version-git-message "Release: v%s"
git config --global user.name "github-actions[bot]"
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
yarn install --frozen-lockfile
yarn standard-version
yarn publish --tag provisional-release --access public
git push --follow-tags -f
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
GITHUB_TOKEN: ${{ secrets.UPLOAD_ARTIFACTS_TOKEN }}
USERNAME: ${{secrets.USERNAME}}
EMAIL: ${{secrets.EMAIL}}
GH_TOKEN: ${{secrets.BRANCH_PROTECTION_TOKEN}}
- name: Enable "include administrators" branch protection
uses: benjefferies/branch-protection-bot@master
if: always() # Force to always run this step to ensure "include administrators" is always turned back on
with:
access-token: ${{ secrets.BRANCH_PROTECTION_TOKEN }}
enforce_admins: true
branch: release/duckdb-bleeding-edge
2 changes: 1 addition & 1 deletion .github/workflows/auto-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout master
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ on:
push:
branches:
- master
- release/*
pull_request:

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout master
- name: Checkout
uses: actions/checkout@master
- name: Setup node
uses: actions/setup-node@v1
Expand Down
19 changes: 12 additions & 7 deletions addon/connection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -106,18 +106,23 @@ Napi::Value Connection::Execute(const Napi::CallbackInfo &info) {
}

Napi::Value Connection::Close(const Napi::CallbackInfo &info) {
for (auto &result : *results) {
if (result != nullptr) {
result->close();
}
// the following gives segfaults for some reason now
// for (auto &result : *results) {
// if (result != nullptr) {
// result->close();
// }
// }
if (connection) {
connection.reset();
}
if (database) {
database.reset();
}
connection.reset();
database.reset();
return info.Env().Undefined();
}
Napi::Value Connection::IsClosed(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
bool isClosed = connection == nullptr || connection->context->is_invalidated;
bool isClosed = connection == nullptr;
return Napi::Boolean::New(env, isClosed);
}
} // namespace NodeDuckDB
4 changes: 2 additions & 2 deletions addon/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ class Connection : public Napi::ObjectWrap<Connection> {
Napi::Value Close(const Napi::CallbackInfo &info);
Napi::Value IsClosed(const Napi::CallbackInfo &info);

shared_ptr<duckdb::DuckDB> database;
shared_ptr<duckdb::Connection> connection;
duckdb::shared_ptr<duckdb::DuckDB> database;
duckdb::shared_ptr<duckdb::Connection> connection;
std::shared_ptr<std::vector<ResultIterator *>> results;
};
} // namespace NodeDuckDB
Expand Down
27 changes: 15 additions & 12 deletions addon/duckdb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ DuckDB::DuckDB(const Napi::CallbackInfo &info)
}

Napi::Value DuckDB::Close(const Napi::CallbackInfo &info) {
database.reset();
if (database) {
database.reset();
}
return info.Env().Undefined();
}
Napi::Value DuckDB::IsClosed(const Napi::CallbackInfo &info) {
Expand All @@ -78,45 +80,46 @@ bool DuckDB::IsClosed() { return database == nullptr; }

Napi::Value DuckDB::GetAccessMode(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
return Napi::Number::New(env,
static_cast<double>(database->config.access_mode));
return Napi::Number::New(
env, static_cast<double>(database->instance->config.access_mode));
}
Napi::Value DuckDB::GetCheckPointWALSize(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
return Napi::Number::New(env, database->config.checkpoint_wal_size);
return Napi::Number::New(env, database->instance->config.checkpoint_wal_size);
}
Napi::Value DuckDB::GetUseDirectIO(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
return Napi::Boolean::New(env, database->config.use_direct_io);
return Napi::Boolean::New(env, database->instance->config.use_direct_io);
}
Napi::Value DuckDB::GetMaximumMemory(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
return Napi::Number::New(env, database->config.maximum_memory);
return Napi::Number::New(env, database->instance->config.maximum_memory);
}
Napi::Value DuckDB::GetUseTemporaryDirectory(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
return Napi::Boolean::New(env, database->config.use_temporary_directory);
return Napi::Boolean::New(env,
database->instance->config.use_temporary_directory);
}
Napi::Value DuckDB::GetTemporaryDirectory(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
return Napi::String::New(env, database->config.temporary_directory);
return Napi::String::New(env, database->instance->config.temporary_directory);
}
Napi::Value DuckDB::GetCollation(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
return Napi::String::New(env, database->config.collation);
return Napi::String::New(env, database->instance->config.collation);
}
Napi::Value DuckDB::GetDefaultOrderType(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
return Napi::Number::New(
env, static_cast<double>(database->config.default_order_type));
env, static_cast<double>(database->instance->config.default_order_type));
}
Napi::Value DuckDB::GetDefaultNullOrder(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
return Napi::Number::New(
env, static_cast<double>(database->config.default_null_order));
env, static_cast<double>(database->instance->config.default_null_order));
}
Napi::Value DuckDB::GetEnableCopy(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
return Napi::Boolean::New(env, database->config.enable_copy);
return Napi::Boolean::New(env, database->instance->config.enable_copy);
}
} // namespace NodeDuckDB
2 changes: 1 addition & 1 deletion addon/duckdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class DuckDB : public Napi::ObjectWrap<DuckDB> {
public:
static Napi::Object Init(Napi::Env env, Napi::Object exports);
DuckDB(const Napi::CallbackInfo &info);
shared_ptr<duckdb::DuckDB> database;
duckdb::shared_ptr<duckdb::DuckDB> database;
static Napi::FunctionReference constructor;
bool IsClosed(void);

Expand Down
53 changes: 27 additions & 26 deletions addon/result_iterator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "duckdb.hpp"
#include "duckdb/common/types/hugeint.hpp"
#include <iostream>
#include <string.h>
using namespace std;

namespace NodeDuckDB {
Expand Down Expand Up @@ -32,16 +33,16 @@ Napi::Object ResultIterator::Create() { return constructor.New({}); }

typedef uint64_t idx_t;

int32_t GetDate(int64_t timestamp) {
return (int32_t)(((int64_t)timestamp) >> 32);
}
int64_t GetDate(int64_t timestamp) { return timestamp; }

int32_t GetTime(int64_t timestamp) { return (int32_t)(timestamp & 0xFFFFFFFF); }
int64_t GetTime(int64_t timestamp) {
return (int64_t)(timestamp & 0xFFFFFFFFFFFFFFFF);
}

#define EPOCH_DATE 719528
#define SECONDS_PER_DAY (60 * 60 * 24)

int64_t Epoch(int32_t date) {
int64_t Epoch(int64_t date) {
return ((int64_t)date - EPOCH_DATE) * SECONDS_PER_DAY;
}

Expand All @@ -52,17 +53,25 @@ Napi::Value ResultIterator::FetchRow(const Napi::CallbackInfo &info) {
return env.Undefined();
}
if (!current_chunk || chunk_offset >= current_chunk->size()) {
current_chunk = result->Fetch();
try {
current_chunk = result->Fetch();
} catch (const duckdb::InvalidInputException &e) {
if (strncmp(e.what(),
"Invalid Input Error: Attempting to fetch from an "
"unsuccessful or closed streaming query result",
50) == 0) {
Napi::Error::New(
env, "Attempting to fetch from an unsuccessful or closed streaming "
"query result: only "
"one stream can be active on one connection at a time)")
.ThrowAsJavaScriptException();
return env.Undefined();
}
throw e;
}
chunk_offset = 0;
}
if (!current_chunk) {
Napi::Error::New(
env, "No data has been returned (possibly stream has been closed: only "
"one stream can be active on one connection at a time)")
.ThrowAsJavaScriptException();
return env.Undefined();
}
if (current_chunk->size() == 0) {
if (!current_chunk || current_chunk->size() == 0) {
return env.Null();
}
Napi::Value row;
Expand Down Expand Up @@ -182,21 +191,13 @@ Napi::Value ResultIterator::getCellValue(Napi::Env env, duckdb::idx_t col_idx) {
throw runtime_error("expected int64 for timestamp");
}
int64_t tval = val.GetValue<int64_t>();
int64_t date = Epoch(GetDate(tval)) * 1000;
int32_t time = GetTime(tval);
return Napi::Number::New(env, date + time);
}
case duckdb::LogicalTypeId::DATE: {
if (result->types[col_idx].InternalType() != duckdb::PhysicalType::INT32) {
throw runtime_error("expected int32 for date");
}
return Napi::Number::New(env, Epoch(val.GetValue<int32_t>()) * 1000);
return Napi::Number::New(env, tval / 1000);
}
case duckdb::LogicalTypeId::TIME: {
if (result->types[col_idx].InternalType() != duckdb::PhysicalType::INT32) {
throw runtime_error("expected int32 for time");
if (result->types[col_idx].InternalType() != duckdb::PhysicalType::INT64) {
throw runtime_error("expected int64 for time");
}
int64_t tval = val.GetValue<int32_t>();
int64_t tval = val.GetValue<int64_t>();
return Napi::Number::New(env, GetTime(tval));
}
case duckdb::LogicalTypeId::INTERVAL: {
Expand Down
4 changes: 2 additions & 2 deletions addon/result_iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class ResultIterator : public Napi::ObjectWrap<ResultIterator> {
static Napi::Object Init(Napi::Env env, Napi::Object exports);
ResultIterator(const Napi::CallbackInfo &info);
static Napi::Object Create();
unique_ptr<duckdb::QueryResult> result;
duckdb::unique_ptr<duckdb::QueryResult> result;
ResultFormat rowResultFormat;
void close();

Expand All @@ -23,7 +23,7 @@ class ResultIterator : public Napi::ObjectWrap<ResultIterator> {
Napi::Value GetType(const Napi::CallbackInfo &info);
Napi::Value Close(const Napi::CallbackInfo &info);
Napi::Value IsClosed(const Napi::CallbackInfo &info);
unique_ptr<duckdb::DataChunk> current_chunk;
duckdb::unique_ptr<duckdb::DataChunk> current_chunk;
uint64_t chunk_offset = 0;
Napi::Value getCellValue(Napi::Env env, duckdb::idx_t col_idx);
Napi::Value getRowArray(Napi::Env env);
Expand Down
24 changes: 13 additions & 11 deletions addon/type-converters.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,31 @@
#include "duckdb.h"
#include "duckdb.hpp"

string NodeDuckDB::TypeConverters::convertString(const Napi::Env &env,
const Napi::Object &options,
const string propertyName) {
duckdb::string
NodeDuckDB::TypeConverters::convertString(const Napi::Env &env,
const Napi::Object &options,
const std::string propertyName) {
if (!options.Get(propertyName).IsString()) {
throw Napi::TypeError::New(env, "Invalid " + propertyName +
": must be a string");
}
return options.Get(propertyName).ToString().Utf8Value();
}

int32_t NodeDuckDB::TypeConverters::convertNumber(const Napi::Env &env,
const Napi::Object &options,
const string propertyName) {
int32_t
NodeDuckDB::TypeConverters::convertNumber(const Napi::Env &env,
const Napi::Object &options,
const std::string propertyName) {
if (!options.Get(propertyName).IsNumber()) {
throw Napi::TypeError::New(env, "Invalid " + propertyName +
": must be a number");
}
return options.Get(propertyName).ToNumber().Int32Value();
}

bool NodeDuckDB::TypeConverters::convertBoolean(const Napi::Env &env,
const Napi::Object &options,
const string propertyName) {
bool NodeDuckDB::TypeConverters::convertBoolean(
const Napi::Env &env, const Napi::Object &options,
const std::string propertyName) {
if (!options.Get(propertyName).IsBoolean()) {
throw Napi::TypeError::New(env, "Invalid " + propertyName +
": must be a boolean");
Expand All @@ -34,9 +36,9 @@ bool NodeDuckDB::TypeConverters::convertBoolean(const Napi::Env &env,

int32_t NodeDuckDB::TypeConverters::convertEnum(const Napi::Env &env,
const Napi::Object &options,
const string propertyName,
const std::string propertyName,
const int min, const int max) {
const string errorMessage =
const std::string errorMessage =
"Invalid " + propertyName + ": must be of appropriate enum type";
if (!options.Get(propertyName).IsNumber()) {
throw Napi::TypeError::New(env, errorMessage);
Expand Down
11 changes: 6 additions & 5 deletions addon/type-converters.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@

namespace NodeDuckDB {
namespace TypeConverters {
string convertString(const Napi::Env &env, const Napi::Object &options,
const string propertyName);
duckdb::string convertString(const Napi::Env &env, const Napi::Object &options,
const std::string propertyName);
int32_t convertNumber(const Napi::Env &env, const Napi::Object &options,
const string propertyName);
const std::string propertyName);
bool convertBoolean(const Napi::Env &env, const Napi::Object &options,
const string propertyName);
const std::string propertyName);
int32_t convertEnum(const Napi::Env &env, const Napi::Object &options,
const string propertyName, const int min, const int max);
const std::string propertyName, const int min,
const int max);
void setDBConfig(const Napi::Env &env, const Napi::Object &config,
duckdb::DBConfig &nativeConfig);
} // namespace TypeConverters
Expand Down
Loading

0 comments on commit 3b5ceca

Please sign in to comment.