1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Simple Machines Forum (SMF) |
5
|
|
|
* |
6
|
|
|
* @package SMF |
7
|
|
|
* @author Simple Machines http://www.simplemachines.org |
8
|
|
|
* @copyright 2017 Simple Machines and individual contributors |
9
|
|
|
* @license http://www.simplemachines.org/about/smf/license.php BSD |
10
|
|
|
* |
11
|
|
|
* @version 2.1 Beta 4 |
12
|
|
|
*/ |
13
|
|
|
|
14
|
|
|
if (!defined('SMF')) |
15
|
|
|
die('Hacking attempt...'); |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* PostgreSQL Cache API class |
19
|
|
|
* @package cacheAPI |
20
|
|
|
*/ |
21
|
|
|
class postgres_cache extends cache_api |
22
|
|
|
{ |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* @var false|resource of the pg_prepare from get_data. |
26
|
|
|
*/ |
27
|
|
|
private $pg_get_data_prep; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* @var false|resource of the pg_prepare from put_data. |
31
|
|
|
*/ |
32
|
|
|
private $pg_put_data_prep; |
33
|
|
|
|
34
|
|
|
public function __construct() |
35
|
|
|
{ |
36
|
|
|
parent::__construct(); |
37
|
|
|
|
38
|
|
|
} |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* {@inheritDoc} |
42
|
|
|
*/ |
43
|
|
|
public function connect() |
44
|
|
|
{ |
45
|
|
|
global $db_prefix, $db_connection; |
46
|
|
|
|
47
|
|
|
pg_prepare($db_connection, '', 'SELECT 1 |
48
|
|
|
FROM pg_tables |
49
|
|
|
WHERE schemaname = $1 |
50
|
|
|
AND tablename = $2'); |
51
|
|
|
|
52
|
|
|
$result = pg_execute($db_connection, '', array('public', $db_prefix . 'cache')); |
53
|
|
|
|
54
|
|
|
if (pg_affected_rows($result) === 0) |
55
|
|
|
pg_query($db_connection, 'CREATE UNLOGGED TABLE {db_prefix}cache (key text, value text, ttl bigint, PRIMARY KEY (key))'); |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* {@inheritDoc} |
60
|
|
|
*/ |
61
|
|
|
public function isSupported($test = false) |
62
|
|
|
{ |
63
|
|
|
global $smcFunc, $db_connection; |
64
|
|
|
|
65
|
|
|
|
66
|
|
|
if ($smcFunc['db_title'] !== 'PostgreSQL') |
67
|
|
|
return false; |
68
|
|
|
|
69
|
|
|
$result = pg_query($db_connection, 'SHOW server_version_num'); |
70
|
|
|
$res = pg_fetch_assoc($result); |
71
|
|
|
|
72
|
|
|
if ($res['server_version_num'] < 90500) |
73
|
|
|
return false; |
74
|
|
|
|
75
|
|
|
return $test ? true : parent::isSupported(); |
76
|
|
|
} |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* {@inheritDoc} |
80
|
|
|
*/ |
81
|
|
|
public function getData($key, $ttl = null) |
82
|
|
|
{ |
83
|
|
|
global $db_prefix, $db_connection; |
84
|
|
|
|
85
|
|
|
$ttl = time() - $ttl; |
86
|
|
|
|
87
|
|
|
if (empty($this->pg_get_data_prep)) |
88
|
|
|
$this->pg_get_data_prep = pg_prepare($db_connection, 'smf_cache_get_data', 'SELECT value FROM ' . $db_prefix . 'cache WHERE key = $1 AND ttl >= $2 LIMIT 1'); |
89
|
|
|
|
90
|
|
|
$result = pg_execute($db_connection, 'smf_cache_get_data', array($key, $ttl)); |
91
|
|
|
|
92
|
|
|
if (pg_affected_rows($result) === 0) |
93
|
|
|
return null; |
94
|
|
|
|
95
|
|
|
$res = pg_fetch_assoc($result); |
96
|
|
|
|
97
|
|
|
return $res['value']; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* {@inheritDoc} |
102
|
|
|
*/ |
103
|
|
|
public function putData($key, $value, $ttl = null) |
104
|
|
|
{ |
105
|
|
|
global $db_prefix, $db_connection; |
106
|
|
|
|
107
|
|
|
if (!isset($value)) |
108
|
|
|
$value = ''; |
109
|
|
|
|
110
|
|
|
$ttl = time() + $ttl; |
111
|
|
|
|
112
|
|
|
if (empty($this->pg_put_data_prep)) |
113
|
|
|
$this->pg_put_data_prep = pg_prepare($db_connection, 'smf_cache_put_data', |
114
|
|
|
'INSERT INTO ' . $db_prefix . 'cache(key,value,ttl) VALUES($1,$2,$3) |
115
|
|
|
ON CONFLICT(key) DO UPDATE SET value = excluded.value, ttl = excluded.ttl' |
116
|
|
|
); |
117
|
|
|
|
118
|
|
|
$result = pg_execute($db_connection, 'smf_cache_put_data', array($key, $value, $ttl)); |
119
|
|
|
|
120
|
|
|
if (pg_affected_rows($result) > 0) |
121
|
|
|
return true; |
122
|
|
|
else |
123
|
|
|
return false; |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* {@inheritDoc} |
128
|
|
|
*/ |
129
|
|
|
public function cleanCache($type = '') |
130
|
|
|
{ |
131
|
|
|
global $smcFunc; |
132
|
|
|
|
133
|
|
|
$smcFunc['db_query']('', |
134
|
|
|
'TRUNCATE TABLE {db_prefix}cache', |
135
|
|
|
array() |
136
|
|
|
); |
137
|
|
|
|
138
|
|
|
return true; |
139
|
|
|
} |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
?> |
|
|
|
|
Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.
A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.