int main() { // Welcome ! logs.notice() << "Yuni DBI Example"; logs.info() << "using the SQLite default adapter"; logs.info(); // empty line return RunExample() ? 0 : EXIT_FAILURE; }
static bool RunExample() { // our connection pool DBI::ConnectorPool connectors; // database location logs.info() << "opening the database file"; auto error = connectors.open(new DBI::Adapter::SQLite(), "dbi-example.db"); if (error) { logs.error() << "impossible to establish a connection to the database"; return false; } // begin a new transaction auto tx = connectors.begin(); // create a new table if not already exists logs.info() << "creating the table 'example'"; tx.perform("CREATE TABLE IF NOT EXISTS example (x INTEGER PRIMARY KEY);"); // truncate the table, if it already exists logs.info() << "truncating the table"; tx.truncate("example"); // fill it with some values logs.info() << "inserting some data"; tx.perform("INSERT INTO example (x) VALUES (42), (3), (-1), (-10), (-3);"); // iterating through a result set { uint rowindex = 0; logs.info(); logs.info() << "iterating through all values"; auto stmt = tx.prepare("SELECT * FROM example WHERE x > $1 ORDER BY x"); stmt.bind(0, -5); // x > -5 stmt.execute(); // iterate through all values stmt.each([&] (DBI::Row& row) -> bool { sint64 x = row[0].asInt64(); logs.info() << " :: resultset: in row " << (++rowindex) << ": x = " << x; return true; // continue }); } // commit changes logs.info() << "commit"; if (DBI::errNone != (error = tx.commit())) { logs.error() << "commit failed"; return false; } return true; }
static void PrepareTheAPI(Messaging::Service& service) { logs.debug() << "preparing protocol"; // note: contrary to the object `service`, `myapi` is not thread-safe Messaging::Protocol* myapi = new Messaging::Protocol(); // retrieving the default schema Messaging::Schema& schema = myapi->schema(); // method: hello_world schema.methods.add("hello_world") .brief("Always answer 'hello world to any request'") .option("http.method", "GET") .invoke(& APIHelloWorld); // method: sum schema.methods.add("sum") .brief("Computes the sum of two numbers") .option("http.method", "GET") .param("a", "First operand", "0") .param("b", "Second operand", "0") .invoke(& APISum); // -- Switching to the new protocol // note: The method `protocol()` must be call to make any modification to // the protocol visible, and can be called anytime, even if started // (useful for reloading the service while running) // note: this method will take ownership of the pointer, thus the pointer // must not be used after this statement service.protocol(myapi); }
static void APIHelloWorld(Messaging::Context&, Marshal::Object& response) { // log server logs.info() << "[method:hello_world] sending hello world !"; // the response response["message"] = "Hellow world !"; }
static bool StartService(Messaging::Service& service) { logs.info() << "starting"; Net::Error error = service.start(); switch (error) { case Net::errNone: break; default: logs.fatal() << "impossible to start the service: " << error; return false; } logs.info() << "examples:"; logs.info() << "# curl -i -X GET 'http://localhost:6042/hello_world'"; logs.info() << "# curl -i -X GET 'http://localhost:6042/sum?a=50&b=42'"; logs.info() << "<ctrl> + C to quit"; logs.info(); // empty line for beauty return true; }
static void APISum(Messaging::Context& context, Marshal::Object& response) { // our parameters double a, b; if (not context.params["a"].to(a) or not context.params["b"].to(b)) { // the parameters are not valid, exiting with a 400 status code // (Bad Request, The request cannot be fulfilled due to bad syntax.) // see http://en.wikipedia.org/wiki/List_of_HTTP_status_codes context.httpStatus = 400; // log server logs.error() << "[method:sum] invalid parameters"; return; } // log server logs.info() << "[method:sum] " << a << " + " << b << " = " << (a + b); // the response response["a"] = a; response["b"] = b; response["sum"] = (a + b); }
int main(int, char**) { // Welcome ! logs.notice() << "Yuni REST Server Example"; logs.info() << "http://www.libyuni.org"; logs.info(); // empty line // The service itself Messaging::Service service; // Prepare the API PrepareTheAPI(service); // Preparing all transports PrepareTransports(service); // Starting the new service if (not StartService(service)) return EXIT_FAILURE; // Waiting for the end of the server service.wait(); return 0; }
/*! * \brief Méthode générique de trace d'un message. * \param logger * Logger de référence du message. * \param level * Niveau de référence du message. * \param message * Message à tracer. */ void logs::ConsoleAppender::writeMessage(const logs::Logger & logger, const logs::Level & level, const std::string & message) { lockMessages(); if (this->state() == utils::CREATED) { //static_cast<utils::Thread *>(this)->lock(); //printf(" Thread ConsoleAppender start \n"); std::ostringstream msg; msg << "ConsoleAppender created by " << logger.name() << " " << level.name(); this->start(msg.str()); //static_cast<utils::Thread *>(this)->unlock(); } unlockMessages(); logs::MemoryAppender::writeMessage(logger, level, message); }
static void PrepareTransports(Messaging::Service& service) { logs.debug() << "preparing transports"; service.transports.add("*", 6042, new Messaging::Transport::REST::Server()); }