source: trunk/prototype/services/PostgreSQL.php @ 6132

Revision 6132, 12.6 KB checked in by marcosw, 12 years ago (diff)

Ticket #2697 - Inserir informações de copyright em cabeçalho de arquivos

Line 
1<?php
2/**
3 *
4 * Copyright (C) 2012 Consórcio Expresso Livre - 4Linux (www.4linux.com.br) e Prognus Software Livre (www.prognus.com.br)
5 *
6 * This program is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU Affero General Public License version 3 as published by
8 * the Free Software Foundation with the addition of the following permission
9 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
10 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
11 * WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program; if not, see www.gnu.org/licenses or write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21 * MA 02110-1301 USA.
22 *
23 * This code is based on the OpenXchange Connector and on the Prognus pSync
24 * Connector both developed by the community and licensed under the GPL
25 * version 2 or above as published by the Free Software Foundation.
26 *
27 * You can contact Prognus Software Livre headquarters at Av. Tancredo Neves,
28 * 6731, PTI, Edifício do Saber, 3º floor, room 306, Foz do Iguaçu - PR - Brasil or at
29 * e-mail address prognus@prognus.com.br.
30 *
31 * Classe de abstração que implementa métodos de manipulação de banco de dados
32 * executando instruções SQL a partir de parâmetros passados pelos métodos.
33 *
34 * @package    Prototype
35 * @license    http://www.gnu.org/copyleft/gpl.html GPL
36 * @author     Consórcio Expresso Livre - 4Linux (www.4linux.com.br) e Prognus Software Livre (www.prognus.com.br)
37 * @version    2.4
38 * @sponsor    Caixa Econômica Federal
39 * @since      Arquivo disponibilizado na versão 2.4
40 */
41
42/**
43 *
44 * @package    Prototype
45 * @license    http://www.gnu.org/copyleft/gpl.html GPL
46 * @author     Consórcio Expresso Livre - 4Linux (www.4linux.com.br) e Prognus Software Livre (www.prognus.com.br)
47 * @version    2.4
48 * @sponsor    Caixa Econômica Federal
49 * @since      Classe disponibilizada na versão 2.4
50 */
51class PostgreSQL implements Service
52{
53    private $con; //Conexão com o banco de dados
54    private $config; //Configuração
55    public  $error = false; //Armazena um erro caso ocorra
56   
57    public function find ( $uri, $justthese = false, $criteria = false ){
58                   
59        $map =  Config::get($uri['concept'], 'PostgreSQL.mapping');
60       
61        $criteria = ($criteria !== false) ? $this->parseCriteria ( $criteria , $map) : '';
62
63        $justthese = self::parseJustthese($justthese, $map);
64
65        return $this->execSql( 'SELECT '.$justthese['select'].' FROM '. (Config::get($uri['concept'],'PostgreSQL.concept')) .' '.$criteria );
66    }
67
68   public function read ( $uri, $justthese = false , $criteria = false){
69   
70      $map =  Config::get($uri['concept'], 'PostgreSQL.mapping');   
71      $justthese = self::parseJustthese($justthese, $map);
72      $criteria = ($criteria !== false) ? $this->parseCriteria ( $criteria , $map , ' WHERE '.$map['id'].' = \''.addslashes( $uri['id'] ).'\'') : ' WHERE '.$map['id'].' = \''.addslashes( $uri['id'] ).'\'';
73   
74      return $this->execSql( 'SELECT '.$justthese['select'].' FROM '. (Config::get($uri['concept'],'PostgreSQL.concept')) .$criteria , true );
75    }
76       
77    public function deleteAll ( $uri,   $justthese = false, $criteria = false ){
78            $map = Config::get($uri['concept'], 'PostgreSQL.mapping');
79            if(!self::parseCriteria ( $criteria , $map)) return false; //Validador para não apagar tabela inteira
80            return $this->execSql( 'DELETE FROM '.(Config::get($uri['concept'],'PostgreSQL.concept')).' '.self::parseCriteria ( $criteria ,$map) );
81    }
82
83    public function delete ( $uri, $justthese = false, $criteria = false ){
84            if(!isset($uri['id']) && !is_int($uri['id'])) return false; //Delete chamado apenas passando id inteiros
85            $map = Config::get($uri['concept'], 'PostgreSQL.mapping');
86            $criteria = ($criteria !== false) ? $this->parseCriteria ( $criteria , $map , ' WHERE '.$map['id'].' = \''.addslashes( $uri['id'] ).'\'') : ' WHERE '.$map['id'].' = \''.addslashes( $uri['id'] ).'\'';
87            return $this->execSql('DELETE FROM '.(Config::get($uri['concept'],'PostgreSQL.concept')).$criteria);
88    }
89
90    public function replace ( $uri,  $data, $criteria = false ){
91            $map = Config::get($uri['concept'], 'PostgreSQL.mapping');
92            return $this->execSql('UPDATE '.(Config::get($uri['concept'],'PostgreSQL.concept')).' '. self::parseUpdateData( $data ,$map).' '.self::parseCriteria($criteria , $map));
93    }
94               
95    public function update ( $uri,  $data, $criteria = false ){
96            $map = Config::get($uri['concept'], 'PostgreSQL.mapping');
97            $criteria = ($criteria !== false) ? $this->parseCriteria ( $criteria , $map , ' WHERE '.$map['id'].' = \''.addslashes( $uri['id'] ).'\'') : ' WHERE '.$map['id'].' = \''.addslashes( $uri['id'] ).'\'';
98            return $this->execSql('UPDATE '.(Config::get($uri['concept'],'PostgreSQL.concept')).' '. self::parseUpdateData( $data ,$map).$criteria);
99    }
100
101    public function create ( $uri,  $data ){   
102            return $this->execSql( 'INSERT INTO '.(Config::get($uri['concept'],'PostgreSQL.concept')).' '.self::parseInsertData( $data , $uri['concept'] ), true );
103    }
104
105    public function execSql( $sql, $unique = false )
106    {
107            if(!$this->con) $this->open( $this->config );
108
109            $rs = pg_query( $this->con, $sql );
110
111            if( is_bool( $rs ) )
112            {
113                if ( !$rs )
114                  $this->error = pg_last_error ( $this->con );
115
116                return( $rs );
117            }
118
119            if( pg_num_rows( $rs ) <= 0 )
120                return array();
121
122            $return = array();
123
124            while( $row = pg_fetch_assoc( $rs ) )
125                $return[] = $row;
126
127            return( $unique ? $return[0] : $return );
128    }
129
130    //@DEPRECATED
131    public function execResultSql( $sql, $unique = false ){
132            return $this->execSql( $sql, $unique );
133    }
134
135    public function begin( $uri ) {
136   
137        if(!$this->con)
138            $this->open( $this->config );
139       
140        $this->error = false;
141        pg_query($this->con, "BEGIN WORK");
142    }
143
144    public function commit($uri ) {
145   
146        if( $this->error !== false )
147        {
148            $error = $this->error;
149            $this->error = false;
150
151            throw new Exception( $error );
152        }
153
154        pg_query($this->con, "COMMIT");
155
156        return( true );
157    }
158
159    public function rollback( $uri ){
160   
161        pg_query($this->con, "ROLLBACK");
162    }
163
164    public function open  ( $config ){
165                       
166        $this->config = $config;
167       
168        $rs = '';
169        $rs .= ( isset($this->config['host']) && $this->config['host'] )  ? ' host='.$this->config['host'] : '' ;
170        $rs .= ( isset($this->config['user']) && $this->config['user'] )  ? ' user='.$this->config['user'] : '' ;
171        $rs .= ( isset($this->config['password']) && $this->config['password'] )  ? ' password='.$this->config['password'] : '' ;
172        $rs .= ( isset($this->config['dbname']) && $this->config['dbname'] )  ? ' dbname='.$this->config['dbname'] : '' ;
173        $rs .= ( isset($this->config['port']) && $this->config['port'] )  ? ' port='.$this->config['port'] : '' ;
174
175        if($this->con = pg_connect( $rs ))
176            return $this->con;
177
178        throw new Exception('It was not possible to enable the target connection!');
179        //$this->con = pg_connect('host='.$config['host'].' user='.$config['user'].' password='.$config['password'].' dbname='.$config['dbname'].'  options=\'--client_encoding=UTF8\'');
180    }
181
182    public function close(){
183
184            pg_close($this->con);
185           
186            $this->con = false;
187
188    }
189
190    public function setup(){}
191
192    public function teardown(){}
193
194    private static function parseInsertData( $data , $concept){
195         
196            $map = Config::get($concept, 'PostgreSQL.mapping');
197       
198            $ind = array();
199            $val = array();
200           
201            foreach ($data as $i => $v){
202                    if(!isset($map[$i])) continue;
203               
204                    $ind[] = $map[$i];
205                    $val[] = '\''.addslashes($v).'\'';
206            }
207           
208            return '('.implode(',', $ind).') VALUES ('.implode(',', $val).') RETURNING '.$map['id'].' as id';
209    }
210       
211    private static function parseUpdateData( $data , &$map){
212                                           
213            $d = array();
214            foreach ($data as $i => $v)
215            {
216                if(!isset($map[$i])) continue;
217               
218                $d[] = $map[$i].' = \''.addslashes ($v).'\'';
219            }
220           
221            return 'SET '.implode(',', $d);
222    }
223
224    private static function parseCriteria( $criteria  , &$map , $query = '' ){               
225       
226            if( isset($criteria["filter"]) && $criteria["filter"] !== NULL )
227            {
228                    /*
229                  * ex: array   (
230                  *               [0] 'OR',
231                  *               [1] array( 'OR', array( array( '=', 'campo', 'valor' ) ),
232                  *               [2] array( '=', 'campo' , 'valor' ),
233                  *               [3] array( 'IN', 'campo', array( '1' , '2' , '3' ) )
234                  *             )
235                  * OR
236                  *         array( '=' , 'campo' , 'valor' )
237                */
238                $query .= ($query === '') ?  'WHERE ('.self::parseFilter( $criteria['filter'] , $map).')' : ' AND ('.self::parseFilter( $criteria['filter'] , $map).')';
239            }
240            /*
241              * ex: array( 'table1' => 'table2' ,  'table1' => 'table2')
242              *         
243              */
244            if( isset($criteria["join"]) )
245            {
246                foreach ($criteria["join"] as $i => $v)
247                    $query .= ' AND '.$i.' = '.$v.' ';
248            }
249           
250            if( isset($criteria["group"]) )
251            {
252                    $query .= ' GROUP BY '.( is_array($criteria["group"]) ? implode(', ', $criteria["group"]) : $criteria["group"] ).' ';
253            }
254           
255            if( isset($criteria["order"]) )
256            {
257                    $query .= ' ORDER BY '.self::parseOrder( $criteria["order"], $map ).' ';
258            }
259            if( isset($criteria["limit"]) )
260            {
261                    $query .= ' LIMIT '. $criteria["limit"] .' ';
262            }
263            if( isset($criteria["offset"]) )
264            {
265                    $query .= ' OFFSET '. $criteria["offset"] .' ';
266            }
267           
268            return $query;
269    }
270   
271    private static function parseFilter( $filter ,&$map){
272   
273        if( !is_array( $filter ) || count($filter) <= 0) return null;
274               
275        $op = self::parseOperator( array_shift( $filter ) );
276       
277        if( is_array($filter[0]) )
278        {
279            $nested = array();
280
281            foreach( $filter as $i => $f )
282                if( $n = self::parseFilter( $f , $map))
283                    $nested[] = $n;
284
285               
286            return (count($nested) > 0 ) ? '('.implode( ' '.$op.' ', $nested ).')' : '';
287        }
288
289        if(!isset($map[$filter[0]])) return '';
290                 
291        $filter[0] = $map[$filter[0]];
292       
293        $igSuffix = $igPrefix = '';
294               
295        if( strpos( $op[0], 'i' ) === 0 )
296        {
297            $op[0] = substr( $op[0], 1 );
298            $filter[0] = 'upper("'.$filter[0].'")';
299            $igPrefix = 'upper(';
300            $igSuffix = ')';
301        }
302
303        if( is_array($filter[1]) )
304            return( $filter[0].' '.$op[0]." ($igPrefix'".implode( "'$igSuffix,$igPrefix'", array_map("addslashes" , $filter[1]) )."'$igSuffix)" );
305
306        return( $filter[0].' '.$op[0]." $igPrefix'".$op[1].addslashes( $filter[1] ).$op[2]."'$igSuffix" );
307    }
308
309    private static function parseOperator( $op ){
310   
311        switch(strtolower($op))
312        {
313            case 'and':
314            case 'or': return( $op );
315            case 'in': return array( $op );
316            case '^': return array( 'like', '%',  '' );
317            case '$': return array( 'like',  '', '%' );
318            case '*': return array( 'like', '%', '%' );
319            case 'i^': return array( 'ilike', '%',  '' );
320            case 'i$': return array( 'ilike',  '', '%' );
321            case 'i*': return array( 'ilike', '%', '%' );
322            default : return array( $op,  '',  '' );
323        }
324    }
325   
326    private static function parseJustthese($justthese , &$map)
327    {
328                 
329        if(!is_array($justthese)) //Caso seja um full select pegar todas as keys
330            $justthese = array_keys($map);
331
332        $return = array();
333
334        foreach ($justthese as &$value)
335        {
336            if(!isset($map[$value])) continue; //Escapa itens não existentes no mapa
337
338            if(is_array($map[$value]))
339                $return['deepness'][$value] = $map[$value];
340            else
341                $return['select'][] = $map[$value] .' as "'. $value. '"';
342        }
343       
344        $return['select'] = implode(', ', $return['select']);
345        return $return; 
346    }
347
348   private static function parseOrder($order , &$map)
349    {
350                 
351        if($notArray = !is_array($order)) //Caso seja um full select pegar todas as keys
352            $order = array( $order );
353
354        $return = array();
355
356        foreach ($order as &$value)
357        {
358            if(!isset($map[$value])) continue; //Escapa itens não existentes no mapa
359
360            $value = $map[$value];
361        }
362
363        return ( $notArray ?  $order[0] : implode(', ', $order) );
364    }
365}
366
367?>
Note: See TracBrowser for help on using the repository browser.