Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: duckdb v 6fe573 #74

Merged
merged 9 commits into from
Feb 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
jupiter marked this conversation as resolved.
Show resolved Hide resolved
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