Skip to main content
Glama
complex_example.cpp20.5 kB
#include <iostream> #include <string> #include <vector> #include <memory> #include <unordered_map> #include <chrono> #include <future> #include <exception> #include <algorithm> // Constants namespace constants { constexpr int MAX_CONNECTIONS = 100; constexpr int DEFAULT_TIMEOUT = 30; const std::string API_VERSION = "1.0.0"; } // Forward declarations class DatabaseConnection; class User; class Product; class QueryResult; // Enums enum class ConnectionStatus { CLOSED, OPEN, ERROR }; enum class QueryStatus { SUCCESS, ERROR, TIMEOUT }; enum class UserStatus { ACTIVE, INACTIVE, SUSPENDED }; // Exception classes class DatabaseException : public std::exception { private: std::string message_; public: explicit DatabaseException(const std::string& message) : message_(message) {} const char* what() const noexcept override { return message_.c_str(); } }; class ValidationException : public std::exception { private: std::string message_; std::string field_; public: ValidationException(const std::string& message, const std::string& field = "") : message_(message), field_(field) {} const char* what() const noexcept override { return message_.c_str(); } const std::string& field() const { return field_; } }; // Abstract base class class DatabaseConnection { public: virtual ~DatabaseConnection() = default; virtual bool connect() = 0; virtual std::unique_ptr<QueryResult> executeQuery(const std::string& query, const std::vector<std::string>& params = {}) = 0; virtual void close() = 0; virtual void beginTransaction() = 0; virtual void commit() = 0; virtual void rollback() = 0; virtual ConnectionStatus getStatus() const = 0; }; // PostgreSQL implementation class PostgresConnection : public DatabaseConnection { private: std::string host_; int port_; std::string database_; std::string username_; std::string password_; ConnectionStatus status_; bool transaction_active_; public: PostgresConnection(const std::string& host, int port, const std::string& database, const std::string& username, const std::string& password) : host_(host), port_(port), database_(database), username_(username), password_(password), status_(ConnectionStatus::CLOSED), transaction_active_(false) {} bool connect() override { try { std::cout << "Connecting to PostgreSQL at " << host_ << ":" << port_ << "/" << database_ << " as " << username_ << std::endl; // Simulate connection logic std::this_thread::sleep_for(std::chrono::milliseconds(100)); status_ = ConnectionStatus::OPEN; return true; } catch (const std::exception& e) { std::cerr << "Failed to connect: " << e.what() << std::endl; status_ = ConnectionStatus::ERROR; return false; } } std::unique_ptr<QueryResult> executeQuery(const std::string& query, const std::vector<std::string>& params = {}) override; void close() override { status_ = ConnectionStatus::CLOSED; transaction_active_ = false; } void beginTransaction() override { if (status_ != ConnectionStatus::OPEN) { throw DatabaseException("Not connected to database"); } transaction_active_ = true; } void commit() override { transaction_active_ = false; } void rollback() override { transaction_active_ = false; } ConnectionStatus getStatus() const override { return status_; } }; // MySQL implementation class MySQLConnection : public DatabaseConnection { private: std::string connection_string_; ConnectionStatus status_; public: explicit MySQLConnection(const std::string& connection_string) : connection_string_(connection_string), status_(ConnectionStatus::CLOSED) {} bool connect() override { status_ = ConnectionStatus::OPEN; return true; } std::unique_ptr<QueryResult> executeQuery(const std::string& query, const std::vector<std::string>& params = {}) override; void close() override { status_ = ConnectionStatus::CLOSED; } void beginTransaction() override {} void commit() override {} void rollback() override {} ConnectionStatus getStatus() const override { return status_; } }; // Query result class class QueryResult { private: std::vector<std::unordered_map<std::string, std::string>> rows_; QueryStatus status_; std::string error_message_; public: QueryResult() : status_(QueryStatus::SUCCESS) {} void addRow(const std::unordered_map<std::string, std::string>& row) { rows_.push_back(row); } const std::vector<std::unordered_map<std::string, std::string>>& getRows() const { return rows_; } size_t getRowCount() const { return rows_.size(); } QueryStatus getStatus() const { return status_; } void setError(const std::string& error) { status_ = QueryStatus::ERROR; error_message_ = error; } }; // Template cache class template<typename K, typename V> class Cache { private: struct CacheItem { V value; std::chrono::steady_clock::time_point expiry; CacheItem(const V& val, std::chrono::seconds ttl) : value(val), expiry(std::chrono::steady_clock::now() + ttl) {} }; std::unordered_map<K, CacheItem> data_; size_t max_size_; public: explicit Cache(size_t max_size = 1000) : max_size_(max_size) {} void set(const K& key, const V& value, std::chrono::seconds ttl = std::chrono::seconds(3600)) { if (data_.size() >= max_size_ && data_.find(key) == data_.end()) { // Simple eviction: remove first element data_.erase(data_.begin()); } data_.emplace(key, CacheItem(value, ttl)); } std::optional<V> get(const K& key) { auto it = data_.find(key); if (it == data_.end()) { return std::nullopt; } if (std::chrono::steady_clock::now() > it->second.expiry) { data_.erase(it); return std::nullopt; } return it->second.value; } void remove(const K& key) { data_.erase(key); } void clear() { data_.clear(); } }; // Data model classes class User { private: int id_; std::string username_; std::string email_; std::chrono::system_clock::time_point created_at_; std::chrono::system_clock::time_point updated_at_; UserStatus status_; std::unordered_map<std::string, std::string> metadata_; public: User(const std::string& username, const std::string& email) : id_(static_cast<int>(std::chrono::system_clock::now().time_since_epoch().count())), username_(username), email_(email), created_at_(std::chrono::system_clock::now()), updated_at_(std::chrono::system_clock::now()), status_(UserStatus::ACTIVE) {} // Getters int getId() const { return id_; } const std::string& getUsername() const { return username_; } const std::string& getEmail() const { return email_; } UserStatus getStatus() const { return status_; } // Setters void setUsername(const std::string& username) { username_ = username; updateTimestamp(); } void setEmail(const std::string& email) { email_ = email; updateTimestamp(); } void setStatus(UserStatus status) { status_ = status; updateTimestamp(); } // Validation bool validateEmail() const { return email_.find('@') != std::string::npos && email_.find('.') != std::string::npos; } void updateTimestamp() { updated_at_ = std::chrono::system_clock::now(); } // Serialization std::unordered_map<std::string, std::string> toMap() const { return { {"id", std::to_string(id_)}, {"username", username_}, {"email", email_}, {"status", std::to_string(static_cast<int>(status_))} }; } static std::unique_ptr<User> fromMap(const std::unordered_map<std::string, std::string>& data) { auto user = std::make_unique<User>(data.at("username"), data.at("email")); user->id_ = std::stoi(data.at("id")); return user; } }; class Product { private: int id_; std::string name_; double price_; std::string category_; std::string description_; std::vector<std::string> tags_; std::chrono::system_clock::time_point created_at_; public: Product(const std::string& name, double price, const std::string& category) : id_(static_cast<int>(std::chrono::system_clock::now().time_since_epoch().count())), name_(name), price_(price), category_(category), created_at_(std::chrono::system_clock::now()) {} // Getters int getId() const { return id_; } const std::string& getName() const { return name_; } double getPrice() const { return price_; } const std::string& getCategory() const { return category_; } const std::vector<std::string>& getTags() const { return tags_; } // Tag management void addTag(const std::string& tag) { if (std::find(tags_.begin(), tags_.end(), tag) == tags_.end()) { tags_.push_back(tag); } } void removeTag(const std::string& tag) { tags_.erase(std::remove(tags_.begin(), tags_.end(), tag), tags_.end()); } // Price calculations double calculateDiscountedPrice(double discount_percent) const { return price_ * (1.0 - discount_percent / 100.0); } }; // Service classes with templates template<typename DatabaseType> class UserService { private: std::unique_ptr<DatabaseType> database_; std::shared_ptr<Cache<int, std::shared_ptr<User>>> cache_; public: UserService(std::unique_ptr<DatabaseType> database, std::shared_ptr<Cache<int, std::shared_ptr<User>>> cache) : database_(std::move(database)), cache_(cache) {} std::future<std::shared_ptr<User>> createUserAsync(const std::string& username, const std::string& email) { return std::async(std::launch::async, [this, username, email]() { auto user = std::make_shared<User>(username, email); if (!user->validateEmail()) { throw ValidationException("Invalid email format", "email"); } try { database_->beginTransaction(); std::string query = "INSERT INTO users (username, email) VALUES (?, ?)"; std::vector<std::string> params = {username, email}; auto result = database_->executeQuery(query, params); if (result->getStatus() != QueryStatus::SUCCESS) { throw DatabaseException("Failed to insert user"); } database_->commit(); // Cache the user cache_->set(user->getId(), user); std::cout << "User created successfully: " << username << std::endl; return user; } catch (const std::exception& e) { database_->rollback(); std::cerr << "Failed to create user: " << e.what() << std::endl; throw; } }); } std::shared_ptr<User> getUser(int id) { // Check cache first auto cached = cache_->get(id); if (cached) { return *cached; } // Query database std::string query = "SELECT * FROM users WHERE id = ?"; std::vector<std::string> params = {std::to_string(id)}; try { auto result = database_->executeQuery(query, params); if (result->getRowCount() == 0) { return nullptr; } auto user = User::fromMap(result->getRows()[0]); auto shared_user = std::shared_ptr<User>(user.release()); // Cache the result cache_->set(id, shared_user); return shared_user; } catch (const std::exception& e) { std::cerr << "Failed to get user: " << e.what() << std::endl; return nullptr; } } bool updateUser(int id, const std::unordered_map<std::string, std::string>& updates) { auto user = getUser(id); if (!user) { return false; } // Apply updates for (const auto& [key, value] : updates) { if (key == "username") { user->setUsername(value); } else if (key == "email") { user->setEmail(value); } } // Update cache cache_->set(id, user); return true; } }; // Specialized template for different database types template<> class UserService<PostgresConnection> { // PostgreSQL-specific optimizations could go here }; // Factory pattern for database connections class DatabaseFactory { public: static std::unique_ptr<DatabaseConnection> createConnection(const std::string& type, const std::unordered_map<std::string, std::string>& config) { if (type == "postgresql") { return std::make_unique<PostgresConnection>( config.at("host"), std::stoi(config.at("port")), config.at("database"), config.at("username"), config.at("password") ); } else if (type == "mysql") { std::string connection_string = "mysql://" + config.at("username") + ":" + config.at("password") + "@" + config.at("host") + ":" + config.at("port") + "/" + config.at("database"); return std::make_unique<MySQLConnection>(connection_string); } throw std::invalid_argument("Unsupported database type: " + type); } }; // Configuration management class AppConfig { private: std::unordered_map<std::string, std::string> config_; public: AppConfig() { // Default configuration config_["debug_mode"] = "false"; config_["log_level"] = "INFO"; config_["cache_size"] = "1000"; config_["max_connections"] = std::to_string(constants::MAX_CONNECTIONS); } void set(const std::string& key, const std::string& value) { config_[key] = value; } std::string get(const std::string& key, const std::string& default_value = "") const { auto it = config_.find(key); return (it != config_.end()) ? it->second : default_value; } bool getBool(const std::string& key, bool default_value = false) const { auto value = get(key); return value == "true" || value == "1"; } int getInt(const std::string& key, int default_value = 0) const { auto value = get(key); return value.empty() ? default_value : std::stoi(value); } static AppConfig fromEnvironment() { AppConfig config; // Load from environment variables if (const char* debug = std::getenv("DEBUG")) { config.set("debug_mode", debug); } if (const char* log_level = std::getenv("LOG_LEVEL")) { config.set("log_level", log_level); } return config; } }; // Utility functions namespace utils { template<typename T> void logInfo(const T& message) { std::cout << "[INFO] " << message << std::endl; } template<typename T> void logError(const T& message) { std::cerr << "[ERROR] " << message << std::endl; } std::string getCurrentTimestamp() { auto now = std::chrono::system_clock::now(); auto time_t = std::chrono::system_clock::to_time_t(now); return std::ctime(&time_t); } } // Implementation of deferred methods std::unique_ptr<QueryResult> PostgresConnection::executeQuery(const std::string& query, const std::vector<std::string>& params) { if (status_ != ConnectionStatus::OPEN) { throw DatabaseException("Not connected to database"); } auto result = std::make_unique<QueryResult>(); // Simulate query execution std::this_thread::sleep_for(std::chrono::milliseconds(50)); return result; } std::unique_ptr<QueryResult> MySQLConnection::executeQuery(const std::string& query, const std::vector<std::string>& params) { if (status_ != ConnectionStatus::OPEN) { throw DatabaseException("Not connected to database"); } return std::make_unique<QueryResult>(); } // Main application int main() { try { utils::logInfo("Starting application " + constants::API_VERSION); // Load configuration auto config = AppConfig::fromEnvironment(); config.set("db_type", "postgresql"); config.set("db_host", "localhost"); config.set("db_port", "5432"); config.set("db_name", "myapp"); config.set("db_user", "user"); config.set("db_password", "password"); // Create database connection std::unordered_map<std::string, std::string> db_config = { {"host", config.get("db_host")}, {"port", config.get("db_port")}, {"database", config.get("db_name")}, {"username", config.get("db_user")}, {"password", config.get("db_password")} }; auto database = DatabaseFactory::createConnection(config.get("db_type"), db_config); if (!database->connect()) { utils::logError("Failed to connect to database"); return 1; } // Create cache auto cache = std::make_shared<Cache<int, std::shared_ptr<User>>>(config.getInt("cache_size", 1000)); // Create user service auto user_service = std::make_unique<UserService<DatabaseConnection>>(std::move(database), cache); // Create sample user asynchronously auto user_future = user_service->createUserAsync("john_doe", "john@example.com"); auto user = user_future.get(); if (user) { utils::logInfo("Created user: " + user->getUsername() + " <" + user->getEmail() + ">"); // Get user auto retrieved_user = user_service->getUser(user->getId()); if (retrieved_user) { utils::logInfo("Retrieved user: " + retrieved_user->getUsername()); } // Update user std::unordered_map<std::string, std::string> updates = { {"email", "john.doe@example.com"} }; if (user_service->updateUser(user->getId(), updates)) { utils::logInfo("User updated successfully"); } } // Create sample product auto product = std::make_unique<Product>("Laptop", 999.99, "Electronics"); product->addTag("computer"); product->addTag("portable"); double discounted = product->calculateDiscountedPrice(10.0); std::cout << "Product: " << product->getName() << ", Original: $" << product->getPrice() << ", Discounted: $" << discounted << std::endl; utils::logInfo("Application completed successfully"); } catch (const std::exception& e) { utils::logError("Application error: " + std::string(e.what())); return 1; } return 0; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kensave/CodeCortX-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server