1<?php 2 3namespace Basho\Riak\Command\Builder\MapReduce; 4 5use Basho\Riak; 6use Basho\Riak\Command; 7 8/** 9 * Builds the command to fetch a collection of objects from Riak using Yokozuna search 10 * 11 * @author Christopher Mancini <cmancini at basho d0t com> 12 */ 13class FetchObjects extends Command\Builder implements Command\BuilderInterface 14{ 15 /** 16 * MR inputs used by query phase 17 * 18 * @var array|string 19 */ 20 protected $inputs = []; 21 22 /** 23 * MR Query phases 24 * - options include map, reduce or link 25 * 26 * @var array 27 */ 28 protected $query = []; 29 30 /** 31 * Timeout for MR query 32 * 33 * @var int 34 */ 35 protected $timeout = 0; 36 37 /** 38 * {@inheritdoc} 39 * 40 * @return Command\MapReduce\Fetch; 41 */ 42 public function build() 43 { 44 $this->validate(); 45 46 if (is_array($this->inputs) && count($this->inputs) == 1) { 47 $this->inputs = $this->inputs[0]; 48 } 49 50 return new Command\MapReduce\Fetch($this); 51 } 52 53 /** 54 * {@inheritdoc} 55 */ 56 public function validate() 57 { 58 $this->required('Inputs'); 59 $this->required('Query'); 60 } 61 62 /** 63 * addBucketInput 64 * 65 * @param Riak\Bucket $bucket 66 * 67 * @return $this 68 */ 69 public function addBucketInput(Riak\Bucket $bucket) 70 { 71 // default bucket type cannot be passed to the MR api due to a bug 72 if ($bucket->getType() == 'default') { 73 $input = $bucket->getName(); 74 } else { 75 $input = [$bucket->getType(), $bucket->getName()]; 76 } 77 78 $this->inputs[] = $input; 79 80 return $this; 81 } 82 83 /** 84 * addLocationInput 85 * 86 * @param Riak\Location $location 87 * 88 * @return $this 89 */ 90 public function addLocationInput(Riak\Location $location) 91 { 92 // default bucket type cannot be passed to the MR api due to a bug 93 if ($location->getBucket()->getType() == 'default') { 94 $input = [$location->getBucket()->getName(), $location->getKey()]; 95 } else { 96 $input = [$location->getBucket()->getName(), $location->getKey(), '', $location->getBucket()->getType()]; 97 } 98 99 $this->inputs[] = $input; 100 101 return $this; 102 } 103 104 /** 105 * withInput 106 * 107 * Sets a single input value as a string. Can be: 108 * - a bucket with the default bucket type 109 * - a 2i index name 110 * - a Search/Yokozuna index name 111 * 112 * @param $input 113 * 114 * @return $this 115 */ 116 public function withInput($input) 117 { 118 $this->inputs = $input; 119 120 return $this; 121 } 122 123 /** 124 * withInputs 125 * 126 * Sets an array of inputs for the MR request 127 * 128 * @param array $inputs 129 * 130 * @return $this 131 */ 132 public function withInputs(array $inputs) 133 { 134 $this->inputs = $inputs; 135 136 return $this; 137 } 138 139 public function getInputs() 140 { 141 return $this->inputs; 142 } 143 144 /** 145 * @return string 146 */ 147 public function getQuery() 148 { 149 return $this->query; 150 } 151 152 /** 153 * buildMapPhase 154 * 155 * Allows you to define the Map Query Phase by using parameters 156 * 157 * @param string $bucket 158 * @param string $key 159 * @param string $source 160 * @param string $language 161 * @param bool $keep 162 * 163 * @return $this 164 */ 165 public function buildMapPhase($bucket = '', $key = '', $source = '', $language = 'javascript', $keep = false) 166 { 167 $this->setPhase('map', $this->assemblePhaseData($bucket, $key, $source, $language), $keep); 168 169 return $this; 170 } 171 172 /** 173 * setPhase 174 * 175 * @param $type 176 * @param $data 177 * @param bool $keep 178 */ 179 protected function setPhase($type, $data, $keep = false) 180 { 181 $data['keep'] = $keep; 182 $object = new \StdClass(); 183 $object->{$type} = $data; 184 $this->query[] = $object; 185 } 186 187 /** 188 * assemblePhaseData 189 * 190 * Assembles the parameters into a data structure to define a Query Phase 191 * 192 * @param string $bucket 193 * @param string $key 194 * @param string $source 195 * @param string $language 196 * @param string $tag 197 * 198 * @return array 199 */ 200 protected function assemblePhaseData($bucket = '', $key = '', $source = '', $language = '', $tag = '') 201 { 202 $data = []; 203 204 if ($language) { 205 $data['language'] = $language; 206 } 207 208 if ($bucket) { 209 $data['bucket'] = $bucket; 210 } 211 212 if ($key) { 213 $data['key'] = $key; 214 } 215 216 if ($source) { 217 $data['source'] = $source; 218 } 219 220 if ($tag) { 221 $data['tag'] = $tag; 222 } 223 224 return $data; 225 } 226 227 /** 228 * buildReducePhase 229 * 230 * Allows you to define the Reduce Query Phase by using parameters 231 * 232 * @param string $bucket 233 * @param string $key 234 * @param string $source 235 * @param string $language 236 * @param bool $keep 237 * 238 * @return $this 239 */ 240 public function buildReducePhase($bucket = '', $key = '', $source = '', $language = 'javascript', $keep = true) 241 { 242 $this->setPhase('reduce', $this->assemblePhaseData($bucket, $key, $source, $language), $keep); 243 244 return $this; 245 } 246 247 /** 248 * buildReducePhase 249 * 250 * Allows you to define the Reduce Query Phase by using parameters 251 * 252 * @param string $bucket 253 * @param string $tag 254 * @param bool $keep 255 * 256 * @internal param string $key 257 * @internal param string $source 258 * @internal param string $language 259 * @return $this 260 */ 261 public function buildLinkPhase($bucket = '', $tag = '', $keep = false) 262 { 263 $this->setPhase('link', $this->assemblePhaseData($bucket, '', '', '', $tag), $keep); 264 265 return $this; 266 } 267 268 /** 269 * withQuery 270 * 271 * Sets the Query Phase/s for the MR request. This value gets converted directly into a JSON array and passed to Riak 272 * 273 * @param array $query 274 * 275 * @return $this 276 */ 277 public function withQuery(array $query) 278 { 279 $this->query = $query; 280 281 return $this; 282 } 283} 284