Database System 0.1.0
Advanced C++20 Database System with Multi-Backend Support
Loading...
Searching...
No Matches
error_handling.cpp
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
22#include <iostream>
23#include <memory>
24#include <string>
25#include <variant>
26
29
30using namespace database;
31
38static void print_error(const std::string& operation, const kcenon::common::error_info& err)
39{
40 std::cerr << " [ERROR] " << operation << ": " << err.message << std::endl;
41}
42
47{
48 std::cout << "\n--- Connection failure handling ---" << std::endl;
49
50 auto context = std::make_shared<database_context>();
51 auto db = std::make_shared<database_manager>(context);
52 db->set_mode(database_types::postgres);
53
54 // Intentionally use wrong credentials
55 auto result = db->connect_result(
56 "host=localhost port=9999 dbname=nonexistent user=nobody password=wrong");
57
58 if (result.is_ok())
59 {
60 std::cout << " Connected (unexpected)" << std::endl;
61 db->disconnect_result();
62 }
63 else
64 {
65 print_error("connect", result.error());
66 std::cout << " Connection failure handled gracefully" << std::endl;
67 }
68}
69
73static void demonstrate_query_errors(std::shared_ptr<database_manager> db)
74{
75 std::cout << "\n--- Query error handling ---" << std::endl;
76
77 // 1. Execute invalid SQL
78 auto bad_sql = db->execute_query_result("THIS IS NOT VALID SQL");
79 if (!bad_sql.is_ok())
80 {
81 print_error("bad SQL", bad_sql.error());
82 }
83
84 // 2. Reference a non-existent table
85 auto missing_table = db->select_query_result("SELECT * FROM nonexistent_table_xyz");
86 if (!missing_table.is_ok())
87 {
88 print_error("missing table", missing_table.error());
89 }
90
91 // 3. Insert with constraint violation (duplicate primary key)
92 db->create_query_result(R"(
93 CREATE TABLE IF NOT EXISTS error_demo (
94 id INTEGER PRIMARY KEY,
95 name VARCHAR(50) NOT NULL
96 )
97 )");
98 db->execute_query_result("DELETE FROM error_demo");
99 db->execute_query_result("INSERT INTO error_demo (id, name) VALUES (1, 'first')");
100
101 auto duplicate = db->execute_query_result(
102 "INSERT INTO error_demo (id, name) VALUES (1, 'duplicate')");
103 if (!duplicate.is_ok())
104 {
105 print_error("duplicate key", duplicate.error());
106 std::cout << " Constraint violation handled" << std::endl;
107 }
108}
109
113static bool demonstrate_chained_operations(std::shared_ptr<database_manager> db)
114{
115 std::cout << "\n--- Chained operations with early return ---" << std::endl;
116
117 // Step 1: Create table
118 auto step1 = db->create_query_result(R"(
119 CREATE TABLE IF NOT EXISTS chain_demo (
120 id SERIAL PRIMARY KEY,
121 value INTEGER NOT NULL
122 )
123 )");
124 if (!step1.is_ok())
125 {
126 print_error("step 1 (create table)", step1.error());
127 return false;
128 }
129 std::cout << " Step 1: Table created" << std::endl;
130
131 // Step 2: Insert data
132 auto step2 = db->execute_query_result(
133 "INSERT INTO chain_demo (value) VALUES (42)");
134 if (!step2.is_ok())
135 {
136 print_error("step 2 (insert)", step2.error());
137 return false;
138 }
139 std::cout << " Step 2: Data inserted" << std::endl;
140
141 // Step 3: Read back
142 auto step3 = db->select_query_result("SELECT id, value FROM chain_demo");
143 if (!step3.is_ok())
144 {
145 print_error("step 3 (select)", step3.error());
146 return false;
147 }
148 std::cout << " Step 3: Read " << step3.value().size() << " row(s)" << std::endl;
149
150 // Step 4: Verify data
151 if (step3.value().empty())
152 {
153 std::cerr << " [ERROR] No rows returned" << std::endl;
154 return false;
155 }
156 std::cout << " Step 4: Data verified" << std::endl;
157
158 return true;
159}
160
164static void demonstrate_last_error(std::shared_ptr<database_manager> db)
165{
166 std::cout << "\n--- last_error() diagnostics ---" << std::endl;
167
168 // Trigger an error
169 db->execute_query_result("SELECT * FROM __does_not_exist__");
170
171 auto err = db->last_error();
172 if (!err.empty())
173 {
174 std::cout << " last_error(): " << err << std::endl;
175 }
176 else
177 {
178 std::cout << " last_error() returned empty (backend may not populate it)"
179 << std::endl;
180 }
181}
182
183int main()
184{
185 std::cout << "=== error_handling example ===" << std::endl;
186
187 // Demonstrate connection failure (does not need a running DB)
189
190 // For the remaining demos, attempt a real connection
191 auto context = std::make_shared<database_context>();
192 auto db = std::make_shared<database_manager>(context);
193 db->set_mode(database_types::postgres);
194
195 std::string connection_string
196 = "host=localhost port=5432 dbname=example_db user=user password=password";
197
198 auto connect = db->connect_result(connection_string);
199 if (!connect.is_ok())
200 {
201 std::cout << "\nSkipping remaining demos (no database connection available)"
202 << std::endl;
203 std::cout << "=== error_handling example completed ===" << std::endl;
204 return 0;
205 }
206
210
211 // Connection info for diagnostics
212 std::cout << "\n--- Connection info ---" << std::endl;
213 auto info = db->connection_info();
214 for (const auto& [key, value] : info)
215 {
216 std::cout << " " << key << " = " << value << std::endl;
217 }
218
219 db->disconnect_result();
220 std::cout << "\nDisconnected" << std::endl;
221
222 std::cout << "=== error_handling example completed ===" << std::endl;
223 return 0;
224}
Dependency injection container for database system components.
static bool demonstrate_chained_operations(std::shared_ptr< database_manager > db)
Demonstrates chaining operations with early return on failure.
static void demonstrate_query_errors(std::shared_ptr< database_manager > db)
Demonstrates handling query errors with Result<T>.
static void print_error(const std::string &operation, const kcenon::common::error_info &err)
Helper to print a Result error.
static void demonstrate_connection_failure()
Demonstrates handling a connection failure gracefully.
int main()
static void demonstrate_last_error(std::shared_ptr< database_manager > db)
Demonstrates using last_error() for additional diagnostics.