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 "imports.h"
6
7namespace cppgres {
8
9template <typename T> struct syscache_traits {
10};
11
12template <> struct syscache_traits<Form_pg_type> {
13 static constexpr ::SysCacheIdentifier cache_id = TYPEOID;
14};
15
16template <> struct syscache_traits<Form_pg_proc> {
17 static constexpr ::SysCacheIdentifier cache_id = PROCOID;
18};
19
20template <typename T>
21concept syscached = requires(T t) {
22 { *t };
23 { syscache_traits<T>::cache_id } -> std::same_as<const ::SysCacheIdentifier &>;
24};
25
26template <syscached T, convertible_into_datum... D> struct syscache {
27 syscache(const D &...key) : syscache(syscache_traits<T>::cache_id, key...) {}
28 syscache(::SysCacheIdentifier cache_id, const D &...key)
29 requires(sizeof...(key) > 0 && sizeof...(key) < 5)
30 {
31 datum keys[4] = {datum_conversion<D>::into_datum(key)...};
32 tuple = ffi_guarded(::SearchSysCache)(cache_id, keys[0], keys[1], keys[2], keys[3]);
33
34 if (!HeapTupleIsValid(tuple)) {
35 throw std::runtime_error("invalid tuple");
36 }
37 }
38
39 ~syscache() { ReleaseSysCache(tuple); }
40
41 decltype(*std::declval<T>()) &operator*() { return *reinterpret_cast<T>(GETSTRUCT(tuple)); }
42 const decltype(*std::declval<T>()) &operator*() const {
43 return *reinterpret_cast<T>(GETSTRUCT(tuple));
44 }
45
46private:
47 HeapTuple tuple;
48};
49
50} // namespace cppgres
Definition: datum.hpp:104
Definition: syscache.hpp:21
static datum into_datum(const T &d)=delete
Convert datum into a type.
Definition: datum.hpp:19
Definition: syscache.hpp:9
Definition: syscache.hpp:26