Repository navigation
Databases: crocket::db with its Postgres backend crocket::pg, and handlers that
return plain structs. Nothing existing breaks; the new pieces are opt-in.
Added
crocket::db, a small database API, with its first backendcrocket::pg
(CMake target), Postgres on libpqxx, built when libpqxx is found
(-DCROCKET_PG=AUTO|ON|OFF). Handlers takeDb&and never name the backend. Plain structs, no annotations or base class: the
table is the type's name in plural snake_case (Hero->heroes, overridable with
db::table_name<T>), columns are the members,idis the key. Handlers takeDb& db;
db.find<T>(id),db.insert(v),db.update(v),db.erase<T>(id),
db.where(&T::member, value | db::like(...) | db::gt(...) | db::in({...}))with
order_by,limit,offset,all,firstandcount, plusdb.sql<T>(...)and
db.exec(...)for raw SQL. Statements are prepared once per connection.- A model's
idmay be missing from a JSON body (it reads as 0 and the database
assigns it);insert()never sendsid, so a client-supplied one is ignored.
json::omittable<T>is the hook. crocket_db_seconds{table,op}andcrocket_db_pool_connections{state}in
Metrics, anddb_ms,db_wait_msanddb_queriesonLoggerrequest lines,
when a request used the database.Config::database(url,pool_size,pool_wait) andCROCKET_DATABASE_URL,
CROCKET_DATABASE_POOL_SIZEandCROCKET_DATABASE_POOL_WAITinConfig::from_env().- Handlers can return a plain struct:
Hero,std::vector<Hero>,std::optional<Hero>
(empty: 404) andCreated<Hero>are JSON on HTTP routes, as if wrapped inJson<T>,
and protobuf on gRPC routes.Json<T>still works and always wins. Proto<T>: an explicit protobuf body,application/x-protobufon HTTP routes and
the normal reply on gRPC routes. A gRPC method returningJson<T>replies with JSON
(application/grpc+json). OpenAPI listsapplication/x-protobufforProto<T>.examples/heroes.cpp: a CRUD API oncrocket::db, andbench/db.cpp,crocket::db
against the same queries written with libpqxx.