/
kvdb.gtw
196 lines (130 loc) · 7.5 KB
/
kvdb.gtw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
~~LANG:FR@frman:kvdb~~
Jelix has an abstract layer to access to key-value databases, less complex than
SQL databases.
You have a @@C@jKVDb@@ from which you retrieve a connector to a key-value
database. Like jDb, there are some "profiles", stored in the
@@F@profiles.ini.php@@ file (See [[config#the-profiles.ini.php-file|the
corresponding chapter]]), where you define parameters to connect to these
databases.
jKVDb works with some "drivers" to access to "key-value" data. Jelix provides
drivers for simple files (file and file2), memcache, redis, and... sql. See
below for more informations about this drivers.
===== Configuration =====
As for jDb, @@F@profiles.ini.php@@ contains some section, one for each databases
you want to access. Each section should contain at least, one parameter,
@@driver@@, indicating the name of the driver to use. Other parameters should be
set, depending on the driver.
The connection type to indicate in profile names is @@jkvdb@@.
===== Accessing to a database =====
You must call @@jKVDb::getConnection()@@, by giving eventually a profile (else
the profile "default" is used). You retrieve an object inheriting from
@@C@jKVDriver@@.
With this object, you can access and modify the content of the key-value
database. Here are some methods you can call:
* @@M@get($key)@@: to retrieve the value corresponding to the given key. Returns null if the key does not exists.
* @@M@set($key, $value)@@: to store a new value or modify an existing value
* @@M@insert($key, $value)@@: to store a new value. return false if the key already exists
* @@M@replace($key,$value)@@: to change the value of the corresponding key. If the key doesn't exist, it returns false.
* @@M@delete($key)@@: delete the given key-value
* @@M@flush()@@: delete all keys
* @@M@append($key, $value)@@: append a string to an existing key value
* @@M@prepend($key, $value)@@: prepend a string to an existing key value
* @@M@increment($key)@@: increment the value. You can indicate also the value of the incrementation
* @@M@decrement($key)@@: decrement the value. You can indicate also the value of the decrementation
===== Other specific operations =====
Some drivers can implement additionnal methods, depending of the capabilites of the database. One of this interface is @@I@jIKVttl@@, where values have a limited life time.
To store such values, you should call the method @@M@setWithTtl($key, $value, $ttl)@@, where $ttl must be a value in seconds.
You can call also the @@M@garbage@@ method to delete all keys which are not anymore valid.
===== Drivers =====
==== memcache ====
It uses the Memcache API of PHP (don't confuse with the other API, memcached). It supports only the version 3.0.1 of memcache or lower.
In the profile, you have to indicate a host and a port, or several host/port. Example with a single server:
<code ini>
[jkvdb:mymemcacheserver]
driver=memcache
host=localhost
</code>
Or with several servers:
<code ini>
[jkvdb:mymemcacheserver]
driver=memcache
host=memcache_server1:11211;memcache_server2:11212
; or:
host[]=memcache_server1:11211
host[]=memcache_server2:11212
</code>
You can also set the parameter @@compress=1@@, so values will be compressed during the storage.
This driver supports the @@I@jIKVttl@@ interface.
==== redis ====
This driver allows to access to a Redis database.
In fact, there are two plugins:
* "redis_php": it uses a pure PHP class, PHPRedis to communicate with Redis.
(this plugin was named "redis" before Jelix 1.6.14)
* "redis_ext": it uses the API of the PHP extension Redis (plugin introduced
into Jelix 1.6.14)
For the configuration, indicate a @@host@@ and a @@port@@ parameter.
<code ini>
[jkvdb:myredis]
driver=redis_php
host = localhost
port = 6379
</code>
This driver supports the @@I@jIKVttl@@ interface.
Since Jelix 1.6.8, it supports also these parameters:
* @@db@@ : the database number in Redis (0 by default)
* @@key_prefix@@ : a prefix which will be added on each key
* @@key_prefix_flush_method@@: the method to delete keys when a prefix is indicated.
If you indicate a prefix, all keys you indicate to jKvDb will be prefixed
by the key_prefix value into the Redis database.
Moreover, when the jkvdb database is asked to be flushed, only keys having the prefix
will be deleted. However, because of how Redis is working, it may be very slow,
and then "freeze" your application.
So the plugin implements different methods to do the flush in this case. You
indicate the method into the @@key_prefix_flush_method@@ parameter:
* @@direct@@ : keys are deleted directly. This is the default behavior, but
should not use it if you know that your database could have hundred keys.
* @@jkvdbredisworker@@ : the deletion will be made asynchronously by a
worker or a cron script. See details below.
* @@event@@ : if you want an other behavior, you should implement it (and it
is better if it is an asynchronous process). Then you can notify your
implementation by listening the @@jKvDbRedisFlushKeyPrefix@@ event jEvent.
This event contains the profile name and the prefix of keys to delete.
How is the @@jkvdbredisworker@@ method working?
When a flush is asked, the plugin only stores the prefix into a Redis list,
named @@jkvdbredisdelkeys@@. A worker (a process that run aside the web server)
or a cron script (a script that is launched by the server periodically), should
then remove these prefixes from the list and delete corresponding keys.
You have an example of a such worker in @@F@lib/jelix/core-modules/jelix/controller/redisworker.cmdline.php@@.
You can launch it with systemd/sysinit/supervisord for example. The command is:
@@php myapp/scripts/script.php jelix~redisworker:deljkvdb <profile>@@.
Replace @@<profile>@@ by the profile name of jKvDb. It waits after incoming
prefixes in the list, and delete corresponding keys. If you launch it by hand on
the command line, just hit @@<ctrl>+C@@ to stop it.
==== db ====
It allows to use a SQL table as a storage for key-values. In the configuration, you must indicate:
* @@table@@: the name of the table to use
* @@dbprofile@@: the name of the jDb profile to use to access to the sql database.
The table should contain three fields, with specific field names and types. here is a SQL script to create such tables:
<code sql>
CREATE TABLE mykvdbtable (
k_key VARCHAR( 50 ) NOT NULL ,
k_value longblob NOT NULL ,
k_expire DATETIME NOT NULL ,
PRIMARY KEY (k_key)
);
</code>
You can have several tables, to avoid conflict between all modules which use jKVDb.
This driver supports the @@I@jIKVttl@@ interface.
==== file ====
It stores values in files. Each file content one value. Configuration:
* @@storage_dir@@: the directory where files are stored. Can contain shortcuts like "var:" or "temp:". default dir is @@F@var/kvfiles/@@.
* @@file_locking@@: false to disable file locking. By default: true.
* @@automatic_cleaning_factor@@: indicate the frequency to clean deprecated files. @@L@0@@ means never, @@L@1@@ means at each access, higher means a lower frequency.
* @@directory_level@@: if you know that you'll have thousand values, you can increase the directory level. By default: 2.
* @@directory_umask@@: umask of created directories. By default: 0700
* @@file_umask@@: umask of created files. By default: 0600.
This driver supports the @@I@jIKVttl@@ interface.
==== file2 ====
It is a driver similar to the "file" driver, but it is less sophisticated. It
has no configuration parameters and store files into @@F@temp/filekv/@@.
You must use it only for temporary values.