1 | /*------------------------------------------------------------------------- |
2 | * |
3 | * compat.c |
4 | * Reimplementations of various backend functions. |
5 | * |
6 | * Portions Copyright (c) 2013-2019, PostgreSQL Global Development Group |
7 | * |
8 | * IDENTIFICATION |
9 | * src/bin/pg_waldump/compat.c |
10 | * |
11 | * This file contains client-side implementations for various backend |
12 | * functions that the rm_desc functions in *desc.c files rely on. |
13 | * |
14 | *------------------------------------------------------------------------- |
15 | */ |
16 | |
17 | /* ugly hack, same as in e.g pg_controldata */ |
18 | #define FRONTEND 1 |
19 | #include "postgres.h" |
20 | |
21 | #include <time.h> |
22 | |
23 | #include "utils/datetime.h" |
24 | #include "lib/stringinfo.h" |
25 | |
26 | /* copied from timestamp.c */ |
27 | pg_time_t |
28 | timestamptz_to_time_t(TimestampTz t) |
29 | { |
30 | pg_time_t result; |
31 | |
32 | result = (pg_time_t) (t / USECS_PER_SEC + |
33 | ((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY)); |
34 | return result; |
35 | } |
36 | |
37 | /* |
38 | * Stopgap implementation of timestamptz_to_str that doesn't depend on backend |
39 | * infrastructure. This will work for timestamps that are within the range |
40 | * of the platform time_t type. (pg_time_t is compatible except for possibly |
41 | * being wider.) |
42 | * |
43 | * XXX the return value points to a static buffer, so beware of using more |
44 | * than one result value concurrently. |
45 | * |
46 | * XXX: The backend timestamp infrastructure should instead be split out and |
47 | * moved into src/common. That's a large project though. |
48 | */ |
49 | const char * |
50 | timestamptz_to_str(TimestampTz dt) |
51 | { |
52 | static char buf[MAXDATELEN + 1]; |
53 | char ts[MAXDATELEN + 1]; |
54 | char zone[MAXDATELEN + 1]; |
55 | time_t result = (time_t) timestamptz_to_time_t(dt); |
56 | struct tm *ltime = localtime(&result); |
57 | |
58 | strftime(ts, sizeof(ts), "%Y-%m-%d %H:%M:%S" , ltime); |
59 | strftime(zone, sizeof(zone), "%Z" , ltime); |
60 | |
61 | snprintf(buf, sizeof(buf), "%s.%06d %s" , |
62 | ts, (int) (dt % USECS_PER_SEC), zone); |
63 | |
64 | return buf; |
65 | } |
66 | |
67 | /* |
68 | * Provide a hacked up compat layer for StringInfos so xlog desc functions can |
69 | * be linked/called. |
70 | */ |
71 | void |
72 | appendStringInfo(StringInfo str, const char *fmt,...) |
73 | { |
74 | va_list args; |
75 | |
76 | va_start(args, fmt); |
77 | vprintf(fmt, args); |
78 | va_end(args); |
79 | } |
80 | |
81 | void |
82 | appendStringInfoString(StringInfo str, const char *string) |
83 | { |
84 | appendStringInfo(str, "%s" , string); |
85 | } |
86 | |
87 | void |
88 | appendStringInfoChar(StringInfo str, char ch) |
89 | { |
90 | appendStringInfo(str, "%c" , ch); |
91 | } |
92 | |