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

Attempt to harmonize fetching of data with RPostgres #242

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Depends:
R (>= 2.8.0)
Imports:
bit64,
blob,
DBI (>= 1.1.0),
hms (>= 0.5.0),
lubridate,
Expand Down
117 changes: 117 additions & 0 deletions src/DbColumn.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#include "pch.h"
#include "DbColumn.h"
#include "DbColumnDataSource.h"
#include "DbColumnStorage.h"


DbColumn::DbColumn(DATA_TYPE dt, const int n_max_, DbColumnDataSourceFactory* factory, const int j)
: source(factory->create(j)),
n(0)
{
if (dt == DT_BOOL)
dt = DT_UNKNOWN;
storage.push_back(new DbColumnStorage(dt, 0, n_max_, *source));
}

DbColumn::~DbColumn() {
}

void DbColumn::set_col_value() {
DbColumnStorage* last = get_last_storage();
DATA_TYPE dt = last->get_item_data_type();
data_types_seen.insert(dt);

DbColumnStorage* next = last->append_col();
if (last != next) storage.push_back(next);
}

void DbColumn::finalize(const int n_) {
n = n_;
}

void DbColumn::warn_type_conflicts(const String& name) const {
std::set<DATA_TYPE> my_data_types_seen = data_types_seen;
DATA_TYPE dt = get_last_storage()->get_data_type();

switch (dt) {
case DT_REAL:
my_data_types_seen.erase(DT_INT);
break;

case DT_INT64:
my_data_types_seen.erase(DT_INT);
break;

default:
break;
}

my_data_types_seen.erase(DT_UNKNOWN);
my_data_types_seen.erase(DT_BOOL);
my_data_types_seen.erase(dt);

if (my_data_types_seen.size() == 0) return;

String name_utf8 = name;
name_utf8.set_encoding(CE_UTF8);

std::stringstream ss;
ss << "Column `" << name_utf8.get_cstring() << "`: " <<
"mixed type, first seen values of type " << format_data_type(dt) << ", " <<
"coercing other values of type ";

bool first = true;
for (std::set<DATA_TYPE>::const_iterator it = my_data_types_seen.begin(); it != my_data_types_seen.end(); ++it) {
if (!first) ss << ", ";
else first = false;
ss << format_data_type(*it);
}

warning(ss.str());
}

DbColumn::operator SEXP() const {
DATA_TYPE dt = get_last_storage()->get_data_type();
SEXP ret = PROTECT(DbColumnStorage::allocate(n, dt));
int pos = 0;
for (size_t k = 0; k < storage.size(); ++k) {
const DbColumnStorage& current = storage[k];
pos += current.copy_to(ret, dt, pos);
}
UNPROTECT(1);
return ret;
}

DATA_TYPE DbColumn::get_type() const {
const DATA_TYPE dt = get_last_storage()->get_data_type();
return dt;
}

const char* DbColumn::format_data_type(const DATA_TYPE dt) {
switch (dt) {
case DT_UNKNOWN:
return "unknown";
case DT_BOOL:
return "boolean";
case DT_INT:
return "integer";
case DT_INT64:
return "integer64";
case DT_REAL:
return "real";
case DT_STRING:
return "string";
case DT_BLOB:
return "blob";
default:
return "<unknown type>";
}
}

DbColumnStorage* DbColumn::get_last_storage() {
return &storage.end()[-1];
}

const DbColumnStorage* DbColumn::get_last_storage() const {
return &storage.end()[-1];
}
40 changes: 40 additions & 0 deletions src/DbColumn.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#ifndef DB_COLUMN_H
#define DB_COLUMN_H


#include "DbColumnDataType.h"
#include "DbColumnDataSourceFactory.h"
#include <boost/shared_ptr.hpp>
#include <boost/ptr_container/ptr_vector.hpp>

class DbColumnDataSourceFactory;
class DbColumnDataSource;
class DbColumnStorage;

class DbColumn {
private:
boost::shared_ptr<DbColumnDataSource> source;
boost::ptr_vector<DbColumnStorage> storage;
int n;
std::set<DATA_TYPE> data_types_seen;

public:
DbColumn(DATA_TYPE dt_, const int n_max_, DbColumnDataSourceFactory* factory, const int j);
~DbColumn();

public:
void set_col_value();
void finalize(const int n_);
void warn_type_conflicts(const String& name) const;

operator SEXP() const;
DATA_TYPE get_type() const;
static const char* format_data_type(const DATA_TYPE dt);

private:
DbColumnStorage* get_last_storage();
const DbColumnStorage* get_last_storage() const;
};


#endif // DB_COLUMN_H
14 changes: 14 additions & 0 deletions src/DbColumnDataSource.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "pch.h"
#include "DbColumnDataSource.h"

DbColumnDataSource::DbColumnDataSource(const int j_) :
j(j_)
{
}

DbColumnDataSource::~DbColumnDataSource() {
}

int DbColumnDataSource::get_j() const {
return j;
}
36 changes: 36 additions & 0 deletions src/DbColumnDataSource.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#ifndef DB_COLUMNDATASOURCE_H
#define DB_COLUMNDATASOURCE_H

#include "DbColumnDataType.h"

class DbColumnDataSource {
const int j;

protected:
DbColumnDataSource(const int j);

public:
virtual ~DbColumnDataSource();

public:
virtual DATA_TYPE get_data_type() const = 0;
virtual DATA_TYPE get_decl_data_type() const = 0;

virtual bool is_null() const = 0;

virtual int fetch_bool() const = 0;
virtual int fetch_int() const = 0;
virtual int64_t fetch_int64() const = 0;
virtual double fetch_real() const = 0;
virtual SEXP fetch_string() const = 0;
virtual SEXP fetch_blob() const = 0;
virtual double fetch_date() const = 0;
virtual double fetch_datetime_local() const = 0;
virtual double fetch_datetime() const = 0;
virtual double fetch_time() const = 0;

protected:
int get_j() const;
};

#endif //DB_COLUMNDATASOURCE_H
8 changes: 8 additions & 0 deletions src/DbColumnDataSourceFactory.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "pch.h"
#include "DbColumnDataSourceFactory.h"

DbColumnDataSourceFactory::DbColumnDataSourceFactory() {
}

DbColumnDataSourceFactory::~DbColumnDataSourceFactory() {
}
17 changes: 17 additions & 0 deletions src/DbColumnDataSourceFactory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef DB_COLUMNDATASOURCEFACTORY_H
#define DB_COLUMNDATASOURCEFACTORY_H

class DbColumnDataSource;

class DbColumnDataSourceFactory {
protected:
DbColumnDataSourceFactory();

public:
virtual ~DbColumnDataSourceFactory();

public:
virtual DbColumnDataSource* create(const int j) = 0;
};

#endif //DB_COLUMNDATASOURCEFACTORY_H
18 changes: 18 additions & 0 deletions src/DbColumnDataType.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef RSQLITE_COLUMNDATATYPE_H
#define RSQLITE_COLUMNDATATYPE_H

enum DATA_TYPE {
DT_UNKNOWN,
DT_BOOL,
DT_INT,
DT_INT64,
DT_REAL,
DT_STRING,
DT_BLOB,
DT_DATE,
DT_DATETIME,
DT_DATETIMETZ,
DT_TIME
};

#endif // RSQLITE_COLUMNDATATYPE_H
Loading