1 : <?php
2 :
3 : class PostgreSQL implements Service
4 : {
5 : private $con; //Conexão com o banco de dados
6 : private $config; //Configuração
7 : public $error = false; //Armazena um erro caso ocorra
8 :
9 : public function find ( $uri, $justthese = false, $criteria = false ){
10 :
11 0 : $map = Config::get($uri['concept'], 'PostgreSQL.mapping');
12 :
13 0 : $criteria = ($criteria !== false) ? $this->parseCriteria ( $criteria , $map) : '';
14 :
15 0 : $justthese = self::parseJustthese($justthese, $map);
16 :
17 0 : return $this->execResultSql( 'SELECT '.$justthese['select'].' FROM '. (Config::get($uri['concept'],'PostgreSQL.concept')) .' '.$criteria );
18 : }
19 :
20 : public function read ( $uri, $justthese = false , $criteria = false){
21 :
22 0 : $map = Config::get($uri['concept'], 'PostgreSQL.mapping');
23 0 : $justthese = self::parseJustthese($justthese, $map);
24 0 : $criteria = ($criteria !== false) ? $this->parseCriteria ( $criteria , $map , ' WHERE id = \''.addslashes( $uri['id'] ).'\'') : ' WHERE id = \''.addslashes( $uri['id'] ).'\'';
25 :
26 0 : return $this->execResultSql( 'SELECT '.$justthese['select'].' FROM '. (Config::get($uri['concept'],'PostgreSQL.concept')) .$criteria , true );
27 : }
28 :
29 : public function deleteAll ( $uri, $justthese = false, $criteria = false ){
30 2 : $map = Config::get($uri['concept'], 'PostgreSQL.mapping');
31 2 : if(!self::parseCriteria ( $criteria , $map)) return false; //Validador para não apagar tabela inteira
32 2 : return $this->execSql( 'DELETE FROM '.(Config::get($uri['concept'],'PostgreSQL.concept')).' '.self::parseCriteria ( $criteria ,$map) );
33 : }
34 :
35 : public function delete ( $uri, $justthese = false ){
36 0 : return $this->execSql('DELETE FROM '.(Config::get($uri['concept'],'PostgreSQL.concept')).' WHERE id = '.addslashes($uri['id']));
37 : }
38 :
39 : public function replace ( $uri, $data, $criteria = false ){
40 0 : $map = Config::get($uri['concept'], 'PostgreSQL.mapping');
41 0 : return $this->execSql('UPDATE '.(Config::get($uri['concept'],'PostgreSQL.concept')).' '. self::parseUpdateData( $data ,$map).' '.self::parseCriteria($criteria , $map));
42 : }
43 :
44 : public function update ( $uri, $data ){
45 0 : $map = Config::get($uri['concept'], 'PostgreSQL.mapping');
46 0 : return $this->execSql('UPDATE '.(Config::get($uri['concept'],'PostgreSQL.concept')).' '. self::parseUpdateData( $data ,$map).' WHERE id = \''. addslashes( $uri['id']) .'\'');
47 : }
48 :
49 : public function create ( $uri, $data ){
50 2 : return $this->execResultSql( 'INSERT INTO '.(Config::get($uri['concept'],'PostgreSQL.concept')).' '.self::parseInsertData( $data , $uri['concept'] ), true );
51 : }
52 :
53 : private function execSql( $sql ){
54 2 : if(!$this->con) $this->open( $this->config );
55 :
56 2 : $rs = pg_query( $this->con, $sql );
57 :
58 2 : if ( !$rs ){
59 0 : $this->error = pg_last_error ( $this->con );
60 0 : return false;
61 : }
62 :
63 2 : return $rs;
64 : }
65 :
66 : public function execResultSql( $sql, $unique = false ){
67 2 : $rs = $this->execSql( $sql );
68 :
69 2 : if( $rs && $rs > 0 )
70 2 : return self::parseSelectResult( $rs , $unique );
71 :
72 0 : return $rs;
73 : }
74 :
75 : public function begin( $uri ) {
76 :
77 2 : if(!$this->con)
78 2 : $this->open( $this->config );
79 :
80 2 : $this->error = false;
81 2 : pg_query($this->con, "BEGIN WORK");
82 2 : }
83 :
84 : public function commit($uri ) {
85 :
86 2 : if( $this->error !== false )
87 2 : {
88 0 : $error = $this->error;
89 0 : $this->error = false;
90 :
91 0 : throw new Exception( $error );
92 : }
93 :
94 2 : pg_query($this->con, "COMMIT");
95 :
96 2 : return( true );
97 : }
98 :
99 : public function rollback( $uri ){
100 :
101 0 : pg_query($this->con, "ROLLBACK");
102 0 : }
103 :
104 : public function open ( $config ){
105 :
106 1 : $this->config = $config;
107 :
108 1 : $rs = '';
109 1 : $rs .= ( isset($this->config['host']) && $this->config['host'] ) ? ' host='.$this->config['host'] : '' ;
110 1 : $rs .= ( isset($this->config['user']) && $this->config['user'] ) ? ' user='.$this->config['user'] : '' ;
111 1 : $rs .= ( isset($this->config['password']) && $this->config['password'] ) ? ' password='.$this->config['password'] : '' ;
112 1 : $rs .= ( isset($this->config['dbname']) && $this->config['dbname'] ) ? ' dbname='.$this->config['dbname'] : '' ;
113 1 : $rs .= ( isset($this->config['port']) && $this->config['port'] ) ? ' port='.$this->config['port'] : '' ;
114 :
115 1 : return( $this->con = pg_connect( $rs ) );
116 : //$this->con = pg_connect('host='.$config['host'].' user='.$config['user'].' password='.$config['password'].' dbname='.$config['dbname'].' options=\'--client_encoding=UTF8\'');
117 : }
118 :
119 : public function close(){
120 :
121 0 : pg_close($this->con);
122 :
123 0 : $this->con = false;
124 :
125 0 : }
126 :
127 0 : public function setup(){}
128 :
129 0 : public function teardown(){}
130 :
131 : private static function parseInsertData( $data , $concept){
132 :
133 2 : $map = Config::get($concept, 'PostgreSQL.mapping');
134 :
135 2 : $ind = array();
136 2 : $val = array();
137 :
138 2 : foreach ($data as $i => $v){
139 2 : if(!isset($map[$i])) continue;
140 :
141 2 : $ind[] = $map[$i];
142 2 : $val[] = '\''.addslashes($v).'\'';
143 2 : }
144 :
145 2 : return '('.implode(',', $ind).') VALUES ('.implode(',', $val).') RETURNING id';
146 : }
147 :
148 : private static function parseUpdateData( $data , &$map){
149 :
150 0 : $d = array();
151 0 : foreach ($data as $i => $v)
152 : {
153 0 : if(!isset($map[$i])) continue;
154 :
155 0 : $d[] = $map[$i].' = \''.addslashes ($v).'\'';
156 0 : }
157 :
158 0 : return 'SET '.implode(',', $d);
159 : }
160 :
161 : private static function parseSelectResult( $result , $unique = false){
162 :
163 2 : $return = array();
164 :
165 2 : if (!$result) return false;
166 2 : if (pg_num_rows($result) === 0) return $return;
167 : else
168 2 : while( $row = pg_fetch_assoc( $result ))
169 2 : $return[] = $row;
170 :
171 2 : if($unique === true) return $return[0];
172 :
173 0 : return $return;
174 : }
175 :
176 : private static function parseCriteria( $criteria , &$map , $query = '' ){
177 :
178 2 : if( isset($criteria["filter"]) && $criteria["filter"] !== NULL )
179 2 : {
180 : /*
181 : * ex: array (
182 : * [0] 'OR',
183 : * [1] array( 'OR', array( array( '=', 'campo', 'valor' ) ),
184 : * [2] array( '=', 'campo' , 'valor' ),
185 : * [3] array( 'IN', 'campo', array( '1' , '2' , '3' ) )
186 : * )
187 : * OR
188 : * array( '=' , 'campo' , 'valor' )
189 : */
190 2 : $query .= ($query === '') ? 'WHERE ('.self::parseFilter( $criteria['filter'] , $map).')' : ' AND ('.self::parseFilter( $criteria['filter'] , $map).')';
191 2 : }
192 : /*
193 : * ex: array( 'table1' => 'table2' , 'table1' => 'table2')
194 : *
195 : */
196 2 : if( isset($criteria["join"]) )
197 2 : {
198 0 : foreach ($criteria["join"] as $i => $v)
199 0 : $query .= ' AND '.$i.' = '.$v.' ';
200 0 : }
201 :
202 2 : if( isset($criteria["group"]) )
203 2 : {
204 0 : $query .= ' GROUP BY '.( is_array($criteria["group"]) ? implode(', ', $criteria["group"]) : $criteria["group"] ).' ';
205 0 : }
206 :
207 2 : if( isset($criteria["order"]) )
208 2 : {
209 0 : $query .= ' ORDER BY '.self::parseOrder( $criteria["order"], $map ).' ';
210 0 : }
211 2 : if( isset($criteria["limit"]) )
212 2 : {
213 0 : $query .= ' LIMIT '. $criteria["limit"] .' ';
214 0 : }
215 2 : if( isset($criteria["offset"]) )
216 2 : {
217 0 : $query .= ' OFFSET '. $criteria["offset"] .' ';
218 0 : }
219 :
220 2 : return $query;
221 : }
222 :
223 : private static function parseFilter( $filter ,&$map){
224 :
225 2 : if( !is_array( $filter ) || count($filter) <= 0) return null;
226 :
227 2 : $op = self::parseOperator( array_shift( $filter ) );
228 :
229 2 : if( is_array($filter[0]) )
230 2 : {
231 0 : $nested = array();
232 :
233 0 : foreach( $filter as $i => $f )
234 0 : if( $n = self::parseFilter( $f , $map))
235 0 : $nested[] = $n;
236 :
237 :
238 0 : return (count($nested) > 0 ) ? '('.implode( ' '.$op.' ', $nested ).')' : '';
239 : }
240 :
241 2 : if(!isset($map[$filter[0]])) return '';
242 :
243 2 : $filter[0] = $map[$filter[0]];
244 :
245 2 : $igSuffix = $igPrefix = '';
246 :
247 2 : if( strpos( $op[0], 'i' ) === 0 )
248 2 : {
249 0 : $op[0] = substr( $op[0], 1 );
250 0 : $filter[0] = 'upper("'.$filter[0].'")';
251 0 : $igPrefix = 'upper(';
252 0 : $igSuffix = ')';
253 0 : }
254 :
255 2 : if( is_array($filter[1]) )
256 2 : return( $filter[0].' '.$op[0]." ($igPrefix'".implode( "'$igSuffix,$igPrefix'", array_map("addslashes" , $filter[1]) )."'$igSuffix)" );
257 :
258 2 : return( $filter[0].' '.$op[0]." $igPrefix'".$op[1].addslashes( $filter[1] ).$op[2]."'$igSuffix" );
259 : }
260 :
261 : private static function parseOperator( $op ){
262 :
263 2 : switch(strtolower($op))
264 : {
265 2 : case 'and':
266 2 : case 'or': return( $op );
267 2 : case 'in': return array( $op );
268 2 : case '^': return array( 'like', '%', '' );
269 2 : case '$': return array( 'like', '', '%' );
270 2 : case '*': return array( 'like', '%', '%' );
271 2 : case 'i^': return array( 'ilike', '%', '' );
272 2 : case 'i$': return array( 'ilike', '', '%' );
273 2 : case 'i*': return array( 'ilike', '%', '%' );
274 2 : default : return array( $op, '', '' );
275 2 : }
276 : }
277 :
278 : private static function parseJustthese($justthese , &$map)
279 : {
280 :
281 0 : if(!is_array($justthese)) //Caso seja um full select pegar todas as keys
282 0 : $justthese = array_keys($map);
283 :
284 0 : $return = array();
285 :
286 0 : foreach ($justthese as &$value)
287 : {
288 0 : if(!isset($map[$value])) continue; //Escapa itens não existentes no mapa
289 :
290 0 : if(is_array($map[$value]))
291 0 : $return['deepness'][$value] = $map[$value];
292 : else
293 0 : $return['select'][] = $map[$value] .' as "'. $value. '"';
294 0 : }
295 :
296 0 : $return['select'] = implode(', ', $return['select']);
297 0 : return $return;
298 : }
299 :
300 : private static function parseOrder($order , &$map)
301 : {
302 :
303 0 : if($notArray = !is_array($order)) //Caso seja um full select pegar todas as keys
304 0 : $order = array( $order );
305 :
306 0 : $return = array();
307 :
308 0 : foreach ($order as &$value)
309 : {
310 0 : if(!isset($map[$value])) continue; //Escapa itens não existentes no mapa
311 :
312 0 : $value = $map[$value];
313 0 : }
314 :
315 0 : return ( $notArray ? $order[0] : implode(', ', $order) );
316 : }
317 : }
318 :
319 : ?>
|