Skip to content

Commit fcade3d

Browse files
Implemented the first reader
1 parent 83b891d commit fcade3d

4 files changed

Lines changed: 35 additions & 17 deletions

File tree

include/sqlgen/duckdb/Connection.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@
1111
#include <stdexcept>
1212
#include <string>
1313

14+
#include "../Range.hpp"
1415
#include "../Ref.hpp"
1516
#include "../Result.hpp"
1617
#include "../Transaction.hpp"
1718
#include "../dynamic/Write.hpp"
1819
#include "../internal/iterator_t.hpp"
20+
#include "../internal/to_container.hpp"
1921
#include "../is_connection.hpp"
2022
#include "../transpilation/get_tablename.hpp"
2123
#include "../transpilation/has_reflection_method.hpp"
@@ -51,7 +53,11 @@ class Connection {
5153

5254
template <class ContainerType>
5355
Result<ContainerType> read(const dynamic::SelectFrom& _query) {
54-
return error("TODO");
56+
using ValueType = transpilation::value_t<ContainerType>;
57+
auto res = Ref<duckdb_result>();
58+
duckdb_query(conn_->conn(), to_sql(_query).c_str(), res.get());
59+
return internal::to_container<ContainerType, Iterator<ValueType>>(
60+
Iterator<ValueType>(res, conn_));
5561
}
5662

5763
Result<Nothing> rollback() noexcept;

include/sqlgen/duckdb/Iterator.hpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "../Ref.hpp"
1212
#include "../Result.hpp"
1313
#include "DuckDBConnection.hpp"
14+
#include "from_chunk_ptrs.hpp"
1415
#include "make_chunk_ptrs.hpp"
1516

1617
namespace sqlgen::duckdb {
@@ -20,6 +21,7 @@ class Iterator {
2021
using ConnPtr = Ref<DuckDBConnection>;
2122
using ResultPtr = Ref<duckdb_result>;
2223

24+
public:
2325
struct End {
2426
bool operator==(const Iterator<T>& _it) const noexcept {
2527
return _it == *this;
@@ -34,9 +36,13 @@ class Iterator {
3436
using difference_type = std::ptrdiff_t;
3537
using value_type = Result<T>;
3638

37-
Iterator(const ResultPtr& _res, const ConnPtr& _conn);
39+
Iterator(const ResultPtr& _res, const ConnPtr& _conn)
40+
: res_(_res),
41+
conn_(_conn),
42+
current_batch_(get_next_batch(_res, _conn)),
43+
ix_(0) {}
3844

39-
~Iterator();
45+
~Iterator() = default;
4046

4147
Result<T>& operator*() const noexcept { return (*current_batch_)[ix_]; }
4248

@@ -75,8 +81,10 @@ class Iterator {
7581
}
7682
return batch;
7783
})
78-
.or_else(
79-
[](auto _err) { return Ref<std::vector<Result<T>>>::make({_err}); })
84+
.or_else([](auto _err) {
85+
return Ref<std::vector<Result<T>>>::make(
86+
std::vector<Result<T>>({Result<T>(_err)}));
87+
})
8088
.value();
8189
}
8290

include/sqlgen/duckdb/from_chunk_ptrs.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include <utility>
99

1010
#include "../Result.hpp"
11-
#include "../Tuple.hpp"
1211
#include "ColumnData.hpp"
1312
#include "chunk_ptrs_t.hpp"
1413

@@ -18,8 +17,9 @@ template <class T, class ChunkPtrsT>
1817
struct FromChunkPtrs;
1918

2019
template <class T, class... Ts>
21-
struct FromChunkPtrs<T, Tuple<ColumnData<Ts>...>> {
22-
Result<T> operator(const Tuple<ColumnData<Ts>...>& _chunk_ptrs, idx_t _i) {
20+
struct FromChunkPtrs<T, rfl::Tuple<ColumnData<Ts>...>> {
21+
Result<T> operator()(const rfl::Tuple<ColumnData<Ts>...>& _chunk_ptrs,
22+
idx_t _i) {
2323
return [&]<int... _is>(std::integer_sequence<int, _is...>) {
2424
// TODO: Integrate this into the parser logic.
2525
return T{*(rfl::get<_is>(_chunk_ptrs).data + _i)...};

tests/duckdb/test_write_and_read.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,35 @@
88
namespace test_write_and_read {
99

1010
struct Person {
11-
sqlgen::PrimaryKey<uint32_t> id;
12-
std::string first_name;
13-
std::string last_name;
11+
// sqlgen::PrimaryKey<uint32_t> id;
12+
// std::string first_name;
13+
// std::string last_name;
1414
int age;
1515
};
1616

1717
TEST(duckdb, test_write_and_read) {
18-
const auto people1 = std::vector<Person>(
18+
/*const auto people1 = std::vector<Person>(
1919
{Person{
2020
.id = 0, .first_name = "Homer", .last_name = "Simpson", .age = 45},
2121
Person{.id = 1, .first_name = "Bart", .last_name = "Simpson", .age = 10},
2222
Person{.id = 2, .first_name = "Lisa", .last_name = "Simpson", .age = 8},
2323
Person{
24-
.id = 3, .first_name = "Maggie", .last_name = "Simpson", .age = 0}});
24+
.id = 3, .first_name = "Maggie", .last_name = "Simpson", .age =
25+
0}});*/
2526

26-
using namespace sqlgen;
27+
const auto people1 = std::vector<Person>({Person{.age = 45}});
2728

28-
duckdb::connect().and_then(write(std::ref(people1))).value();
29+
using namespace sqlgen;
2930

30-
/*const auto people2 = sqlgen::read<std::vector<Person>>(conn).value();
31+
const auto people2 = duckdb::connect()
32+
.and_then(write(std::ref(people1)))
33+
.and_then(sqlgen::read<std::vector<Person>>)
34+
.value();
3135

3236
const auto json1 = rfl::json::write(people1);
3337
const auto json2 = rfl::json::write(people2);
3438

35-
EXPECT_EQ(json1, json2);*/
39+
EXPECT_EQ(json1, json2);
3640
}
3741

3842
} // namespace test_write_and_read

0 commit comments

Comments
 (0)