Skip to content
Open
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
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
12 changes: 10 additions & 2 deletions turbodbc/cursor.py → cnvxaturbodbc/cursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
make_parameter_set,
make_row_based_result_set,
set_arrow_parameters,
set_numpy_parameters
set_numpy_parameters,
)

from .exceptions import InterfaceError, translate_exceptions
Expand Down Expand Up @@ -115,7 +115,7 @@ def _execute(self):
return self

@translate_exceptions
def execute(self, sql, parameters=None):
def execute(self, sql, parameters=None, timeout: int = 0):
"""
Execute an SQL command or query

Expand All @@ -129,6 +129,14 @@ def execute(self, sql, parameters=None):
self.rowcount = -1
self._assert_valid()
self.impl.prepare(sql)

if timeout > 0:
# Use the new method that sets SQL_ATTR_QUERY_TIMEOUT
self.impl.prepare_with_timeout(sql, timeout)
else:
# Fallback to old method that sets no special timeout
self.impl.prepare(sql)

if parameters:
buffer = make_parameter_set(self.impl)
buffer.add_set(parameters)
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
21 changes: 21 additions & 0 deletions cpp/turbodbc/Library/src/cursor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,27 @@ void cursor::prepare(std::string const & sql)
} else {
statement->prepare(sql);
}

command_ = std::make_shared<command>(statement, configuration_);
}

// NEW METHOD with user-specified timeout
void cursor::prepare_with_timeout(std::string const & sql, std::int32_t timeout_seconds)
{
reset();
auto statement = connection_->make_statement();
if (configuration_.options.prefer_unicode) {
statement->prepare(as_utf16(sql));
} else {
statement->prepare(sql);
}

// Only set the attribute if the user gave a positive timeout
if (timeout_seconds > 0) {
statement->set_attribute(SQL_ATTR_QUERY_TIMEOUT,
static_cast<std::intptr_t>(timeout_seconds));
}

command_ = std::make_shared<command>(statement, configuration_);
}

Expand Down
99 changes: 99 additions & 0 deletions cpp/turbodbc/Library/src/cursor_backup.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#include <turbodbc/cursor.h>
#include <turbodbc/make_description.h>

#include <turbodbc/buffer_size.h>

#include <cpp_odbc/statement.h>
#include <cpp_odbc/error.h>

#include <boost/variant/get.hpp>
#include <sqlext.h>
#include <stdexcept>

#include <cstring>
#include <sstream>
#include <codecvt>

#include <simdutf.h>

namespace {

std::u16string as_utf16(std::string utf8_encoded) {
size_t expected_utf16_chars = simdutf::utf16_length_from_utf8(utf8_encoded.data(), utf8_encoded.size());
std::unique_ptr<char16_t[]> utf16{new char16_t[expected_utf16_chars]};
size_t utf16_chars = simdutf::convert_utf8_to_utf16le(utf8_encoded.data(), utf8_encoded.size(), utf16.get());
return std::u16string(utf16.get(), utf16_chars);
}
}

namespace turbodbc {

cursor::cursor(std::shared_ptr<cpp_odbc::connection const> connection,
turbodbc::configuration configuration) :
connection_(connection),
configuration_(std::move(configuration)),
command_()
{
}

cursor::~cursor() = default;

void cursor::prepare(std::string const & sql)
{
reset();
auto statement = connection_->make_statement();
if (configuration_.options.prefer_unicode) {
statement->prepare(as_utf16(sql));
} else {
statement->prepare(sql);
}

statement->set_attribute(SQL_ATTR_QUERY_TIMEOUT, static_cast<std::intptr_t>(5));

command_ = std::make_shared<command>(statement, configuration_);
}

void cursor::execute()
{
command_->execute();
auto raw_result_set = command_->get_results();
if (raw_result_set) {
results_ = raw_result_set;
}
}

std::shared_ptr<result_sets::result_set> cursor::get_result_set() const
{
return command_->get_results();
}

bool cursor::more_results() const
{
return command_->more_results();
}

int64_t cursor::get_row_count()
{
return command_->get_row_count();
}

std::shared_ptr<cpp_odbc::connection const> cursor::get_connection() const
{
return connection_;
}

std::shared_ptr<turbodbc::command> cursor::get_command()
{
return command_;
}

void cursor::reset()
{
results_.reset();
if(command_) {
command_->finalize();
}
command_.reset();
}

}
2 changes: 2 additions & 0 deletions cpp/turbodbc/Library/turbodbc/cursor.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class cursor {

void prepare(std::string const &sql);

void prepare_with_timeout(std::string const &sql, std::int32_t timeout_seconds);

void execute();

void reset();
Expand Down
50 changes: 50 additions & 0 deletions cpp/turbodbc/Library/turbodbc/cursor_backup.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#pragma once

#include <turbodbc/configuration.h>
#include <turbodbc/command.h>
#include <turbodbc/column_info.h>
#include <turbodbc/result_sets/result_set.h>

#include <cpp_odbc/connection.h>

#include <memory>


namespace turbodbc {

/**
* TODO: Cursor needs proper unit tests
*/
class cursor {
public:
cursor(std::shared_ptr<cpp_odbc::connection const> connection,
turbodbc::configuration configuration);

void prepare(std::string const &sql);

void execute();

void reset();

void add_parameter_set(std::vector <nullable_field> const &parameter_set);

int64_t get_row_count();

bool more_results() const;

std::shared_ptr <result_sets::result_set> get_result_set() const;

std::shared_ptr<cpp_odbc::connection const> get_connection() const;

std::shared_ptr <turbodbc::command> get_command();

~cursor();

private:
std::shared_ptr<cpp_odbc::connection const> connection_;
turbodbc::configuration configuration_;
std::shared_ptr <turbodbc::command> command_;
std::shared_ptr <result_sets::result_set> results_;
};

}
5 changes: 5 additions & 0 deletions cpp/turbodbc_python/Library/src/python_bindings/cursor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ void for_cursor(pybind11::module & module)
{
pybind11::class_<turbodbc::cursor>(module, "Cursor")
.def("prepare", &turbodbc::cursor::prepare, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("prepare_with_timeout", &turbodbc::cursor::prepare_with_timeout,
pybind11::call_guard<pybind11::gil_scoped_release>(),
pybind11::arg("sql"),
pybind11::arg("timeout_seconds") = 0,
"Prepare the given SQL with a custom statement timeout (seconds)")
.def("execute", &turbodbc::cursor::execute, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("_reset", &turbodbc::cursor::reset, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_row_count", &turbodbc::cursor::get_row_count)
Expand Down
22 changes: 11 additions & 11 deletions meson.build
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
project(
'turbodbc', 'cpp',
'cnvxaturbodbc', 'cpp',
license: 'MIT',
meson_version: '>= 1.1.0',
default_options: [
Expand Down Expand Up @@ -184,16 +184,16 @@ py.extension_module(

py.install_sources(
[
'turbodbc/options.py',
'turbodbc/connect.py',
'turbodbc/__init__.py',
'turbodbc/data_types.py',
'turbodbc/api_constants.py',
'turbodbc/connection.py',
'turbodbc/exceptions.py',
'turbodbc/constructors.py',
'turbodbc/cursor.py',
'cnvxaturbodbc/options.py',
'cnvxaturbodbc/connect.py',
'cnvxaturbodbc/__init__.py',
'cnvxaturbodbc/data_types.py',
'cnvxaturbodbc/api_constants.py',
'cnvxaturbodbc/connection.py',
'cnvxaturbodbc/exceptions.py',
'cnvxaturbodbc/constructors.py',
'cnvxaturbodbc/cursor.py',
],
subdir: 'turbodbc',
subdir: 'cnvxaturbodbc',
)

2 changes: 1 addition & 1 deletion pixi.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[project]
name = "turbodbc"
name = "cnvxaturbodbc"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this rename about?

version = "0.1.0"
description = "Add a short description here"
authors = ["Uwe L. Korn <uwe.korn@quantco.com>"]
Expand Down
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ requires = [
build-backend = "mesonpy"

[project]
name = "turbodbc"
version = "5.1.2"
name = "cnvxaturbodbc"
version = "1.0.2"
description = "turbodbc is a Python DB API 2.0 compatible ODBC driver"
readme = "README.md"
requires-python = ">=3.10"
Expand Down Expand Up @@ -41,7 +41,7 @@ exclude = '''
| dist
)/
'''
target-version = ['py39']
target-version = ['py311']

[tool.isort]
multi_line_output = 3
Expand Down