Cppgres
Build Postgres extensions in C++
Loading...
Searching...
No Matches
syscache.hpp
1#pragma once
2
3#include "datum.hpp"
4#include "guard.hpp"
5#include "heap_tuple.hpp"
6#include "imports.h"
7#include "xact.hpp"
8
9namespace cppgres {
10
11template <typename T> struct syscache_traits {};
12
13template <> struct syscache_traits<Form_pg_type> {
14 static constexpr ::SysCacheIdentifier cache_id = TYPEOID;
15};
16
17template <> struct syscache_traits<Form_pg_proc> {
18 static constexpr ::SysCacheIdentifier cache_id = PROCOID;
19};
20
21template <typename T>
22concept syscached = requires(T t) {
23 { *t };
24 { syscache_traits<T>::cache_id } -> std::same_as<const ::SysCacheIdentifier &>;
25};
26
27template <syscached T, convertible_into_datum... D> struct syscache {
28 syscache(const D &...key) : syscache(syscache_traits<T>::cache_id, key...) {}
29 syscache(::SysCacheIdentifier cache_id, const D &...key)
30 requires(sizeof...(key) > 0 && sizeof...(key) < 5)
31 : cache_id(cache_id), tuple([&]() {
32 datum keys[4] = {datum_conversion<D>::into_datum(key)...};
33 return ffi_guard{::SearchSysCache}(cache_id, keys[0], keys[1], keys[2], keys[3]);
34 }()) {
35 if (!HeapTupleIsValid(tuple)) {
36 throw std::runtime_error("invalid tuple");
37 }
38 }
39
40 ~syscache() { ReleaseSysCache(tuple); }
41
42 decltype(*std::declval<T>()) &operator*() {
43 return *reinterpret_cast<T>(GETSTRUCT(tuple.operator HeapTuple()));
44 }
45 const decltype(*std::declval<T>()) &operator*() const {
46 return *reinterpret_cast<T>(GETSTRUCT(tuple.operator HeapTuple()));
47 }
48
56 template <convertible_from_datum V> std::optional<V> get_attribute(int attr) {
57 bool isnull;
58 Datum ret = ffi_guard{::SysCacheGetAttr}(cache_id, tuple, attr, &isnull);
59 if (isnull) {
60 return std::nullopt;
61 }
62 return from_nullable_datum<V>(nullable_datum(ret), oid(/*FIXME*/ InvalidOid));
63 }
64
65 operator const heap_tuple &() const { return tuple; }
66
67private:
68 ::SysCacheIdentifier cache_id;
69 heap_tuple tuple;
70};
71
72} // namespace cppgres
Definition: datum.hpp:167
Definition: syscache.hpp:22
static datum into_datum(const T &d)=delete
Convert datum into a type.
Definition: datum.hpp:35
Definition: guard.hpp:19
Heap tuple convenience wrapper.
Definition: heap_tuple.hpp:11
Definition: datum.hpp:56
Definition: datum.hpp:17
Definition: syscache.hpp:11
Definition: syscache.hpp:27
std::optional< V > get_attribute(int attr)
Get an attribute by index.
Definition: syscache.hpp:56