add test
[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
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 return $q . " " . (is_array($v) ? implode(", ", $v) : $v);
52 }
53
54 /**
55 * Get the query params
56 * @return array
57 */
58 function getParams() {
59 return $this->params;
60 }
61
62 /**
63 * Get the param types
64 * @return array
65 */
66 function getTypes() {
67 return $this->types;
68 }
69
70 /**
71 * Reset
72 * @return \pq\Query\Writer
73 */
74 function reset() {
75 $this->query = "";
76 $this->params = array();
77 $this->types = array();
78 return $this;
79 }
80
81 /**
82 * Append to the query string
83 * @return \pq\Query\Writer
84 */
85 function write() {
86 $this->query .= array_reduce(func_get_args(), array($this, "reduce"));
87 return $this;
88 }
89
90 /**
91 * Write a param placeholder and push the param onto the param list
92 * @param mixed $param
93 * @param string $type
94 * @return string
95 */
96 function param($param, $type = null) {
97 if ($param instanceof \pq\Gateway\Cell) {
98 $param = $param->get();
99 }
100 if ($param instanceof Expr) {
101 return (string) $param;
102 }
103
104 $this->params[] = $param;
105 $this->types[] = $type;
106
107 return "\$".count($this->params);
108 }
109
110 /**
111 * Write nested AND/OR criteria
112 * @param array $criteria
113 * @return \pq\Query\Writer
114 */
115 function criteria(array $criteria) {
116 if ((list($left, $right) = each($criteria))) {
117 $this->write("(");
118 if (is_array($right)) {
119 $this->criteria($right);
120 } else {
121 $this->write("(", $left, $this->param($right), ")");
122 }
123 while ((list($left, $right) = each($criteria))) {
124 $this->write(is_int($left) && is_array($right) ? "OR" : "AND");
125 if (is_array($right)) {
126 $this->criteria($right);
127 } else {
128 $this->write("(", $left, $this->param($right), ")");
129 }
130 }
131 $this->write(")");
132 }
133 return $this;
134 }
135
136 /**
137 * Execute the query through \pq\Connection::execParams($this, $this->params, $this->types)
138 * @param \pq\Connection $c
139 * @return \pq\Result
140 */
141 function exec(\pq\Connection $c) {
142 return $c->execParams($this, $this->params, $this->types);
143 }
144 }