1#include "duckdb/main/connection.hpp"
2
3#include "duckdb/main/client_context.hpp"
4#include "duckdb/main/connection_manager.hpp"
5#include "duckdb/main/database.hpp"
6#include "duckdb/main/appender.hpp"
7#include "duckdb/main/relation/read_csv_relation.hpp"
8#include "duckdb/main/relation/table_relation.hpp"
9#include "duckdb/main/relation/table_function_relation.hpp"
10#include "duckdb/main/relation/value_relation.hpp"
11#include "duckdb/main/relation/view_relation.hpp"
12#include "duckdb/parser/parser.hpp"
13
14using namespace duckdb;
15using namespace std;
16
17Connection::Connection(DuckDB &database) : db(database), context(make_unique<ClientContext>(database)) {
18 db.connection_manager->AddConnection(this);
19#ifdef DEBUG
20 EnableProfiling();
21#endif
22}
23
24Connection::~Connection() {
25 if (!context->is_invalidated) {
26 context->Cleanup();
27 db.connection_manager->RemoveConnection(this);
28 }
29}
30
31string Connection::GetProfilingInformation(ProfilerPrintFormat format) {
32 if (context->is_invalidated) {
33 return "Context is invalidated.";
34 }
35 if (format == ProfilerPrintFormat::JSON) {
36 return context->profiler.ToJSON();
37 } else {
38 return context->profiler.ToString();
39 }
40}
41
42void Connection::Interrupt() {
43 context->Interrupt();
44}
45
46void Connection::EnableProfiling() {
47 context->EnableProfiling();
48}
49
50void Connection::DisableProfiling() {
51 context->DisableProfiling();
52}
53
54void Connection::EnableQueryVerification() {
55 context->query_verification_enabled = true;
56}
57
58void Connection::DisableQueryVerification() {
59 context->query_verification_enabled = false;
60}
61
62unique_ptr<QueryResult> Connection::SendQuery(string query) {
63 return context->Query(query, true);
64}
65
66unique_ptr<MaterializedQueryResult> Connection::Query(string query) {
67 auto result = context->Query(query, false);
68 assert(result->type == QueryResultType::MATERIALIZED_RESULT);
69 return unique_ptr_cast<QueryResult, MaterializedQueryResult>(move(result));
70}
71
72unique_ptr<PreparedStatement> Connection::Prepare(string query) {
73 return context->Prepare(query);
74}
75
76unique_ptr<QueryResult> Connection::QueryParamsRecursive(string query, vector<Value> &values) {
77 auto statement = Prepare(query);
78 if (!statement->success) {
79 return make_unique<MaterializedQueryResult>(statement->error);
80 }
81 return statement->Execute(values);
82}
83
84unique_ptr<TableDescription> Connection::TableInfo(string table_name) {
85 return TableInfo(DEFAULT_SCHEMA, table_name);
86}
87
88unique_ptr<TableDescription> Connection::TableInfo(string schema_name, string table_name) {
89 return context->TableInfo(schema_name, table_name);
90}
91
92vector<unique_ptr<SQLStatement>> Connection::ExtractStatements(string query) {
93 Parser parser;
94 parser.ParseQuery(query);
95 return move(parser.statements);
96}
97
98void Connection::Append(TableDescription &description, DataChunk &chunk) {
99 context->Append(description, chunk);
100}
101
102shared_ptr<Relation> Connection::Table(string table_name) {
103 return Table(DEFAULT_SCHEMA, move(table_name));
104}
105
106shared_ptr<Relation> Connection::Table(string schema_name, string table_name) {
107 auto table_info = TableInfo(schema_name, table_name);
108 if (!table_info) {
109 throw Exception("Table does not exist!");
110 }
111 return make_shared<TableRelation>(*context, move(table_info));
112}
113
114shared_ptr<Relation> Connection::View(string tname) {
115 return View(DEFAULT_SCHEMA, move(tname));
116}
117
118shared_ptr<Relation> Connection::View(string schema_name, string table_name) {
119 return make_shared<ViewRelation>(*context, move(schema_name), move(table_name));
120}
121
122shared_ptr<Relation> Connection::TableFunction(string fname) {
123 vector<Value> values;
124 return TableFunction(move(fname), move(values));
125}
126
127shared_ptr<Relation> Connection::TableFunction(string fname, vector<Value> values) {
128 return make_shared<TableFunctionRelation>(*context, move(fname), move(values));
129}
130
131shared_ptr<Relation> Connection::Values(vector<vector<Value>> values) {
132 vector<string> column_names;
133 return Values(move(values), move(column_names));
134}
135
136shared_ptr<Relation> Connection::Values(vector<vector<Value>> values, vector<string> column_names, string alias) {
137 return make_shared<ValueRelation>(*context, move(values), move(column_names), alias);
138}
139
140shared_ptr<Relation> Connection::Values(string values) {
141 vector<string> column_names;
142 return Values(move(values), move(column_names));
143}
144
145shared_ptr<Relation> Connection::Values(string values, vector<string> column_names, string alias) {
146 return make_shared<ValueRelation>(*context, move(values), move(column_names), alias);
147}
148
149shared_ptr<Relation> Connection::ReadCSV(string csv_file, vector<string> columns) {
150 // parse columns
151 vector<ColumnDefinition> column_list;
152 for (auto &column : columns) {
153 auto col_list = Parser::ParseColumnList(column);
154 if (col_list.size() != 1) {
155 throw ParserException("Expected a singlec olumn definition");
156 }
157 column_list.push_back(move(col_list[0]));
158 }
159 return make_shared<ReadCSVRelation>(*context, csv_file, move(column_list));
160}
161
162void Connection::BeginTransaction() {
163 auto result = Query("BEGIN TRANSACTION");
164 if (!result->success) {
165 throw Exception(result->error);
166 }
167}
168
169void Connection::Commit() {
170 auto result = Query("COMMIT");
171 if (!result->success) {
172 throw Exception(result->error);
173 }
174}
175
176void Connection::Rollback() {
177 auto result = Query("ROLLBACK");
178 if (!result->success) {
179 throw Exception(result->error);
180 }
181}
182