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

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