add identity and lock
[m6w6/pq-gateway] / lib / pq / Query / Writer.php
1 <?php
2
3 namespace pq\Query;
4
5 /**
6 * A very simple query writer used by \pq\Gateway
7 */
8 class Writer implements WriterInterface
9 {
10 /**
11 * @var string
12 */
13 protected $query;
14
15 /**
16 * @var array
17 */
18 protected $params;
19
20 /**
21 * @var array
22 */
23 protected $types;
24
25 /**
26 * @param string $query initial query string
27 * @param array $params intial set of params
28 * @param array $types the types of the params
29 */
30 function __construct($query = "", array $params = array(), array $types = array()) {
31 $this->query = $query;
32 $this->params = $params;
33 $this->types = $types;
34 }
35
36 /**
37 * Get the query string
38 * @return string
39 */
40 function __toString() {
41 return $this->query;
42 }
43
44 /**
45 * Reduce arguments to write()
46 * @param string $q
47 * @param mixed $v
48 * @return string
49 */
50 protected function reduce($q, $v) {
51 if (is_array($v)) {
52 $v = implode(", ", $v);
53 }
54 if (strlen($q)) {
55 $q .= " ";
56 }
57 return $q . $v;
58 }
59
60 /**
61 * Get the query params
62 * @return array
63 */
64 function getParams() {
65 return $this->params;
66 }
67
68 /**
69 * Get the param types
70 * @return array
71 */
72 function getTypes() {
73 return $this->types;
74 }
75
76 /**
77 * Reset
78 * @return \pq\Query\Writer
79 */
80 function reset() {
81 $this->query = "";
82 $this->params = array();
83 $this->types = array();
84 return $this;
85 }
86
87 /**
88 * Append to the query string
89 * @return \pq\Query\Writer
90 */
91 function write() {
92 if (strlen($this->query)) {
93 $this->query .= " ";
94 }
95 $this->query .= array_reduce(func_get_args(), array($this, "reduce"));
96 return $this;
97 }
98
99 /**
100 * Write a param placeholder and push the param onto the param list
101 * @param mixed $param
102 * @param string $type
103 * @return string
104 */
105 function param($param, $type = null) {
106 if ($param instanceof ExpressibleInterface) {
107 $param = $param->get();
108 }
109 if ($param instanceof Expr) {
110 return (string) $param;
111 }
112
113 $this->params[] = $param;
114 $this->types[] = $type;
115
116 return "\$".count($this->params);
117 }
118
119 /**
120 * Write nested AND/OR criteria
121 * @param array $criteria
122 * @return \pq\Query\Writer
123 */
124 function criteria(array $criteria) {
125 if ((list($left, $right) = each($criteria))) {
126 $this->write("(");
127 if (is_array($right)) {
128 $this->criteria($right);
129 } else {
130 $this->write("(", $left, $this->param($right), ")");
131 }
132 while ((list($left, $right) = each($criteria))) {
133 $this->write(is_int($left) && is_array($right) ? "OR" : "AND");
134 if (is_array($right)) {
135 $this->criteria($right);
136 } else {
137 $this->write("(", $left, $this->param($right), ")");
138 }
139 }
140 $this->write(")");
141 }
142 return $this;
143 }
144 }