| 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 | |
| 14 | using namespace duckdb; |
| 15 | using namespace std; |
| 16 | |
| 17 | Connection::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 | |
| 24 | Connection::~Connection() { |
| 25 | if (!context->is_invalidated) { |
| 26 | context->Cleanup(); |
| 27 | db.connection_manager->RemoveConnection(this); |
| 28 | } |
| 29 | } |
| 30 | |
| 31 | string 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 | |
| 42 | void Connection::Interrupt() { |
| 43 | context->Interrupt(); |
| 44 | } |
| 45 | |
| 46 | void Connection::EnableProfiling() { |
| 47 | context->EnableProfiling(); |
| 48 | } |
| 49 | |
| 50 | void Connection::DisableProfiling() { |
| 51 | context->DisableProfiling(); |
| 52 | } |
| 53 | |
| 54 | void Connection::EnableQueryVerification() { |
| 55 | context->query_verification_enabled = true; |
| 56 | } |
| 57 | |
| 58 | void Connection::DisableQueryVerification() { |
| 59 | context->query_verification_enabled = false; |
| 60 | } |
| 61 | |
| 62 | unique_ptr<QueryResult> Connection::SendQuery(string query) { |
| 63 | return context->Query(query, true); |
| 64 | } |
| 65 | |
| 66 | unique_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 | |
| 72 | unique_ptr<PreparedStatement> Connection::Prepare(string query) { |
| 73 | return context->Prepare(query); |
| 74 | } |
| 75 | |
| 76 | unique_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 | |
| 84 | unique_ptr<TableDescription> Connection::TableInfo(string table_name) { |
| 85 | return TableInfo(DEFAULT_SCHEMA, table_name); |
| 86 | } |
| 87 | |
| 88 | unique_ptr<TableDescription> Connection::TableInfo(string schema_name, string table_name) { |
| 89 | return context->TableInfo(schema_name, table_name); |
| 90 | } |
| 91 | |
| 92 | vector<unique_ptr<SQLStatement>> Connection::(string query) { |
| 93 | Parser parser; |
| 94 | parser.ParseQuery(query); |
| 95 | return move(parser.statements); |
| 96 | } |
| 97 | |
| 98 | void Connection::Append(TableDescription &description, DataChunk &chunk) { |
| 99 | context->Append(description, chunk); |
| 100 | } |
| 101 | |
| 102 | shared_ptr<Relation> Connection::Table(string table_name) { |
| 103 | return Table(DEFAULT_SCHEMA, move(table_name)); |
| 104 | } |
| 105 | |
| 106 | shared_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 | |
| 114 | shared_ptr<Relation> Connection::View(string tname) { |
| 115 | return View(DEFAULT_SCHEMA, move(tname)); |
| 116 | } |
| 117 | |
| 118 | shared_ptr<Relation> Connection::View(string schema_name, string table_name) { |
| 119 | return make_shared<ViewRelation>(*context, move(schema_name), move(table_name)); |
| 120 | } |
| 121 | |
| 122 | shared_ptr<Relation> Connection::TableFunction(string fname) { |
| 123 | vector<Value> values; |
| 124 | return TableFunction(move(fname), move(values)); |
| 125 | } |
| 126 | |
| 127 | shared_ptr<Relation> Connection::TableFunction(string fname, vector<Value> values) { |
| 128 | return make_shared<TableFunctionRelation>(*context, move(fname), move(values)); |
| 129 | } |
| 130 | |
| 131 | shared_ptr<Relation> Connection::Values(vector<vector<Value>> values) { |
| 132 | vector<string> column_names; |
| 133 | return Values(move(values), move(column_names)); |
| 134 | } |
| 135 | |
| 136 | shared_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 | |
| 140 | shared_ptr<Relation> Connection::Values(string values) { |
| 141 | vector<string> column_names; |
| 142 | return Values(move(values), move(column_names)); |
| 143 | } |
| 144 | |
| 145 | shared_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 | |
| 149 | shared_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 | |
| 162 | void Connection::BeginTransaction() { |
| 163 | auto result = Query("BEGIN TRANSACTION" ); |
| 164 | if (!result->success) { |
| 165 | throw Exception(result->error); |
| 166 | } |
| 167 | } |
| 168 | |
| 169 | void Connection::Commit() { |
| 170 | auto result = Query("COMMIT" ); |
| 171 | if (!result->success) { |
| 172 | throw Exception(result->error); |
| 173 | } |
| 174 | } |
| 175 | |
| 176 | void Connection::Rollback() { |
| 177 | auto result = Query("ROLLBACK" ); |
| 178 | if (!result->success) { |
| 179 | throw Exception(result->error); |
| 180 | } |
| 181 | } |
| 182 | |