Here is a simplified version of a DBI type scheme, almost entirely using
convert function overloads. I temporarily have eval_foreign instead of
eval, because I cannot figure out how to overload Base.eval successfully.
cd("/home/haldane/Julia_package")
using DataFrames
using SQLite
using Lazy
import Base.convert
type DataBaseTable
conn::SQLiteDB
name::String
end
type CsvFile
file::String
end
function convert(::Type{DataBaseTable},
conn::SQLiteDB,
name::String,
df::DataFrame)
create(conn,
name,
df,
@>> df names map(string) )
DataBaseTable(conn, name)
end
function convert(::Type{SQLiteDB}, string::String)
SQLiteDB(string)
end
function eval_foreign(db::SQLiteDB, code::String)
query(db, code)
end
function convert(::Type{Dict}, conn::SQLiteDB)
names = @as _ begin
"select name from sqlite_master where type = 'table'"
eval_foreign(conn, _)
_.values[1]
end
[symbol(name) => DataBaseTable(conn, name) for name in names]
end
function convert(::Type{DataFrame}, dbt::DataBaseTable)
answer = eval_foreign(dbt.conn, "select * from $(dbt.name)" )
df = DataFrame(answer.values)
@>> answer.colnames map(symbol) names!(df)
end
function convert(::Type{CsvFile}, name::String, df::DataFrame)
writetable(name, df)
CsvFile(name)
end
function convert(::Type{DataFrame}, file::String)
readtable(file)
end
function convert(::Type{DataFrame}, cf = CsvFile)
readtable(cf.file)
end
conn = @>> "my_database.db" convert(SQLiteDB)
A = DataFrame(a = 1, b = 2)
B = DataFrame(a = 1, b = 2)
@>> A convert(DataBaseTable, conn, "A")
@>> B convert(DataBaseTable, conn, "B")
tables = @>> conn convert(Dict)
A = @>> begin
tables[:A]
convert(DataFrame)
convert(CsvFile, "A.csv")
convert(DataFrame)
end