diff --git a/msc-plugin/libaquery.vcxproj b/msc-plugin/libaquery.vcxproj
index 26da616..ee0fd5f 100644
--- a/msc-plugin/libaquery.vcxproj
+++ b/msc-plugin/libaquery.vcxproj
@@ -345,10 +345,12 @@
+
+
@@ -361,6 +363,7 @@
+
diff --git a/server/DataSource_conn.h b/server/DataSource_conn.h
new file mode 100644
index 0000000..ff66606
--- /dev/null
+++ b/server/DataSource_conn.h
@@ -0,0 +1,43 @@
+#ifndef __DATASOURCE_CONN_H__
+#define __DATASOURCE_CONN_H__
+struct Context;
+
+struct AQQueryResult {
+ void* res;
+ unsigned ref;
+};
+enum DataSourceType {
+ Invalid,
+ MonetDB,
+ MariaDB,
+ DuckDB,
+ SQLite
+};
+
+struct DataSource {
+ void* server = nullptr;
+ Context* cxt = nullptr;
+ bool status = false;
+ char* query = nullptr;
+ DataSourceType type = Invalid;
+
+ void* res = nullptr;
+ void* ret_col = nullptr;
+ long long cnt = 0;
+ const char* last_error = nullptr;
+
+ void* handle;
+
+ DataSource() = default;
+ explicit DataSource(Context* cxt = nullptr) = delete;
+
+ virtual void connect(Context* cxt) = 0;
+ virtual void exec(const char* q) = 0;
+ virtual void* getCol(int col_idx, int type) = 0;
+ // virtual long long getFirstElement() = 0;
+ virtual void close() = 0;
+ virtual bool haserror() = 0;
+ // virtual void print_results(const char* sep = " ", const char* end = "\n");
+ virtual ~DataSource() = 0;
+};
+#endif //__DATASOURCE_CONN_H__
\ No newline at end of file
diff --git a/server/duckdb_conn.cpp b/server/duckdb_conn.cpp
new file mode 100644
index 0000000..b395340
--- /dev/null
+++ b/server/duckdb_conn.cpp
@@ -0,0 +1,89 @@
+#include "duckdb_conn.h"
+#include "../deps/duckdb.hpp"
+#include "libaquery.h"
+#include "types.h"
+#include
+#include
+using namespace std;
+
+void DuckdbServer::connect(Context* cxt) {
+ duckdb_database* db_handle =
+ static_cast(malloc(sizeof(duckdb_database)));
+ this->handle = db_handle;
+ bool status = duckdb_open(nullptr, db_handle);
+ duckdb_connection* conn_handle;
+ status = status || duckdb_connect(*db_handle, conn_handle);
+ this->server = conn_handle;
+ if (status != 0) {
+ puts("DuckdbServer: Error! Creating/Connecting to INMemory DB.");
+ }
+}
+
+DuckdbServer::DuckdbServer(Context* cxt) {
+ this->cxt = cxt;
+ connect(cxt);
+}
+
+void DuckdbServer::exec(const char* q) {
+ //TODO: Add res to GC queue with ref count.
+ auto res = static_cast(malloc(sizeof(duckdb_result)));
+ auto status = duckdb_query(*static_cast(this->server), q, res);
+ if (status) {
+ last_error = duckdb_result_error(res);
+ this->res = nullptr;
+ this->cnt = 0;
+ }
+ else {
+ this->res = res;
+ this->cnt = duckdb_row_count(res);
+ }
+}
+
+void* DuckdbServer::getCol(int col_idx, int ty) {
+ auto res = static_cast(this->res);
+ if (ty == types::Type_t::ASTR) {
+ std::string_view* ret =
+ static_cast(malloc(sizeof(std::string_view) * cnt));
+ for(uint32_t i = 0; i < cnt; ++i)
+ ret[i] = {duckdb_value_varchar(res, col_idx, i)};
+ return ret;
+ }
+ else
+ {
+ auto chk = duckdb_result_chunk_count(*res);
+ const auto v_size = duckdb_vector_size();
+ auto sz = types::AType_sizes[ty];
+ char* ret = static_cast(malloc(sz * cnt));
+ uint32_t j = 0;
+ for (uint32_t i = 0; i < chk; ++i) {
+ auto data = duckdb_vector_get_data(
+ duckdb_data_chunk_get_vector(
+ duckdb_result_get_chunk(*res, i),
+ col_idx)
+ );
+ const auto curr_ptr = i * v_size;
+ const auto rem_size = int(cnt) - curr_ptr;
+ memcpy(ret + i * v_size, data,
+ (rem_size < v_size ? rem_size : v_size) * sz);
+ }
+ return ret;
+ }
+}
+
+bool DuckdbServer::haserror() {
+ if (last_error) {
+ puts(last_error);
+ last_error = nullptr;
+ return true;
+ }
+ return false;
+}
+
+void DuckdbServer::close() {
+ duckdb_disconnect(static_cast(server));
+ duckdb_close(static_cast(handle));
+}
+
+DuckdbServer::~DuckdbServer() {
+ this->close();
+}
diff --git a/server/duckdb_conn.h b/server/duckdb_conn.h
new file mode 100644
index 0000000..96f27c7
--- /dev/null
+++ b/server/duckdb_conn.h
@@ -0,0 +1,16 @@
+#ifndef __DUCKDB_CONN_H__
+#define __DUCKDB_CONN_H__
+#include "DataSource_conn.h"
+
+struct DuckdbServer : DataSource {
+ explicit DuckdbServer(Context* cxt = nullptr);
+ void connect(Context* cxt);
+ void exec(const char* q);
+ void* getCol(int col_idx, int type);
+ long long getFirstElement();
+ void close();
+ bool haserror();
+ void print_results(const char* sep = " ", const char* end = "\n");
+ ~DuckdbServer();
+};
+#endif //__DUCKDB_CONN_H__
\ No newline at end of file
diff --git a/server/libaquery.h b/server/libaquery.h
index 3211058..cd3ce40 100644
--- a/server/libaquery.h
+++ b/server/libaquery.h
@@ -81,6 +81,11 @@ struct Config{
int buffer_sizes[];
};
+struct AQQueryResult {
+ void* res;
+ uint32_t ref;
+};
+
struct Session{
struct Statistic{
size_t total_active;
diff --git a/server/monetdb_conn.h b/server/monetdb_conn.h
index 4fe55f6..5a6b228 100644
--- a/server/monetdb_conn.h
+++ b/server/monetdb_conn.h
@@ -23,7 +23,6 @@ struct Server{
void close();
bool haserror();
static bool havehge();
- void test(const char*);
void print_results(const char* sep = " ", const char* end = "\n");
friend void print_monetdb_results(void* _srv, const char* sep, const char* end, int limit);
~Server();