Subversion Repositories phpLibraryV2

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 rodolico 1
<?php
2
 
4 rodolico 3
   //require_once "DBDatabase.class.php";
6 rodolico 4
   global $DEBUG;
1 rodolico 5
 
6
   define( 'HTML_QUOTE_CHAR', '"' );
7
   define( 'CONSTANT_NO_VALUE_DROPDOWN', '--------' );
8
 
9
   class DBQuery {
4 rodolico 10
 
11
      // following are used for the class with no instantiation
12
      protected static $connected = false;
13
      protected static $connectionInfo = null; // connection information for database
6 rodolico 14
 
15
      protected $parameters = array(
16
                               // query to be run
17
                               'query' => '',
18
                               // the number of rows 1) affectd by an insert, update or delete or 2) returned by a select
19
                               'rowsAffected' => '',
20
                               // the value of the last row inserted (mysql only)
21
                               'lastInsertKey' => '',
22
                               // an array that contains the data retrieved by a query (select only)
23
                               'returnData' => '',
24
                               // an array that contains the meta data from the query
25
                               'columnMetaData' => '',
26
                               // if true, $returnData is an array of associative array, with the column names being the key fields
27
                               'useAssociativeArray' => '',
28
                               // if true, will return errors to STDOUT
29
                               'showErrors' => '',
30
                               // set to last error returned
31
                               'error' => '',
32
                               // Will be instantiation of a  Logging instance if set
33
                               'log' => '',
34
                               // if set to a table name, all queries are written to it
35
                               'auditTable' => '',
36
                               'orderBy' => '',
37
                             );
38
 
4 rodolico 39
 
40
      public static function connect( $connectionInfo = null ) {
41
         if ( isset ( $connectionInfo ) ) {
42
            DBQuery::$connectionInfo = $connectionInfo;
43
            if ( ! isset( DBQuery::$connectionInfo['host'] ) || DBQuery::$connectionInfo['host'] == '' )
44
               DBQuery::$connectionInfo['host'] = '127.0.0.1';
45
         } // if they passed in a connection string
46
         if ( ! DBQuery::$connected ) {
47
            try {
48
               if ( mysql_connect( DBQuery::$connectionInfo['host'], DBQuery::$connectionInfo['username'], DBQuery::$connectionInfo['password'] ) === false )
49
                  throw new Exception( mysql_error() );
50
               if ( mysql_select_db( DBQuery::$connectionInfo['name'] ) === false )
51
                  throw new Exception(mysql_error());
52
               DBQuery::$connected = true;
53
            } catch ( Exception $e ) {
54
               die( $e->getMessage() );
55
            }
56
         } // if we are not connected
57
      } // static function connect
58
 
6 rodolico 59
      protected function logIt ( $level, $message, $file = null, $class = null, $function = null, $line = null ) {
60
         global $DEBUG;
61
         if ( isset( $DEBUG ) ) {
62
            $DEBUG->writeLog( $level, $message, $file, $class, $function, $line );
63
         }
64
      } // logIt
65
 
1 rodolico 66
      public function __construct( $query, $whereClause = null, $orderBy = null, $runImmediate = false ) {
6 rodolico 67
         $this->parameters['query'] = $query;
1 rodolico 68
         if ( isset( $whereClause ) ) {
6 rodolico 69
            $this->parameters[ 'query' ] .= $this->makeWhereClause( $whereClause );
4 rodolico 70
         } // whereclause
1 rodolico 71
         if ( isset( $orderBy ) ) {
6 rodolico 72
            $this->parameters[ 'orderBy' ] .= ' order by ' . implode( ',', $orderBy );
4 rodolico 73
         } // orderby
6 rodolico 74
         $this->parameters[ 'rowsAffected' ] = 0;
75
         $this->parameters[ 'lastInsertKey' ] = '';
76
         $this->parameters[ 'returnData' ] = array();
77
         $this->parameters[ 'columnMetaData' ] = array();
78
         $this->parameters[ 'useAssociativeArray' ] = true;
79
         $this->parameters[ 'showErrors' ] = true;
80
         $this->parameters[ 'error' ] = '';
4 rodolico 81
         if ( $runImmediate )
1 rodolico 82
            $this->run();
6 rodolico 83
         // if (isset( $AUDITTABLE ) ) $this->parameters[ 'auditTable' ) =  new Logging( $LOGFILE );
4 rodolico 84
      } // __construct
1 rodolico 85
 
6 rodolico 86
      public function save() {
87
         return $this->parameters;
88
      } // function save
89
 
90
      public function load( $parameters = array() ) {
91
         $this->parameters = $parameters;
92
      } // function load
93
 
1 rodolico 94
      public function __set( $name, $value ) {
6 rodolico 95
         $this->parameters[$name] = $value;
4 rodolico 96
         return $value;
1 rodolico 97
      }
98
 
99
      public function __get( $name ) {
6 rodolico 100
         return isset( $this->parameters[$name] ) ? $this->parameters[$name] : null;
1 rodolico 101
      }
102
 
103
      public function __isset( $name ) {
6 rodolico 104
         return isset( $this->parameters[$name] );
1 rodolico 105
      }
106
 
107
      /* 
108
         function actually executes the query, populating the members with the results
6 rodolico 109
         returns true if no errors, false if errors (see $this->parameters[ 'error' ) for code)
1 rodolico 110
      */
111
      function run () {
6 rodolico 112
         if ( ! DBQuery::$connected ) {
113
            if ( isset( DBQuery::$connectionInfo ) ) {
114
               DBQuery::connect();
115
            } else {
116
               throw new Exception( "No Connection Available" );
117
            }
118
         }
1 rodolico 119
         // print "<pre>In Query database\n---------------------\n$query\n---------------------\n</pre>";
6 rodolico 120
         $this->logIt( 2, $this->parameters['query'] );
121
//         if ( isset( $this->parameters[ 'auditTable' )) ) audit( $query );
122
         $result = @mysql_query($this->parameters[ 'query' ]);
1 rodolico 123
         if( mysql_errno() ) {
6 rodolico 124
            $this->parameters[ 'error' ] = 'MYSQL ERROR #'.mysql_errno().' : <small>' . mysql_error(). "</small><br><VAR>$this->parameters[query]</VAR>";
125
            if ( $this->parameters[ 'showErrors' ] ) echo($this->parameters[ 'error' ]);
1 rodolico 126
            return false;
127
         } // if
6 rodolico 128
         if( preg_match ( '/^\s*select/i', $this->parameters[ 'query' ] ) ) { // this is a select statement
129
            $this->parameters[ 'rowsAffected' ] = @mysql_num_rows($result);
130
            $this->parameters[ 'columnMetaData' ] = array();
1 rodolico 131
            for ($i = 0; $i < mysql_num_fields( $result ); $i++) {
132
               $meta = mysql_fetch_field ( $result );
6 rodolico 133
               $this->parameters[ 'columnMetaData' ][] = array('name' => $meta->name, 'length' => $meta->max_length, 'numeric' => $meta->numeric, 'type' => $meta->type );
1 rodolico 134
            }
6 rodolico 135
            if( ! $this->parameters[ 'rowsAffected' ] ) return;
136
            $this->parameters[ 'returnData' ] = array();
137
            for( $i = 0; $i < $this->parameters[ 'rowsAffected' ]; $i++ ) {
138
               $this->parameters[ 'returnData' ][] = $this->parameters[ 'useAssociativeArray' ] ? mysql_fetch_assoc($result) : mysql_fetch_row($result);
1 rodolico 139
            }
140
            mysql_free_result($result);
141
         } else { // not a select statement
6 rodolico 142
            $this->parameters[ 'rowsAffected' ] = mysql_affected_rows();
143
            $this->parameters[ 'lastInsertKey' ] = mysql_insert_id();
1 rodolico 144
         }
145
         return true;
146
      } // function run
147
 
148
 
149
 
150
      /*
151
       * function will return one and only one row, NOT as an array of array
152
       * but as a single row array
153
       * if more than one row is returned by query, error is set and function
154
       * returns false.
155
       * Otherwise, function returns true
156
       */
157
      public function getOneRow( $sql = null ) {
158
         if ( isset( $sql ) )
6 rodolico 159
            $this->parameters[ 'query' ] = $sql;
160
         $save = $this->parameters[ 'useAssociativeArray' ];
1 rodolico 161
         $useAssociativeArray = true;
162
         $this->run();
163
         $useAssociativeArray = $save;
6 rodolico 164
         if ( $this->parameters[ 'rowsAffected' ] == 1 ) {
165
            $this->parameters[ 'returnData' ] = $this->parameters[ 'returnData' ][0];
1 rodolico 166
            return true;
167
         } else
6 rodolico 168
            $this->parameters['error'] = "$this->parameters[query] did not return a unique row in getOneRow";
1 rodolico 169
         return false;
170
      } // getOneRow
171
 
172
 
173
      // function returns the first column of the first row of data returned from query
174
      // or null no value returned
6 rodolico 175
      public function getOneDBValue( $sql = null ) {
1 rodolico 176
         if ( isset( $sql ) )
6 rodolico 177
            $this->parameters[ 'query' ] = $sql;
178
         $save = $this->parameters[ 'useAssociativeArray' ];
1 rodolico 179
         $useAssociativeArray = false;
180
         $this->run();
181
         $useAssociativeArray = $save;
6 rodolico 182
         return $this->parameters[ 'rowsAffected' ] ? $this->parameters[ 'returnData' ][0][0] : null;
1 rodolico 183
      }
184
 
6 rodolico 185
      public function countNumberOfRows ( $sql = null ) {
1 rodolico 186
         if ( isset( $sql ) )
6 rodolico 187
            $this->parameters[ 'query' ] = $sql;
188
         $save = $this->parameters[ 'useAssociativeArray' ];
189
         $this->parameters['useAssociativeArray'] = false;
1 rodolico 190
         $this->run();
6 rodolico 191
         $this->parameters['useAssociativeArray'] = $save;
192
         return $this->parameters[ 'rowsAffected' ];
1 rodolico 193
      }
194
 
6 rodolico 195
      public function makeWhereClause ($conditions, $joinedBy = 'and') {
1 rodolico 196
         $joinedBy = " $joinedBy "; // make sure there are spaces around it
197
         $whereClause = ' where ' . implode ( $joinedBy, $conditions );
198
         return $whereClause;
199
      }
200
 
201
      /* 
202
         values is an associative array of name/value pairs
203
         function will replace all items of the form <$name> with its values (the less than and greater than symbols around the key)
204
      */
6 rodolico 205
      protected function insertValuesIntoQuery( $values ) {
1 rodolico 206
         foreach ( $values as $name => $value ) {
6 rodolico 207
            $this->parameters[ 'query' ] = search_replace_string($this->parameters[ 'query' ], "<$name>", $value );
1 rodolico 208
         }
6 rodolico 209
      } // insertValuesIntoQuery
4 rodolico 210
 
6 rodolico 211
 
4 rodolico 212
      /*
213
       * function will attempt to make a constant ($value) safe for SQL depending on the type.
214
       * 
215
       * if $value is empty, $default is returned, as will happen if any of the
216
       * conversions (date, datetime, etc...) fail.
217
       * 
218
       * First, it will pass it through get_magic_quotes_gpc, 
219
       * then will run through mysql_real_escape_string
220
       * 
221
       * For strings, will encapsulate in quotes
222
       * Dates will attempt a conversion, then change to YYYY-MM-DD and encapsulate in quotes
223
       * DateTime will perform the same, but change to YYYY-MM-DD HH:MM:SS
224
       * Integer and Floats are passed through builtins intval and floatval
225
       * Boolean only checks the first character, a '0', 'f' and 'n' denoting false
226
       *    all else denoting true. The result is converted based on the variable
227
       *    $falsetrue, with the first char denoting false and the second denoting true
228
       */
229
      public static function makeSafeSQLConstant ( $value, $type='S', $default='null', $falsetrue='10' ) {
230
         if (strlen($value) == 0) // simply set any empty values to null
231
            return $default;
232
         // print "Processing $value as $type with default $default<br>\n";
233
         switch ( strtolower( $type ) ) {
234
            case 'string' :
235
            case 's' : 
236
                     if ( get_magic_quotes_gpc() ) 
237
                        $value = stripslashes($value);
238
                     $value = mysql_real_escape_string( $value );
239
                     $value = strlen( $value ) > 0 ? "'$value'" : $default;
240
                     break;
241
            case 'date' :
242
            case 'd' :
243
                     if ( $value != 'null' ) {
244
                        $result = strtotime( $value );
245
                        $value = ( $result === false ) ? $default : "'" . Date( 'Y-m-d', $result) . "'";
246
                     }
247
                     break;
248
            case 'datetime':
249
            case 'timestamp':
250
            case 'dt': 
251
                     if ( $value != 'null' ) {
252
                        $result = strtotime( $value );
253
                        $value = ( $result === false ) ? $default : "'" . Date( 'Y-m-d H:i:s', $result) . "'";
254
                     }
255
                     break;
256
            case 'integer':
257
            case 'i' :  
258
                     $value = intval( $value );
259
                     break;
260
            case 'float':
261
            case 'f' :  
262
                     $value = floatval( $value );
263
                     break;
264
            case 'bool':
265
            case 'boolean':
266
            case 'b' :  // note, because of the way strpos works, you can not
267
                        // simply set $value based on the output; you MUST do
268
                        // as below; specifically check for false, then set the result
269
                        $value =  strpos( '0fn', strtolower(substr( $value, 0, 1 )) ) === false ? 0 : 1;
270
                        $value = substr( $falsetrue, $value, 0, 1 );
271
                        break;
272
         } // switch
273
         return $value;
274
      }
1 rodolico 275
 
4 rodolico 276
 
1 rodolico 277
   } // class DBQuery
278
 
279
?>