-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBucket.php
375 lines (333 loc) · 10.5 KB
/
Bucket.php
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
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
<?php
namespace riiak;
use \CComponent,
\CJSON,
\Exception,
\Yii;
/**
* The Bucket object allows you to access and change information
* about a Riak bucket, and provides methods to create or retrieve
* objects within the bucket.
* @package riiak
*
* @property array $properties
* @property bool $allowMultiples
* @property int $dw
* @property int $nVal
* @property int $r
* @property int $w
*
* @property-read array $keys
*/
class Bucket extends CComponent {
/**
* Client instance
*
* @var \riiak\Riiak
*/
public $client;
/**
* Bucket name
*
* @var string
*/
public $name;
/**
* R-Value
*
* @var int
*/
protected $_r;
/**
* W-Value
*
* @var int
*/
protected $_w;
/**
* DW-Value
*
* @var int
*/
protected $_dw;
/**
* @var array
*/
protected $_properties;
/**
* @var array
*/
protected $_keys;
public function __construct(Riiak $client, $name) {
$this->client = $client;
$this->name = $name;
}
/**
* Get the R-Value for this bucket, if set. Falls back to client value.
*
* @param int $r Optional: The R-Value to be returned if not null
* @return int
*/
public function getR($r = null) {
if ($r !== null)
return $r;
if ($this->_r !== null)
return $this->_r;
return $this->client->r;
}
/**
* Set the R-value for this bucket.
* get/getBinary operations may use this value
*
* @param int $r The new R-Value
* @return \riiak\Bucket
*/
public function setR($r) {
$this->_r = $r;
return $this;
}
/**
* Get the W-Value for this bucket, if set. Falls back to client value.
*
* @param int $w Optional: The W-Value to be returned if not null
* @return int
*/
public function getW($w=null) {
if ($w !== null)
return $w;
if ($this->_w !== null)
return $this->_w;
return $this->client->w;
}
/**
* Set the W-Value for this bucket
* get/getBinary operations may use this value
*
* @param int $w The new W-Value
* @return \riiak\Bucket
*/
public function setW($w) {
$this->_w = $w;
return $this;
}
/**
* Get the DW-Value for this bucket, if set. Falls back to client value.
*
* @param int $dw Optional: The DW-Value to be returned if not null
* @return int
*/
public function getDW($dw=null) {
if ($dw !== null)
return $dw;
if ($this->_dw !== null)
return $this->_dw;
return $this->client->dw;
}
/**
* Set the DW-Value for this bucket
* get/getBinary operations may use this value
*
* @param int $dw The new DW-Value
* @return \riiak\Bucket
*/
public function setDW($dw) {
$this->_dw = $dw;
return $this;
}
/**
* Create a new Riak object that will be stored as JSON
*
* @param string $key optional Key value
* @param mixed $data optional Data to store (Default: null)
* @return \riiak\Object
*/
public function newObject($key = null, $data = null) {
return $this->newBinary($key, $data, 'application/json', true);
}
/**
* Create a new Riak object that will be stored as Binary
*
* @param string $key optional Key value
* @param mixed $data optional Data to store
* @param string $contentType optional Content type of the object (Default: application/json)
* @param bool $jsonize optional Whether to treat the object as JSON (Default: false)
* @return \riiak\Object
*/
public function newBinary($key = null, $data = null, $contentType = 'application/json', $jsonize = false) {
$obj = new Object($this->client, $this, $key);
$obj->data = $data;
$obj->contentType = $contentType;
$obj->jsonize = $jsonize;
return $obj;
}
/**
* Retrieve a JSON-encoded object from Riak
*
* @param string $key Name of the key
* @param int $r optional R-Value of the request (Default: bucket's R)
* @return \riiak\Object
*/
public function get($key, $r = null) {
return $this->getBinary($key, $r, true);
}
/**
* Retrieves binary/string object from Riak
*
* @param string $key Name of the key
* @param int $r R-Value of the request (Default: bucket's R)
* @param bool $jsonize Whether to treat the object as JSON (Default: false)
* @return \riiak\Object
*/
public function getBinary($key, $r = null, $jsonize = false) {
$obj = new Object($this->client, $this, $key);
$obj->jsonize = $jsonize;
$r = $this->getR($r);
return $obj->reload($r);
}
public function getMulti(array $keys, $r = null) {
return $this->getMultiBinary($keys, $r, true);
}
public function getMultiBinary(array $keys, $r = null, $jsonize = false) {
$bucket = $this;
$client = $this->client;
$objects = array_map(function($key)use($jsonize, $client, $bucket) {
$obj = new Object($client, $bucket, $key);
$obj->jsonize = $jsonize;
return $obj;
}, $keys);
$r = $this->getR($r);
return Object::reloadMulti($client, $objects, $r);
}
/**
* Set N-value for this bucket. Controls number replicas of each object
* that will be written. Set once before writing data to the bucket.
* Should never change this value from the initially used N-Val, otherwise
* unexpected results may occur. Only use if you know what you're doing
*
* @param int $nval The new N-Val
*/
public function setNVal($nval) {
$this->setProperty('n_val', $nval);
}
/**
* Retrieve the N-value for this bucket
*
* @return int
*/
public function getNVal() {
return $this->getProperty('n_val');
}
/**
* Whether writes can have conflicting data. Detect by calling hasSiblings()
* and getSiblings(). Only use if you know what you are doing
*
* @param bool $bool True to store & return conflicting writes
*/
public function setAllowMultiples($bool) {
$this->setProperty('allow_mult', $bool);
}
/**
* Retrieve the 'allow multiples' setting
*
* @return bool
*/
public function getAllowMultiples() {
return 'true' == $this->getProperty('allow_mult');
}
/**
* Set a bucket property. Only use if you know what you're doing
*
* @param string $key
* @param mixed $value
*/
public function setProperty($key, $value) {
$this->setProperties(array($key => $value));
}
/**
* Retrieve a bucket property
*
* @param string $key The property to retrieve
* @return mixed|null
*/
public function getProperty($key) {
$props = $this->getProperties();
if (array_key_exists($key, $props))
return $props[$key];
else
return null;
}
/**
* Set multiple bucket properties in one call. Only use if you know
* what you're doing
*
* @param array $props An associative array of $key=>$value
* @return Bucket
*/
public function setProperties(array $props) {
Yii::trace('Setting Bucket properties for bucket "' . $this->name . '"', 'ext.riiak.Bucket');
$this->client->transport->setBucket($this, array('props'=>$props));
$this->_properties = null;
return $this;
}
/**
* Retrieve an associative array of all bucket properties
*
* @param bool $refresh
* @return array
*/
public function getProperties($refresh = false) {
if ($refresh || !is_array($this->_properties)) {
Yii::trace('Fetching properties for bucket "' . $this->name . '"', 'ext.riiak.Bucket');
$props = $this->client->transport->listBucketProps($this);
if(empty($props))
return array();
$this->_properties = $props;
}
return $this->_properties;
}
/**
* Retrieve an array of all keys in this bucket
* Note: this operation is pretty slow
*
* @param bool $refresh
* @return array
*/
public function getKeys($refresh = false) {
if ($refresh || !is_array($this->_keys)) {
Yii::log('Bucket key listing is a very intensive operation, and should never occur in production!', \CLogger::LEVEL_WARNING);
Yii::trace('Fetching keys for bucket "' . $this->name . '"', 'ext.riiak.Bucket');
$this->_keys = $this->client->transport->listBucketKeys($this);
}
return $this->_keys;
}
/**
* Search a secondary index
* @author Eric Stevens <[email protected]>
* @param string $name - The name of the index to search
* @param string $type - The type of index ('int' or 'bin')
* @param string|int $startOrExact
* @param string|int $end optional
* @param bool $dedupe - whether to eliminate duplicate entries if any
* @return array of Links
*/
public function indexSearch($name, $type, $startOrExact, $end = NULL, $dedupe = false) {
$url = $this->client->transport->buildBucketIndexPath($this, $name . '_' . $type, $startOrExact, $end);
$response = $this->client->transport->get($url);
$obj = Object::populateResponse(new Object($this->client, $this), $response, 'secondaryIndex');
if (!$obj->exists)
throw new Exception('Error searching index.');
$data = $obj->data;
$keys = array_map('urldecode', $data['keys']);
/**
* Combo of array_keys+array_flip is faster than array_unique
*/
if ($dedupe)
$keys = array_keys(array_flip($keys));
array_walk($keys, array($this, 'inflateLinkCallback'));
return $keys;
}
protected function inflateLinkCallback(&$key, $k) {
$key = new Link($this->name, $key);
$key->client = $this->client;
}
}