├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── install_mssql.sh
└── workflows
│ ├── ezsql-linux.yml
│ ├── ezsql-macos.yml
│ └── ezsql-windows.yml
├── CHANGELOG.md
├── CONTRIBUTORS.md
├── LICENSE
├── README.md
├── WIKI.md
├── _config.yml
├── cacert.pem
├── composer.json
├── lib
├── Config.php
├── ConfigAbstract.php
├── ConfigInterface.php
├── Constants.php
├── DInjector.php
├── Database.php
├── Database
│ ├── ez_mysqli.php
│ ├── ez_pdo.php
│ ├── ez_pgsql.php
│ ├── ez_sqlite3.php
│ └── ez_sqlsrv.php
├── DatabaseInterface.php
├── Db.php
├── Exception
│ ├── ContainerException.php
│ └── NotFoundException.php
├── ezFunctions.php
├── ezQuery.php
├── ezQueryInterface.php
├── ezResultset.php
├── ezSchema.php
├── ezsqlModel.php
└── ezsqlModelInterface.php
├── openssl.cnf
└── unsupported
├── .travis.yml
├── appveyor.yml
├── ez_sql_loader.php
├── lib
├── ez_sql_cubrid.php
├── ez_sql_oracle8_9.php
└── ez_sql_oracleTNS.php
└── tests
├── cubrid
└── ezSQL_cubridTest.php
└── oracle8_9
├── ezSQL_oracle8_9Test.php
└── ezSQL_oracleTNSTest_.php
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: error-bug, warning-bug
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 |
16 | **Expected behavior**
17 | A clear and concise description of what you expected to happen.
18 |
19 | > *Warning*: Failing to provide necessary information may cause the issue to be closed without consideration
20 |
21 | **Environment (please complete the following information):**
22 | - EZSQL Version :
23 | - PHP Version:
24 | - SQL Driver:[ mysql, pgsql, sqlserver, sqlite3]
25 |
26 | **PHP code snippet used**
27 |
28 | ```php
29 | rows_affected (thx Pere Pasqual)
41 |
42 | 2.14 - Added sybase connector by Muhammad Iyas
43 |
44 | 2.13 - Support for transactions. See: http://stackoverflow.com/questions/8754215/ezsql-with-multiple-queries/8781798
45 |
46 | 2.12 - Added $db->get_set() - Creates a SET nvp sql string from an associative array (and escapes all values)
47 |
48 | 2.11 - Fixed $db->insert_id in postgres version
49 |
50 | 2.10 - Added isset($this->dbh) check to oracle version
51 |
52 | 2.09 - Fixed issues with mysql_real_escape_string not working if no connection
53 | (Thanks to Nicolas Vannier)
54 |
55 | 2.08 - Re-added timer functions that seemed to have disappeared
56 |
57 | 2.07 - Used mysql_real_escape_string instead of mysql_escape_string
58 |
59 | 2.02 - Please note, this change log is no longer being used
60 | please see change_log.htm for changes later than
61 | 2.02
62 |
63 | 2.01 - Added Disk Caching & Multiple DB connection support
64 |
65 | 2.00 - Re-factored **ezsql** for Oracle, mySQL & SQLite
66 |
67 | - DB Object is no longer initialized by default
68 | (makes it easier to use multiple connections)
69 |
70 | - Core **ezsql** functions have been separated from DB
71 | specific functions (makes it easier to add new databases)
72 |
73 | - Errors are being piped through trigger_error
74 | (using standard PHP error logging)
75 |
76 | - Abstracted error messages (enabling future translation)
77 |
78 | - Upgraded $db->query error return functionality
79 |
80 | - Added $db->systdate function to abstract mySQL NOW()
81 | and Oracle SYSDATE
82 |
83 | Note: For other DB Types please use version 1.26
84 |
85 | 1.26 - Update (All)
86 |
87 | - Fixed the pesky regular expression that tests for
88 | an insert/update etc. Now it works even for the most
89 | weirdly formatted queries! (thx dille)
90 |
91 | 1.25 - Update (mySQL/Oracle)
92 |
93 | - Optimise $db->query function in both mySQL and Oracle versions.
94 | Now the return value is working 'as expected' in ALL cases so you
95 | are always safe using:
96 |
97 | if ( $db->query("some query") )
98 |
99 | No matter if an insert or a select.
100 |
101 | In the case of insert/update the return value is based on the
102 | number of rows affected (used to be insert id which is
103 | not valid for an update)
104 |
105 | In the case of select the return value is based on number of
106 | rows returned.
107 |
108 | Thx Bill Bruggemeyer :)
109 |
110 | 1.24 - Update (Docs)
111 |
112 | - Now includes tutorial for using EZ Results with Smarty
113 | templating engine - thx Steve Warwick
114 |
115 | 1.23 - Update (All PHP versions)
116 |
117 | - Fixed the age old problem of returning false on
118 | successful insert. $db->query()now returns the insert_id
119 | if there was a successful insert or false if not. Sorry
120 | that this took so long to fix!
121 |
122 | Version Affected: mySQL/Porgress/ms-sql/sqlite
123 |
124 | - Added new variable $db->debug_all
125 |
126 | By default it is set to false but if you change it
127 | to true. i.e.
128 |
129 | include_once "ez_sql.php";
130 | $db->debug_all = true;
131 |
132 | Then it will print out each and every query and all
133 | of the results that your script creates.
134 |
135 | Very useful if you want to follow the entire logic
136 | path of what ALL your queries are doing, but can't
137 | be bothered to put $db->debug() statements all over
138 | the place!
139 |
140 | Update (Postgress SQL Version)
141 |
142 | - Our old friend Tom De Bruyne as updated the postgress
143 | version.
144 |
145 | 1) It now works without throwing errors (also thanks Geert Nijpels)
146 |
147 | 2) It now, in theory, returns $this->insert_id after an insert.
148 |
149 |
150 | 1.22 - Update (All PHP versions)
151 |
152 | - Added new variable $db->num_queries it keeps track
153 | of exactly how many 'real' (not cached) queries were
154 | executed (using **ezsql**) during the lifetime of one script.
155 | Useful for debugging and optimizing.
156 |
157 | - Put a white table behind the vardump output so that
158 | it doesn't get lost on dark websites.
159 |
160 | 1.21 - Update (All Versions)
161 |
162 | - Now 'replace' really does return an insert id..
163 | (the 1.19 fix did not complete the job. Doh!)
164 |
165 | 1.20 - Update (New Version)
166 |
167 | - C++ SQLite version added. Look at ez_demo.cpp.
168 | (thanks Brennan Falkner)
169 |
170 | 1.19 - Update (All Versions)
171 |
172 | - Fixed bug where any string containing the word 'insert',
173 | 'delete' or 'update' (where those words were not the actual
174 | query) was causing unexpected results (thx Simon Willison).
175 |
176 | The fix was to alter the regular expression to only match
177 | queries containing those words at the beginning of the query
178 | (with optional whitespace allowed before the words)
179 |
180 | i.e.
181 |
182 | THIS: preg_match("/$word /", strtolower($query))
183 | TO THIS: preg_match("/^\\s*$word /", strtolower($query))
184 |
185 | - Added new sql word 'replace' to the above match pattern
186 | so that the $db->insert_id would be also be populated
187 | on 'replace' queries (thx Rolf Dahl)
188 |
189 | 1.18 - Update (All Versions)
190 |
191 | - Added new SQLite version (thanks Brennan Falkner)
192 |
193 | - Fixed new bug that was introduced with bug fix 1.14
194 | false was being returned on successful insert update etc.
195 | now it is true
196 |
197 | 1.17 - Update (All Versions)
198 |
199 | - New MS-SQL version added (thanks to Tom De Bruyne)
200 | - Made the donation request 'less annoying' by making it more subtle!
201 |
202 | 1.16 - Update (All Versions)
203 |
204 | - Added new function $db->escape()
205 | Formats a string correctly to stop accidental
206 | mal formed queries under all PHP conditions
207 |
208 | 1.15 - Bug fixes
209 |
210 | - (Postgres)
211 | $this->result = false; was in the wrong place.
212 | Fixed! Thanks (Carlos Camiña García)
213 |
214 | - (all versions)
215 | Pesky get_var was still returning null instead of 0 in
216 | certain cases. Bug fix of !== suggested by Osman
217 |
218 | 1.14 - Bug fixes
219 |
220 | - (all versions)
221 | Added !='' into the conditional return of get_var.
222 | because if the result was the number 0 it was not returning anything
223 |
224 | - (mySQL / Interbase / Postgres)
225 | Added $this->result = false; if insert / update / delete
226 | because it was causing mysql retrieval errors that no one
227 | knew about due to the @ signs.
228 |
229 | 1.13 - Update (All Versions)
230 |
231 | - Swapped 2nd and 3rd argument order.
232 | - From.. get_row(query, int row offset, output type)
233 | - To.... get_row(query, output type, int row offset)
234 |
235 | 1.12 - Update (All Versions)
236 |
237 | - Tweaked the new hide/show error code
238 | - Made sure the $this->show_errors was always initialized
239 | - $db->query() function now returns false if there was an SQL error.
240 | So that you can now do the following when you hide errors.
241 |
242 | if ( $db->query("BAD SYNTAX") )
243 | {
244 | echo "Bad Query";
245 | }
246 |
247 | 1.11 - Update (All Versions)
248 |
249 | - added $db->hide_errors();
250 | - added $db->show_errors();
251 | - added global array $EZSQL_ERROR;
252 |
253 | 1.10 - Fix (mySQL)
254 |
255 | - Insist that mysql_insert_id(); uses $this->dbh.
256 |
257 | 1.09 - Bug Fix
258 |
259 | - Oracle version had the wrong number of parameters in the
260 | $db = new db(etc,etc,etc,etc) part.
261 |
262 | - Also added var $vardump_called; to all versions.
263 |
264 | 1.08 - Bug Fix
265 |
266 | - Michael fixed the select function in PostgreSQL version.
267 |
268 | 1.07 - Bug Fix
269 |
270 | - Added var $debug_called; to all versions.
271 |
272 | 1.06 - Update
273 |
274 | - Fixed Bug In Oracle Version where an insert was
275 | causing an error with OCIFetch
276 | - New PostgreSQL Version Added by Michael Paesold (mpaesold@gmx.at)
277 |
278 | 1.05 - Bug Fix (mySQL)
279 |
280 | - Removed repeated piece of code.
281 |
282 | 1.04 - Update
283 |
284 | - $db->num_rows - variable added (All Versions)
285 | - $db->rows_affected - variable added ( mySQL / Oracle )
286 | - New InterBase/FireBase Version Added by LLCedar (llceder@wxs.nl)
287 |
288 | 1.03 - Update (All Versions)
289 |
290 | Enhancements to vardump..
291 |
292 | - Added display variable type
293 | - If no value display No Value / False
294 | - Added this readme file
295 |
296 | 1.02 - Update (mySQL version)
297 |
298 | - Added $db->insert_id to
299 |
300 | 1.01 - New Version
301 |
302 | - Oracle 8 Version as below
303 |
304 | 1.00 - Initial Release
305 |
306 | Functions..
307 |
308 | - $db->get_results - get multiple row result set from the database (or previously cached results)
309 | - $db->get_row -- get one row from the database (or previously cached results)
310 | - $db->get_col - get one column from query (or previously cached results) based on column offset
311 | - $db->get_var -- get one variable, from one row, from the database (or previously cached results)
312 | - $db->query -- send a query to the database (and if any results, cache them)
313 | - $db->debug - print last sql query and returned results (if any)
314 | - $db->vardump - print the contents and structure of any variable
315 | - $db->select -- select a new database to work with
316 | - $db->get_col_info - get information about one or all columns such as column name or type
317 | - $db = new db -- Initiate new db object.
--------------------------------------------------------------------------------
/CONTRIBUTORS.md:
--------------------------------------------------------------------------------
1 | **ezsql** *Contributors*
2 | ============================================
3 |
4 | * **[Justin Vincent](http://twitter.com/justinvincent)**
5 | > jv@jvmultimedia.com
6 | * Author: ezsql class - *ez_SQL_core, mySQL, PDO, PostgreSQL, Cubrid, Oracle8_9*
7 | Contact Info :
8 | * Follow me on twitter:
9 | http://twitter.com/justinvincent
10 | * Check out my podcast TechZing where we talk about tech and tech startups:
11 | http://techzinglive.com
12 |
13 | * **[Stefanie Janine Stoelting](https://stefanie-stoelting.de)**
14 | > mail@stefanie-stoelting.de
15 | * Author:
16 | * *ezsql version 3.00*
17 | * *oracleTNS*
18 | * *phpunit tests*
19 | * *RecordSet - for working with query results*
20 |
21 | * **davisjw**
22 | > davisjw@gmail.com
23 | * Author: ezsql class - *Sqlserver*
24 |
25 | * **Silvio Wanka**
26 | * Author: ezsql class - *sqlite3*
27 |
28 | ----
29 |
30 | ____L. Stubbs____
31 |
32 | > lstubbs@techno.express
33 |
34 | * Author/Maintainer:
35 | * ezsql version 3
36 | * In Development version *4.0*
37 | * *ezQuery, ezFunctions, ezSchema*
38 |
39 | ----
40 |
41 | **[Full contributors list.](https://github.com/ezsql/ezsql/contributors)**
42 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # **ezsql**
2 |
3 | [](https://github.com/ezSQL/ezsql/actions?query=workflow%3AWindows)
4 | [](https://github.com/ezSQL/ezsql/actions?query=workflow%3ALinux)
5 | [](https://github.com/ezSQL/ezsql/actions?query=workflow%3AmacOS)
6 | [](https://codecov.io/gh/ezSQL/ezSQL)
7 | [](https://www.codacy.com/app/techno-express/ezsql?utm_source=github.com&utm_medium=referral&utm_content=ezSQL/ezsql&utm_campaign=Badge_Grade)
8 | [](https://codeclimate.com/github/ezSQL/ezsql/maintainability)
9 | [](https://packagist.org/packages/ezsql/ezsql)
10 |
11 | ***A class to make it very easy to deal with database connections.***
12 | *An universal interchangeable **CRUD** system.*
13 |
14 | This is [__Version 5__](https://github.com/ezSQL/ezsql/tree/v5) which will break users of **version 4**.
15 |
16 | Mainly by:
17 |
18 | - The use of `namespace` in the `global` functions **ezFunctions.php** file.
19 | Usage of the **global** functions will require the user to begin a `.php` file something like:
20 |
21 | ```php
22 | use function ezsql\functions\where;
23 | // Or
24 | use function ezsql\functions\{
25 | getInstance,
26 | selecting,
27 | inserting,
28 | };
29 | ```
30 |
31 | - Class properties that was accessible by magic methods `get/set`, now PSR 1 camelCase.
32 | - Renamed `select` of `ez_mysqli` to `dbSelect`.
33 | - Renamed class method and behavior of `selecting` to `select`.
34 | - `selecting`, and new `inserting` methods, can be called without table name, only the other necessary parameters:
35 | - The table *name* with *prefix*, can be preset/stored with methods `tableSetup(name, prefix), or setTable(name), setPrefix(append)`, if called without presetting, `false` is returned.
36 | - This **feature** will be added to **all** database *CRUD* access methods , each method name will have an `ing` ending added.
37 | - Removed global functions where `table` name passed in, use functions using preset table names ending with `ing`.
38 | - renamed cleanInput to clean_string
39 | - renamed createCertificate to create_certificate
40 | - added global get_results to return result sets in different formats
41 |
42 | [__Version 4__](https://github.com/ezSQL/ezsql/tree/v4) has many modern programming practices in which will break users of version 3.
43 |
44 | [__Version 3__](https://github.com/ezSQL/ezsql/tree/v3) broke version 2.1.7 in one major way, it required *PHP 5.6*. Which drop mysql extension support, other than that, nothing as far using the library was changed, only additional features.
45 |
46 | This library has an `Database` class, an combination of the [Factory](https://en.wikipedia.org/wiki/Factory_method_pattern) pattern with an [Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection) container hosting. This library now is following many OOP principles, one in which, the methods properties public access has been removed. This library also following PSR-2, PSR-4, PSR-11 conventions, and mostly PSR-1, that's still an work in progress.
47 |
48 | * More Todo...
49 |
50 | For an full overview see [documentation Wiki](https://github.com/ezSQL/ezsql/wiki/Documentation), which is not completely finish.
51 |
52 | ## Installation
53 |
54 | composer require ezsql/ezsql
55 |
56 | ## Usage
57 |
58 | ```php
59 | require 'vendor/autoload.php';
60 |
61 | // **** is one of mysqli, pgsql, sqlsrv, sqlite3, or Pdo.
62 | use ezsql\Database;
63 |
64 | $db = Database::initialize('****', [$dsn_path_user, $password, $database, $other_settings], $optional_tag);
65 |
66 | // Is same as:
67 | use ezsql\Config;
68 | use ezsql\Database\ez_****;
69 |
70 | $settings = new Config('****', [$dsn_path_user, $password, $database, $other_settings]);
71 |
72 | $db = new ez_****($settings);
73 | ```
74 |
75 | This library will assume the developer is using some sort of IDE with intellisense enabled. The comments/doc-block area will hold any missing documentations. For additional examples see __phpunit__ tests, The tests are fully functional integration tests, meaning the are live database tests, no mocks.
76 |
77 | The following has been added since version 2.1.7.
78 |
79 | ___General Methods___
80 |
81 | to_string($arrays, $separation = ',');
82 | clean($string);
83 | create_cache(string $path = null);
84 | secureSetup(string $key = 'certificate.key',
85 | string $cert = 'certificate.crt',
86 | string $ca = 'cacert.pem',
87 | string $path = '.'._DS
88 | );
89 | secureReset();
90 | create_certificate(string $privatekeyFile = certificate.key,
91 | string $certificateFile = certificate.crt,
92 | string $signingFile = certificate.csr,
93 | string $ssl_path = null, array $details = [commonName => localhost]
94 | );
95 |
96 | ___Shortcut Table Methods___
97 |
98 | create(string $table = null, ...$schemas);// $schemas requires... column()
99 | column(string $column = null, string $type = null, ...$args);
100 | primary(string $primaryName, ...$primaryKeys);
101 | index(string $indexName, ...$indexKeys);
102 | drop(string $table);
103 |
104 | Example
105 |
106 | ```php
107 | // Creates an database table
108 | create('profile',
109 | // and with database column name, datatype
110 | // data types are global CONSTANTS
111 | // SEQUENCE|AUTO is placeholder tag, to be replaced with the proper SQL drivers auto number sequencer word.
112 | column('id', INTR, 11, AUTO, PRIMARY), // mysqli
113 | column('name', VARCHAR, 50, notNULL),
114 | column('email', CHAR, 25, NULLS),
115 | column('phone', TINYINT)
116 | );
117 | ```
118 |
119 | ---
120 |
121 | innerJoin(string $leftTable = null, string $rightTable = null,
122 | string $leftColumn = null, string $rightColumn = null, string $tableAs = null, $condition = EQ);
123 |
124 | leftJoin(string $leftTable = null, string $rightTable = null,
125 | string $leftColumn = null, string $rightColumn = null, string $tableAs = null, $condition = EQ);
126 |
127 | rightJoin(string $leftTable = null, string $rightTable = null,
128 | string $leftColumn = null, string $rightColumn = null, string $tableAs = null, $condition = EQ);
129 |
130 | fullJoin(string $leftTable = null, string $rightTable = null,
131 | string $leftColumn = null, string $rightColumn = null, string $tableAs = null, $condition = EQ);
132 | ---
133 |
134 | ```php
135 | prepareOn(); // When activated will use prepare statements for all shortcut SQL Methods calls.
136 | prepareOff(); // When off shortcut SQL Methods calls will use vendors escape routine instead. This is the default behavior.
137 | ```
138 |
139 | ### Shortcut SQL Methods
140 |
141 | * `having(...$having);`
142 | * `groupBy($groupBy);`
143 | * `union(string $table = null, $columnFields = '*', ...$conditions);`
144 | * `unionAll(string $table = null, $columnFields = '*', ...$conditions);`
145 | * `orderBy($orderBy, $order);`
146 | * `limit($numberOf, $offset = null)`
147 | * `where( ...$whereConditions);`
148 | * `select(string $table = null, $columnFields = '*', ...$conditions);`
149 | * `create_select(string $newTable, $fromColumns, $oldTable = null, ...$conditions);`
150 | * `select_into(string $newTable, $fromColumns, $oldTable = null, ...$conditions);`
151 | * `update(string $table = null, $keyAndValue, ...$whereConditions);`
152 | * `delete(string $table = null, ...$whereConditions);`
153 | * `replace(string $table = null, $keyAndValue);`
154 | * `insert(string $table = null, $keyAndValue);`
155 | * `create(string $table = null, ...$schemas);`
156 | * `drop(string $table = null);`
157 | * `alter(string $table = null, ...$alteringSchema);`
158 | * `insert_select(string $toTable = null, $toColumns = '*', $fromTable = null, $fromColumns = '*', ...$conditions);`
159 |
160 | ```php
161 | // The variadic ...$whereConditions, and ...$conditions parameters,
162 | // represent the following global functions.
163 | // They are comparison expressions returning an array with the given arguments,
164 | // the last arguments of _AND, _OR, _NOT, _andNOT will combine expressions
165 | eq('column', $value, _AND), // combine next expression
166 | neq('column', $value, _OR), // will combine next expression again
167 | ne('column', $value), // the default is _AND so will combine next expression
168 | lt('column', $value)
169 | lte('column', $value)
170 | gt('column', $value)
171 | gte('column', $value)
172 | isNull('column')
173 | isNotNull('column')
174 | like('column', '_%?')
175 | notLike('column', '_%?')
176 | in('column', ...$value)
177 | notIn('column', ...$value)
178 | between('column', $value, $value2)
179 | notBetween('column', $value, $value2)
180 | // The above should be used within the where( ...$whereConditions) clause
181 | // $value will protected by either using escape or prepare statement
182 | ```
183 |
184 | ```php
185 | // To allow simple grouping of basic $whereConditions,
186 | // wrap the following around a group of the above comparison
187 | // expressions within the where( ...$whereConditions) clause
188 | grouping( eq(key, value, combiner ), eq(key, value, combiner ) )
189 | // The above will wrap beginning and end grouping in a where statement
190 | // where required to break down your where clause.
191 | ```
192 |
193 | ```php
194 | // Note: The usage of this method will require the user/developer to check
195 | // if `query_string` or `param_array` is valid.
196 | //
197 | // This is really an `private` internal method for other shortcut methods,
198 | // it's made public for `class development` usage only.
199 | //
200 | //
201 | // Supply the the whole `query` string, and placing '?' within, with the same number of arguments in an array.
202 | // It will then determine arguments type, execute, and return results.
203 | query_prepared(string $query_string, array $param_array);
204 | // You will need to call this method to get last successful query result.
205 | // It wll return an object array.
206 | queryResult();
207 | ```
208 |
209 | #### Example for using prepare statements indirectly, with above shortcut SQL methods
210 |
211 | ```php
212 | // To get all shortcut SQL methods calls to use prepare statements
213 | $db->prepareOn(); // This needs to be called at least once at instance creation
214 |
215 | $values = [];
216 | $values['name'] = $user;
217 | $values['email'] = $address;
218 | $values['phone'] = $number;
219 | $db->insert('profile', $values);
220 | $db->insert('profile', ['name' => 'john john', 'email' => 'john@email', 'phone' => 123456]);
221 |
222 | // returns result set given the table name, column fields, and ...conditions
223 | $result = $db->select('profile', 'phone', eq('email', $email), between('id', 1, $values));
224 |
225 | foreach ($result as $row) {
226 | echo $row->phone;
227 | }
228 |
229 | $result = $db->select('profile', 'name, email',
230 | // Conditionals can also be called, stacked with other functions like:
231 | // innerJoin(), leftJoin(), rightJoin(), fullJoin()
232 | // as (leftTable, rightTable, leftColumn, rightColumn, tableAs, equal condition),
233 | // where( eq( columns, values, _AND ), like( columns, _d ) ),
234 | // groupBy( columns ),
235 | // having( between( columns, values1, values2 ) ),
236 | // orderBy( columns, desc ),
237 | // limit( numberOfRecords, offset ),
238 | // union(table, columnFields, conditions),
239 | // unionAll(table, columnFields, conditions)
240 | $db->where( eq('phone', $number, _OR), neq('id', 5) ),
241 | // another way: where( array(key, operator, value, combine, combineShifted) );
242 | // or as strings double spaced: where( "key operator value combine combineShifted" );
243 | $db->orderBy('name'),
244 | $db->limit(1)
245 | );
246 |
247 | foreach ($result as $row) {
248 | echo $row->name.' '.$row->email;
249 | }
250 |
251 | // To get results in `JSON` format
252 | $json = get_results(JSON, $db);
253 | ```
254 |
255 | #### Example for using prepare statements directly, no shortcut SQL methods used
256 |
257 | ```php
258 | $db->query_prepared('INSERT INTO profile( name, email, phone) VALUES( ?, ?, ? );', [$user, $address, $number]);
259 |
260 | $db->query_prepared('SELECT name, email FROM profile WHERE phone = ? OR id != ?', [$number, 5]);
261 | $result = $db->queryResult(); // the last query that has results are stored in `lastResult` protected property
262 | // Or for results in other formats use the global function, will use global database instance if no `$db` supplied
263 | $result = get_results(/* OBJECT|ARRAY_A|ARRAY_N|JSON */, $db); // Defaults to `OBJECT`
264 |
265 | foreach ($result as $row) {
266 | echo $row->name.' '.$row->email;
267 | }
268 | ```
269 |
270 | Most of shortcut methods have counter **global** _functions_ available.
271 | They can only be access by beginning your `.php` file like:
272 |
273 | ```php
274 | use function ezsql\functions\functionBelow;
275 | // Or as here, a complete list.
276 | use function ezsql\functions\{
277 | database,
278 | mysqlInstance,
279 | pgsqlInstance,
280 | mssqlInstance,
281 | sqliteInstance,
282 | pdoInstance,
283 | tagInstance,
284 | setInstance,
285 | getInstance,
286 | clearInstance,
287 | get_vendor,
288 | ///
289 | to_string,
290 | clean_string,
291 | is_traversal,
292 | sanitize_path,
293 | create_certificate,
294 | ///
295 | column,
296 | primary,
297 | foreign,
298 | unique,
299 | index,
300 | addColumn,
301 | dropColumn,
302 | changingColumn,
303 | ///
304 | eq,
305 | neq,
306 | ne,
307 | lt,
308 | lte,
309 | gt,
310 | gte,
311 | isNull,
312 | isNotNull,
313 | like,
314 | in,
315 | notLike,
316 | notIn,
317 | between,
318 | notBetween,
319 | ///
320 | where,
321 | grouping,
322 | groupBy,
323 | having,
324 | orderBy,
325 | limit,
326 | innerJoin,
327 | leftJoin,
328 | rightJoin,
329 | fullJoin,
330 | union,
331 | unionAll,
332 | ///
333 | creating,
334 | deleting,
335 | dropping,
336 | replacing,
337 | selecting,
338 | inserting,
339 | altering,
340 | get_results,
341 | table_setup,
342 | set_table,
343 | set_prefix,
344 | select_into,
345 | insert_select,
346 | create_select,
347 | };
348 | ```
349 |
350 | For the functions **usage/docs** see [ezFunctions.php](https://github.com/ezSQL/ezsql/blob/v5/lib/ezFunctions.php).
351 |
352 | ## For Authors and **[Contributors](https://github.com/ezSQL/ezsql/blob/master/CONTRIBUTORS.md)**
353 |
354 | ## Contributing
355 |
356 | Contributions are encouraged and welcome; I am always happy to get feedback or pull requests on Github :) Create [Github Issues](https://github.com/ezSQL/ezsql/issues) for bugs and new features and comment on the ones you are interested in.
357 |
358 | ## License
359 |
360 | **ezsql** is open-sourced software licensed originally under (LGPL-3.0), and the addon parts under (MIT).
361 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | plugins:
2 | - jekyll-relative-links
3 | relative_links:
4 | enabled: true
5 | collections: true
6 | include:
7 | - WIKI.md
8 | - README.md
9 | - CONTRIBUTORS.md
10 | - LICENSE.md
11 | - CODE_OF_CONDUCT.md
12 | - ISSUE_TEMPLATE.md
13 | - PULL_REQUEST_TEMPLATE.md
14 |
15 | theme: jekyll-theme-architect
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ezsql/ezsql",
3 | "description": "Advance database access library. Make interacting with a database ridiculously easy. An universal interchangeable CRUD system.",
4 | "keywords": [
5 | "crud",
6 | "dba",
7 | "mysql",
8 | "mysqli",
9 | "postgresql",
10 | "mssql",
11 | "sqlsrv",
12 | "sqlserver",
13 | "pdo",
14 | "sqlite",
15 | "sqlite3",
16 | "database",
17 | "abstraction",
18 | "sql"
19 | ],
20 | "license": [
21 | "LGPL-3.0-or-later",
22 | "MIT"
23 | ],
24 | "authors": [
25 | {
26 | "name": "Justin Vincent",
27 | "email": "webmaster@justinvincent.com"
28 | },
29 | {
30 | "name": "Stefanie Janine Stoelting",
31 | "email": "mail@stefanie-stoelting.de"
32 | },
33 | {
34 | "name": "l. stubbs",
35 | "email": "lstubbs@techno.express"
36 | }
37 | ],
38 | "support": {
39 | "issues": "https://github.com/ezSQL/ezSQL/issues"
40 | },
41 | "require": {
42 | "php": ">7.1",
43 | "psr/container": "^1.0"
44 | },
45 | "provide": {
46 | "psr/container-implementation": "1.0"
47 | },
48 | "autoload": {
49 | "files": [
50 | "lib/Constants.php",
51 | "lib/ezFunctions.php"
52 | ],
53 | "psr-4": {
54 | "ezsql\\": "lib/"
55 | }
56 | },
57 | "require-dev": {
58 | "phpunit/phpunit": "^6 | ^7 | ^8"
59 | },
60 | "autoload-dev": {
61 | "psr-4": {
62 | "ezsql\\Tests\\": "tests/"
63 | }
64 | },
65 | "scripts": {
66 | "test": "phpunit --bootstrap vendor/autoload.php tests"
67 | },
68 | "minimum-stability": "stable"
69 | }
70 |
--------------------------------------------------------------------------------
/lib/Config.php:
--------------------------------------------------------------------------------
1 | setDriver($sql);
20 | if ($sql == \Pdo) {
21 | $this->setupPdo($arguments);
22 | } elseif ($sql == \POSTGRESQL) {
23 | $this->setupPgsql($arguments);
24 | } elseif ($sql == \SQLSRV) {
25 | $this->setupSqlsrv($arguments);
26 | } elseif ($sql == \MYSQLI) {
27 | $this->setupMysqli($arguments);
28 | } elseif ($sql == \SQLITE3) {
29 | $this->setupSqlite3($arguments);
30 | }
31 | }
32 | }
33 |
34 | public static function initialize(string $driver = '', array $arguments = null)
35 | {
36 | return new self($driver, $arguments);
37 | }
38 |
39 | private function setupMysqli($args)
40 | {
41 | if (!\function_exists('mysqli_connect'))
42 | throw new Exception('Fatal Error: ez_mysql requires mySQLi Lib to be compiled and or linked in to the PHP engine');
43 |
44 | if (\count($args) >= 3) {
45 | $this->setUser($args[0]);
46 | $this->setPassword($args[1]);
47 | $this->setName($args[2]);
48 | $this->setHost(empty($args[3]) ? $this->getHost() : $args[3]);
49 | $this->setPort(empty($args[4]) ? '3306' : $args[4]);
50 | $charset = !empty($args[5]) ? $args[5] : '';
51 | $this->setCharset(empty($charset) ? $this->getCharset() : \strtolower(\str_replace('-', '', $charset)));
52 | } else
53 | throw new Exception(\MISSING_CONFIGURATION);
54 | }
55 |
56 | private function setupPdo($args)
57 | {
58 | if (!\class_exists('PDO'))
59 | throw new Exception('Fatal Error: ez_pdo requires PDO Lib to be compiled and or linked in to the PHP engine');
60 | if (\count($args) >= 3) {
61 | $this->setDsn($args[0]);
62 | $this->setUser($args[1]);
63 | $this->setPassword($args[2]);
64 | $this->setOptions(empty($args[3]) ? $this->getOptions() : $args[3]);
65 | $this->setIsFile(empty($args[4]) ? $this->getIsFile() : $args[4]);
66 | } else
67 | throw new Exception(\MISSING_CONFIGURATION);
68 | }
69 |
70 | private function setupSqlsrv($args)
71 | {
72 | if (!\function_exists('sqlsrv_connect'))
73 | throw new Exception('Fatal Error: ez_sqlsrv requires the php_sqlsrv.dll or php_pdo_sqlsrv.dll to be installed. Also enable MS-SQL extension in PHP.ini file ');
74 |
75 | if (\count($args) >= 3) {
76 | $this->setUser($args[0]);
77 | $this->setPassword($args[1]);
78 | $this->setName($args[2]);
79 | $this->setHost(empty($args[3]) ? $this->getHost() : $args[3]);
80 | $this->setToMssql(empty($args[4]) ? $this->getToMssql() : $args[4]);
81 | } else
82 | throw new Exception(\MISSING_CONFIGURATION);
83 | }
84 |
85 | private function setupPgsql($args)
86 | {
87 | if (!\function_exists('pg_connect'))
88 | throw new Exception('Fatal Error: ez_pgsql requires PostgreSQL Lib to be compiled and or linked in to the PHP engine');
89 |
90 | if (count($args) >= 3) {
91 | $this->setUser($args[0]);
92 | $this->setPassword($args[1]);
93 | $this->setName($args[2]);
94 | $this->setHost(empty($args[3]) ? $this->getHost() : $args[3]);
95 | $this->setPort(empty($args[4]) ? '5432' : $args[4]);
96 | } else
97 | throw new Exception(\MISSING_CONFIGURATION);
98 | }
99 |
100 | private function setupSqlite3($args)
101 | {
102 | if (!\class_exists('SQLite3'))
103 | throw new Exception('Fatal Error: ez_sqlite3 requires SQLite3 Lib to be compiled and or linked in to the PHP engine');
104 |
105 | if (\count($args) == 2) {
106 | $this->setPath($args[0]);
107 | $this->setName($args[1]);
108 | } else
109 | throw new Exception(\MISSING_CONFIGURATION);
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/lib/ConfigAbstract.php:
--------------------------------------------------------------------------------
1 |
5 | *
6 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
7 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
8 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
9 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
10 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
11 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
12 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
13 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
14 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
15 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
16 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17 | *
18 | * This software consists of voluntary contributions made by many individuals
19 | * and is licensed under the MIT license.
20 | */
21 |
22 | declare(strict_types=1);
23 |
24 | namespace ezsql;
25 |
26 | /**
27 | *
28 | * @method void setDriver($args);
29 | * Database Sql driver name
30 | * @method void setDsn($args);
31 | * The PDO connection parameter string, database server in the DSN parameters
32 | * @method void setUser($args);
33 | * Database user name
34 | * @method void setPassword($args);
35 | * Database password for the given user
36 | * @method void setName($args);
37 | * Database name
38 | * @method void setHost($args);
39 | * Host name or IP address
40 | * @method void setPort($args);
41 | * TCP/IP port of PostgreSQL/MySQL
42 | * @method void setCharset($args);
43 | * Database charset
44 | * @method void setOptions($args);
45 | * The PDO array for connection options, MySQL connection charset, for example
46 | * @method void setIsFile($args);
47 | * Check PDO for whether it is a file based database connection, for example to a SQLite
48 | * database file, or not
49 | * @method void setToMssql($args);
50 | * If we want to convert Queries in MySql syntax to MS-SQL syntax.
51 | * Yes, there are some differences in query syntax.
52 | * @method void setToMysql($args);
53 | * If we want to convert Queries in MySql syntax to MS-SQL syntax.
54 | * Yes, there are some differences in query syntax.
55 | * @method void setPath($args);
56 | * The path to open an SQLite database
57 | *
58 | * @method string getDriver();
59 | * Database Sql driver name
60 | * @method string getDsn();
61 | * The PDO connection parameter string, database server in the DSN parameters
62 | * @method string getUser();
63 | * Database user name
64 | * @method string getPassword()
65 | * Database password for the given user
66 | * @method string getName();
67 | * Database name
68 | * @method string getHost();
69 | * Host name or IP address
70 | * @method string getPort();
71 | * TCP/IP port of PostgreSQL/MySQL
72 | * @method string getCharset();
73 | * Database charset
74 | * @method string getOptions();
75 | * The PDO array for connection options, MySQL connection charset, for example
76 | * @method string getToMysql();
77 | * If we want to convert Queries in MySql syntax to MS-SQL syntax.
78 | * Yes, there are some differences in query syntax.
79 | * @method bool getIsFile();
80 | * Check PDO for whether it is a file based database connection, for example to a SQLite
81 | * database file, or not
82 | * @method bool getToMssql();
83 | * If we want to convert Queries in MySql syntax to MS-SQL syntax.
84 | * Yes, there are some differences in query syntax.
85 | * @method string getPath();
86 | * The path to open an SQLite database
87 | */
88 | abstract class ConfigAbstract
89 | {
90 | /**
91 | * Database Sql driver name
92 | * @var string
93 | */
94 | private $driver;
95 |
96 | /**
97 | * Database user name
98 | * @var string
99 | */
100 | private $user = '';
101 |
102 | /**
103 | * Database password for the given user
104 | * @var string
105 | */
106 | private $password = '';
107 |
108 | /**
109 | * Database name
110 | * @var string
111 | */
112 | private $name = '';
113 |
114 | /**
115 | * Host name or IP address
116 | * @var string
117 | */
118 | private $host = 'localhost';
119 |
120 | /**
121 | * Database charset
122 | * @var string Default is utf8
123 | */
124 | private $charset = 'utf8';
125 |
126 | /**
127 | * The PDO connection parameter string, database server in the DSN parameters
128 | * @var string Default is empty string
129 | */
130 | private $dsn = '';
131 |
132 | /**
133 | * The PDO array for connection options, MySQL connection charset, for example
134 | * @var array
135 | */
136 | private $options = array();
137 |
138 | /**
139 | * Check PDO for whether it is a file based database connection, for example to a SQLite
140 | * database file, or not
141 | * @var boolean Default is false
142 | */
143 | private $isfile = false;
144 |
145 | /**
146 | * TCP/IP port of PostgreSQL
147 | * @var string Default is port 5432
148 | */
149 | private $port = '5432';
150 |
151 | /**
152 | * If we want to convert Queries in MySql syntax to MS-SQL syntax.
153 | * Yes, there are some differences in query syntax.
154 | */
155 | private $tomssql = true;
156 |
157 | /**
158 | * The path to open an SQLite database
159 | */
160 | private $path = '';
161 |
162 | /**
163 | * Use for Calling Non-Existent Functions, handling Getters and Setters
164 | * @property-read function
165 | * @property-write args
166 | *
167 | * @return mixed
168 | */
169 | public function __call($function, $args)
170 | {
171 | $prefix = \substr($function, 0, 3);
172 | $property = \strtolower(substr($function, 3, \strlen($function)));
173 | if (($prefix == 'set') && \property_exists($this, $property)) {
174 | $this->$property = $args[0];
175 | } elseif (($prefix == 'get') && \property_exists($this, $property)) {
176 | return $this->$property;
177 | } else {
178 | throw new \Exception("$function does not exist");
179 | }
180 | }
181 | }
182 |
--------------------------------------------------------------------------------
/lib/ConfigInterface.php:
--------------------------------------------------------------------------------
1 | Fatal Error: Missing configuration details to connect to database');
17 | \define('CONFIGURATION_REQUIRES', 'Fatal Error: This configuration requires ezsqlModel (ezsqlModel.php) to be included/loaded before it can be used');
18 | \define('FAILED_CONNECTION', 'Failed to make connection to database');
19 |
20 | // ezQuery prepare placeholder/positional tag
21 | \define('_TAG', '__ez__');
22 |
23 | /**
24 | * Operator boolean expressions.
25 | */
26 | \define('EQ', '=');
27 | \define('NEQ', '<>');
28 | \define('NE', '!=');
29 | \define('LT', '<');
30 | \define('LTE', '<=');
31 | \define('GT', '>');
32 | \define('GTE', '>=');
33 | \define('_BOOLEAN', ['<', '>', '=', '!=', '>=', '<=', '<>']);
34 |
35 | \define('_IN', 'IN');
36 | \define('_notIN', 'NOT IN');
37 | \define('_LIKE', 'LIKE');
38 | \define('_notLIKE', 'NOT LIKE');
39 | \define('_BETWEEN', 'BETWEEN');
40 | \define('_notBETWEEN', 'NOT BETWEEN');
41 |
42 | \define('_isNULL', 'IS NULL');
43 | \define('_notNULL', 'IS NOT NULL');
44 | \define('_BOOLEAN_OPERATORS', [
45 | '<', '>', '=', '!=', '>=', '<=', '<>',
46 | 'IN', 'LIKE', 'NOT LIKE', 'BETWEEN', 'NOT BETWEEN', 'IS', 'IS NOT'
47 | ]);
48 |
49 | /**
50 | * Combine operators.
51 | */
52 | \define('_AND', 'AND');
53 | \define('_OR', 'OR');
54 | \define('_NOT', 'NOT');
55 | \define('_andNOT', 'AND NOT');
56 | \define('_COMBINERS', ['AND', 'OR', 'NOT', 'AND NOT']);
57 |
58 | /*
59 | * for joining shortcut methods.
60 | */
61 | \define('_INNER', 'INNER');
62 | \define('_LEFT', 'LEFT');
63 | \define('_RIGHT', 'RIGHT');
64 | \define('_FULL', 'FULL');
65 | \define('_JOINERS', ['INNER', 'LEFT', 'RIGHT', 'FULL']);
66 |
67 | /**
68 | * Associative array of supported SQL Drivers, and library
69 | * @define(array)
70 | */
71 | \define('VENDOR', [
72 | 'mysql' => 'ezsql\Database\ez_mysqli',
73 | 'mysqli' => 'ezsql\Database\ez_mysqli',
74 | 'pdo' => 'ezsql\Database\ez_pdo',
75 | 'postgresql' => 'ezsql\Database\ez_pgsql',
76 | 'pgsql' => 'ezsql\Database\ez_pgsql',
77 | 'sqlite' => 'ezsql\Database\ez_sqlite3',
78 | 'sqlite3' => 'ezsql\Database\ez_sqlite3',
79 | 'sqlserver' => 'ezsql\Database\ez_sqlsrv',
80 | 'mssql' => 'ezsql\Database\ez_sqlsrv',
81 | 'sqlsrv' => 'ezsql\Database\ez_sqlsrv'
82 | ]);
83 |
84 | \define('MYSQL', 'mysqli');
85 | \define('MYSQLI', 'mysqli');
86 | \define('Pdo', 'pdo');
87 | \define('PGSQL', 'pgsql');
88 | \define('POSTGRESQL', 'pgsql');
89 | \define('SQLITE', 'sqlite3');
90 | \define('SQLITE3', 'sqlite3');
91 | \define('SQLSRV', 'sqlsrv');
92 | \define('SQLSERVER', 'sqlsrv');
93 | \define('MSSQL', 'sqlsrv');
94 |
95 | // String SQL data types
96 | \define('CHAR', 'CHAR');
97 | \define('VARCHAR', 'VARCHAR');
98 | \define('CHARACTER', 'CHARACTER');
99 | \define('TEXT', 'TEXT');
100 | \define('TINY', 'TINYTEXT');
101 | \define('TINYTEXT', 'TINYTEXT');
102 | \define('MEDIUM', 'MEDIUMTEXT');
103 | \define('MEDIUMTEXT', 'MEDIUMTEXT');
104 | \define('LONGTEXT', 'LONGTEXT');
105 | \define('BINARY', 'BINARY');
106 | \define('VARBINARY', 'VARBINARY');
107 | \define('NCHAR', 'NCHAR');
108 | \define('NVAR', 'NVARCHAR');
109 | \define('NVARCHAR', 'NVARCHAR');
110 | \define('NTEXT', 'NTEXT');
111 | \define('IMAGE', 'IMAGE');
112 | \define('CLOB', 'CLOB');
113 |
114 | // Numeric SQL data types
115 | \define('INTR', 'INT');
116 | \define('INT0', 'INT');
117 | \define('INT2', 'INT2');
118 | \define('INT4', 'INT4');
119 | \define('INT8', 'INT8');
120 | \define('NUMERIC', 'NUMERIC');
121 | \define('DECIMAL', 'DECIMAL');
122 | \define('BIT', 'BIT');
123 | \define('VARBIT', 'VARBIT');
124 | \define('INTEGERS', 'INTEGER');
125 | \define('TINYINT', 'TINYINT');
126 | \define('SMALLINT', 'SMALLINT');
127 | \define('MEDIUMINT', 'MEDIUMINT');
128 | \define('BIGINT', 'BIGINT');
129 | \define('DEC', 'DEC');
130 | \define('FIXED', 'FIXED');
131 | \define('FLOATS', 'FLOAT');
132 | \define('DOUBLES', 'DOUBLE');
133 | \define('REALS', 'REAL');
134 | \define('BOOLS', 'BOOL');
135 | \define('BOOLEANS', 'BOOLEAN');
136 | \define('SMALLMONEY', 'SMALLMONEY');
137 | \define('MONEY', 'MONEY');
138 |
139 | // Date/Time SQL data types
140 | \define('DATES', 'DATE');
141 | \define('TIMESTAMP', 'TIMESTAMP');
142 | \define('TIMES', 'TIME');
143 | \define('DATETIME', 'DATETIME');
144 | \define('YEAR', 'YEAR');
145 | \define('DATETIME2', 'DATETIME2');
146 | \define('SMALLDATETIME', 'SMALLDATETIME');
147 | \define('DATETIMEOFFSET', 'DATETIMEOFFSET');
148 |
149 | // Large Object SQL data types
150 | \define('TINYBLOB', 'TINYBLOB');
151 | \define('BLOB', 'BLOB');
152 | \define('MEDIUMBLOB', 'MEDIUMBLOB');
153 |
154 | \define('NULLS', 'NULL');
155 | \define('notNULL', 'NOT NULL');
156 |
157 | \define('CONSTRAINT', 'CONSTRAINT');
158 | \define('PRIMARY', 'PRIMARY KEY');
159 | \define('FOREIGN', 'FOREIGN KEY');
160 | \define('UNIQUE', 'UNIQUE');
161 | \define('INDEX', 'INDEX');
162 | \define('REFERENCES', 'REFERENCES');
163 |
164 | \define('AUTO', '__autoNumbers__');
165 | \define('SEQUENCE', '__autoNumbers__');
166 | \define('AUTO_INCREMENT', 'AUTO_INCREMENT');
167 | \define('AUTOINCREMENT', 'AUTOINCREMENT');
168 | \define('IDENTITY', 'IDENTITY');
169 | \define('SERIAL', 'SERIAL');
170 | \define('SMALLSERIAL', 'SMALLSERIAL');
171 | \define('BIGSERIAL', 'BIGSERIAL');
172 |
173 | \define('ADD', 'ADD');
174 | \define('DROP', 'DROP COLUMN');
175 | \define('CHANGE', 'CHANGE COLUMN');
176 | \define('ALTER', 'ALTER COLUMN');
177 | \define('MODIFY', 'MODIFY COLUMN');
178 | \define('RENAME', 'RENAME TO');
179 | \define('CHANGER', '__modifyingColumns__');
180 |
181 | if (!\defined('_DS'))
182 | \define('_DS', \DIRECTORY_SEPARATOR);
183 |
184 | \define('CONSTANTS', true);
185 | }
186 |
--------------------------------------------------------------------------------
/lib/DInjector.php:
--------------------------------------------------------------------------------
1 | instances[$abstract] = $concrete;
36 | }
37 |
38 | /**
39 | * @param $abstract
40 | *
41 | * @return null|object
42 | * @throws NotFoundException
43 | */
44 | public function get($abstract, $values = [])
45 | {
46 | if (!$this->has($abstract)) {
47 | throw new NotFoundException("{$abstract} does not exists");
48 | }
49 |
50 | return $this->resolve($this->instances[$abstract], $values);
51 | }
52 |
53 | /**
54 | * Auto setup, execute, or resolve any dependencies.
55 | *
56 | * @param $abstract
57 | * @param array $values
58 | *
59 | * @return mixed|null|object
60 | * @throws ContainerException
61 | */
62 | public function autoWire($abstract, $values = [])
63 | {
64 | // if we don't have it, just register it
65 | if (!$this->has($abstract)) {
66 | $this->set($abstract);
67 | }
68 |
69 | return $this->resolve($this->instances[$abstract], $values);
70 | }
71 |
72 | /**
73 | * Do we have dependence
74 | * @param $abstract
75 | * @return bool
76 | */
77 | public function has($abstract): bool
78 | {
79 | return isset($this->instances[$abstract]);
80 | }
81 |
82 | /**
83 | * resolve single dependence
84 | *
85 | * @param $concrete
86 | * @param $values
87 | *
88 | * @return mixed|object
89 | * @throws ContainerException
90 | */
91 | protected function resolve($concrete, $values = [])
92 | {
93 | if ($concrete instanceof \Closure) {
94 | return $concrete($this, $values);
95 | }
96 |
97 | $reflector = new \ReflectionClass($concrete);
98 | // check if class is instantiable
99 | if (!$reflector->isInstantiable()) {
100 | throw new ContainerException("Class {$concrete} is not instantiable");
101 | }
102 |
103 | // get class constructor
104 | $constructor = $reflector->getConstructor();
105 | if (\is_null($constructor)) {
106 | // get new instance from class
107 | return $reflector->newInstance();
108 | }
109 |
110 | // get constructor params
111 | $parameters = $constructor->getParameters();
112 | $dependencies = $this->getDependencies($parameters, $values);
113 |
114 | // get new instance with dependencies resolved
115 | return $reflector->newInstanceArgs($dependencies);
116 | }
117 |
118 | /**
119 | * get all dependencies resolved
120 | *
121 | * @param $parameters
122 | *
123 | * @return array
124 | * @throws ContainerException
125 | */
126 | protected function getDependencies($parameters, $values = null)
127 | {
128 | $dependencies = [];
129 | if (\is_array($parameters)) {
130 | foreach ($parameters as $parameter) {
131 | // get the type hinted class
132 | $dependency = $parameter->getType() && !$parameter->getType()->isBuiltin()
133 | ? new \ReflectionClass($parameter->getType()->getName())
134 | : NULL;
135 | if ($dependency === NULL) {
136 | // check if the constructor parameter name exists as a key in the values array
137 | if (\array_key_exists($parameter->getName(), $values)) {
138 | // get default value of parameter
139 | $dependencies[] = $values[$parameter->getName()];
140 | } else {
141 | // check if default value for a parameter is available
142 | if ($parameter->isDefaultValueAvailable()) {
143 | // get default value of parameter
144 | $dependencies[] = $parameter->getDefaultValue();
145 | } else {
146 | throw new ContainerException("Can not resolve class dependency {$parameter->name}");
147 | }
148 | }
149 | } else {
150 | // get dependency resolved
151 | $dependencies[] = $this->autoWire($dependency->name, $values);
152 | }
153 | }
154 | }
155 |
156 | return $dependencies;
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/lib/Database.php:
--------------------------------------------------------------------------------
1 | set($key, $value);
88 | $di->set('ezsql\ConfigInterface', 'ezsql\Config');
89 | $instance = $di->get($key, ['driver' => $key, 'arguments' => $setting]);
90 | if (!empty($tag)) {
91 | self::$instances[$tag] = $instance;
92 | return $instance;
93 | }
94 | }
95 |
96 | $db = Db::get('ez' . $key);
97 | Db::set('global', $db);
98 | return $db;
99 | }
100 | }
101 |
102 | /**
103 | * Print-out a memory used benchmark.
104 | *
105 | * @return array|float time elapsed, memory usage.
106 | */
107 | public static function benchmark()
108 | {
109 | return [
110 | 'start' => self::$_ts,
111 | 'elapse' => \microtime(true) - self::$_ts,
112 | 'memory' => \memory_get_usage(true),
113 | ];
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/lib/Database/ez_pdo.php:
--------------------------------------------------------------------------------
1 | database = $settings;
46 |
47 | // Turn on track errors
48 | ini_set('track_errors', '1');
49 |
50 | if (!Db::has('ez' . \Pdo))
51 | Db::set('ez' . \Pdo, $this);
52 | Db::set('global', $this);
53 | } // __construct
54 |
55 | public function settings()
56 | {
57 | return $this->database;
58 | }
59 |
60 | /**
61 | * Try to connect to the database server in the DSN parameters
62 | *
63 | * @param string $dsn The connection parameter string
64 | * Default is empty string
65 | * @param string $user The database user name
66 | * Default is empty string
67 | * @param string $password The database password
68 | * Default is empty string
69 | * @param array $options Array for setting connection options
70 | * Default is an empty array
71 | * @param boolean $isFileBased File based databases like SQLite don't need user and password,
72 | * Default is false
73 | * @return boolean
74 | */
75 | public function connect(
76 | $dsn = '',
77 | $user = '',
78 | $password = '',
79 | $options = array(),
80 | $isFile = false
81 | ) {
82 | $this->_connected = false;
83 | $key = $this->sslKey;
84 | $cert = $this->sslCert;
85 | $ca = $this->sslCa;
86 | $path = $this->sslPath;
87 |
88 | $vendor = $this->database->getDsn();
89 | if ($this->isSecure) {
90 | if (\strpos($vendor, \PGSQL) !== false) {
91 | $this->secureOptions = 'sslmode=require;sslcert=' . $path . $cert . ';sslkey=' . $path . $key . ';sslrootcert=' . $path . $ca . ';';
92 | } elseif (\strpos($vendor, 'mysql') !== false) {
93 | $this->secureOptions = array(
94 | \PDO::MYSQL_ATTR_SSL_KEY => $path . $key,
95 | \PDO::MYSQL_ATTR_SSL_CERT => $path . $cert,
96 | \PDO::MYSQL_ATTR_SSL_CA => $path . $ca,
97 | \PDO::MYSQL_ATTR_SSL_CAPATH => $path,
98 | \PDO::MYSQL_ATTR_SSL_CIPHER => 'DHE-RSA-AES256-SHA',
99 | \PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false
100 | );
101 | } elseif (\strpos($vendor, \MSSQL) !== false) {
102 | $this->secureOptions = ';Encrypt=true;TrustServerCertificate=true';
103 | }
104 | }
105 |
106 | if ($this->isSecure && \is_string($this->secureOptions))
107 | $dsn = empty($dsn) ? $vendor . $this->secureOptions : $dsn . $this->secureOptions;
108 | else
109 | $dsn = empty($dsn) ? $vendor : $dsn;
110 |
111 | if ($this->isSecure && \is_array($this->secureOptions))
112 | $options = $this->secureOptions;
113 | else
114 | $options = empty($options) ? $this->database->getOptions() : $options;
115 |
116 | $user = empty($user) ? $this->database->getUser() : $user;
117 | $password = empty($password) ? $this->database->getPassword() : $password;
118 | $isFile = empty($isFile) ? $this->database->getIsFile() : $isFile;
119 |
120 | // Establish PDO connection
121 | try {
122 | if ($isFile) {
123 | $this->dbh = new \PDO($dsn, null, null, null);
124 | $this->_connected = true;
125 | } else {
126 | $this->dbh = new \PDO($dsn, $user, $password, $options);
127 | $this->_connected = true;
128 | }
129 | } catch (\PDOException $e) {
130 | $this->register_error($e->getMessage() . '- $dsn: ' . $dsn);
131 | }
132 |
133 | return $this->_connected;
134 | } // connect
135 |
136 | /**
137 | * With PDO it is only an alias for the connect method
138 | *
139 | * @param string $dsn The connection parameter string
140 | * - Default is empty string
141 | * @param string $user The database user name
142 | * - Default is empty string
143 | * @param string $password The database password
144 | * - Default is empty string
145 | * @param array $options Array for setting connection options
146 | * - Default is an empty array
147 | * @param boolean $isFileBased File based databases
148 | * like SQLite don't need user and password, they work with path in the dsn parameter
149 | * - Default is false
150 | * @return boolean
151 | */
152 | public function quick_connect(
153 | $dsn = '',
154 | $user = '',
155 | $password = '',
156 | $options = array(),
157 | $isFileBased = false
158 | ) {
159 | return $this->connect($dsn, $user, $password, $options, $isFileBased);
160 | } // quick_connect
161 |
162 | /**
163 | * Format a SQLite string correctly for safe SQLite insert
164 | * (no mater if magic quotes are on or not)
165 | */
166 |
167 | /**
168 | * Escape a string with the PDO method
169 | *
170 | * @param string $str
171 | * @return string
172 | */
173 | public function escape(string $str)
174 | {
175 | // If there is no existing database connection then try to connect
176 | if (!isset($this->dbh) || !$this->dbh) {
177 | $this->connect(
178 | $this->database->getDsn(),
179 | $this->database->getUser(),
180 | $this->database->getPassword(),
181 | $this->database->getOptions(),
182 | $this->database->getIsFile()
183 | );
184 | }
185 |
186 | // pdo quote adds ' at the beginning and at the end, remove them for standard behavior
187 | $return_val = \substr($this->dbh->quote($str), 1, -1);
188 |
189 | return $return_val;
190 | } // escape
191 |
192 | /**
193 | * Return SQLite specific system date syntax
194 | * i.e. Oracle: SYSDATE Mysql: NOW()
195 | *
196 | * @return string
197 | */
198 | public function sysDate()
199 | {
200 | return "datetime('now')";
201 | }
202 |
203 | /**
204 | * Hooks into PDO error system and reports it to user
205 | *
206 | * @return string
207 | */
208 | public function catch_error()
209 | {
210 | $error_str = 'No error info';
211 |
212 | $err_array = $this->dbh->errorInfo();
213 |
214 | // Note: Ignoring error - bind or column index out of range
215 | if (isset($err_array[1]) && $err_array[1] != 25) {
216 |
217 | $error_str = '';
218 | foreach ($err_array as $entry) {
219 | $error_str .= $entry . ', ';
220 | }
221 |
222 | $error_str = \substr($error_str, 0, -2);
223 |
224 | $this->register_error($error_str . ' ' . $this->lastQuery);
225 |
226 | return true;
227 | }
228 | } // catch_error
229 |
230 | /**
231 | * Creates a prepared query, binds the given parameters and returns the result of the executed
232 | *
233 | * @param string $query
234 | * @param array $param
235 | * @param boolean $isSelect - return \PDOStatement, if SELECT SQL statement, otherwise int
236 | * @return bool|int|\PDOStatement
237 | */
238 | public function query_prepared(string $query, array $param = null, $isSelect = false)
239 | {
240 | $stmt = $this->dbh->prepare($query);
241 | $result = false;
242 | if ($stmt && $stmt->execute(\array_values($param))) {
243 | $result = $stmt->rowCount();
244 | // Store Query Results
245 | $num_rows = 0;
246 | try {
247 | while ($row = @$stmt->fetch(\PDO::FETCH_ASSOC)) {
248 | // Store results as an objects within main array
249 | $this->lastResult[$num_rows] = (object) $row;
250 | $num_rows++;
251 | }
252 | } catch (\Throwable $ex) {
253 | //
254 | }
255 |
256 | $this->numRows = $num_rows;
257 | }
258 |
259 | $return = ($isSelect) ? $stmt : $result;
260 | if ($this->shortcutUsed)
261 | return $return;
262 |
263 | $status = ((\strpos($query, 'SELECT ') !== false) || (\strpos($query, 'select ') !== false));
264 | $prepareOnly = ($status) ? $stmt : $result;
265 | return $this->processResult($query, $prepareOnly, $status);
266 | }
267 |
268 | /**
269 | * Perform post processing on SQL query call
270 | *
271 | * @param string $query
272 | * @param mixed $result
273 | * @param bool $isSelect
274 | * @return bool|void
275 | */
276 | private function processResult(string $query, $result = null, bool $isSelect = false)
277 | {
278 | $this->shortcutUsed = false;
279 |
280 | // If there is an error then take note of it..
281 | if ($this->catch_error()) {
282 | return false;
283 | }
284 |
285 | if ($isSelect) {
286 | $this->is_insert = false;
287 |
288 | if (!empty($result)) {
289 | $col_count = $result->columnCount();
290 | for ($i = 0; $i < $col_count; $i++) {
291 | // Start DEBUG by psc!
292 | $this->colInfo[$i] = new \stdClass();
293 | // End DEBUG by psc
294 | if ($meta = $result->getColumnMeta($i)) {
295 | $this->colInfo[$i]->name = $meta['name'];
296 | $this->colInfo[$i]->type = $meta['native_type'];
297 | $this->colInfo[$i]->max_length = '';
298 | } else {
299 | $this->colInfo[$i]->name = 'undefined';
300 | $this->colInfo[$i]->type = 'undefined';
301 | $this->colInfo[$i]->max_length = '';
302 | }
303 | }
304 |
305 | // Store Query Results
306 | $num_rows = 0;
307 | try {
308 | while ($row = @$result->fetch(\PDO::FETCH_ASSOC)) {
309 | // Store results as an objects within main array
310 | $this->lastResult[$num_rows] = (object) $row;
311 | $num_rows++;
312 | }
313 | } catch (\Throwable $ex) {
314 | //
315 | }
316 |
317 | // Log number of rows the query returned
318 | $this->numRows = empty($num_rows) ? $this->numRows : $num_rows;
319 |
320 | // Return number of rows selected
321 | $this->return_val = $this->numRows;
322 | }
323 | } else {
324 | $this->is_insert = true;
325 |
326 | if (!empty($result))
327 | $this->_affectedRows = $result;
328 |
329 | try {
330 | // Take note of the insert_id
331 | if (\preg_match("/^(insert|replace)\s+/i", $query)) {
332 | $this->insertId = @$this->dbh->lastInsertId();
333 | }
334 | } catch (\Throwable $ex) {
335 | //
336 | }
337 |
338 | // Return number of rows affected
339 | $this->return_val = $this->_affectedRows;
340 | }
341 |
342 | return $this->return_val;
343 | }
344 |
345 | /**
346 | * Perform SQL query
347 | *
348 | * @param string $query
349 | * @param array $param
350 | * @return bool|void
351 | */
352 | private function processQuery(string $query, array $param = null)
353 | {
354 | // Query was an insert, delete, update, replace
355 | if (\preg_match("/^(insert|delete|update|replace|drop|create)\s+/i", $query)) {
356 | // Perform the query and log number of affected rows
357 | // Perform the query via std PDO query or PDO prepare function..
358 | if (!empty($param) && \is_array($param) && $this->isPrepareOn()) {
359 | $this->shortcutUsed = true;
360 | $this->_affectedRows = $this->query_prepared($query, $param, false);
361 | } else {
362 | try {
363 | $this->_affectedRows = $this->dbh->exec($query);
364 | } catch (\Throwable $ex) {
365 | //
366 | }
367 | }
368 |
369 | if ($this->processResult($query) === false)
370 | return false;
371 | } else {
372 | // Query was an select
373 |
374 | // Perform the query and log number of affected rows
375 | // Perform the query via std PDO query or PDO prepare function..
376 | if (!empty($param) && \is_array($param) && $this->isPrepareOn()) {
377 | $this->shortcutUsed = true;
378 | $sth = $this->query_prepared($query, $param, true);
379 | } else
380 | try {
381 | $sth = $this->dbh->query($query);
382 | } catch (\Throwable $ex) {
383 | //
384 | }
385 |
386 | if ($this->processResult($query, $sth, true) === false)
387 | return false;
388 | }
389 | }
390 |
391 | /**
392 | * Basic Query - see docs for more detail
393 | *
394 | * @param string $query
395 | * @param bool $use_prepare
396 | * @return object
397 | */
398 | public function query(string $query, bool $use_prepare = false)
399 | {
400 | $param = [];
401 | if ($use_prepare)
402 | $param = $this->prepareValues();
403 |
404 | // check for ezQuery placeholder tag and replace tags with proper prepare tag
405 | $query = \str_replace(_TAG, '?', $query);
406 |
407 | // For reg expressions
408 | $query = \str_replace("/[\n\r]/", '', \trim($query));
409 |
410 | // Initialize return
411 | $this->return_val = 0;
412 |
413 | // Flush cached values..
414 | $this->flush();
415 |
416 | // Log how the function was called
417 | $this->log_query("\$db->query(\"$query\")");
418 |
419 | // Keep track of the last query for debug..
420 | $this->lastQuery = $query;
421 |
422 | $this->numQueries++;
423 |
424 | // Start timer
425 | $this->timer_start($this->numQueries);
426 |
427 | // Use core file cache function
428 | if ($cache = $this->get_cache($query)) {
429 | // Keep tack of how long all queries have taken
430 | $this->timer_update_global($this->numQueries);
431 |
432 | // Trace all queries
433 | if ($this->useTraceLog) {
434 | $this->traceLog[] = $this->debug(false);
435 | }
436 |
437 | return $cache;
438 | }
439 |
440 | // If there is no existing database connection then try to connect
441 | if (!isset($this->dbh) || !$this->dbh) {
442 | $this->connect(
443 | $this->database->getDsn(),
444 | $this->database->getUser(),
445 | $this->database->getPassword(),
446 | $this->database->getOptions(),
447 | $this->database->getIsFile()
448 | );
449 | }
450 |
451 | if ($this->processQuery($query, $param) === false) {
452 | if ($this->isTransactional)
453 | throw new \PDOException($this->getLastError());
454 |
455 | return false;
456 | }
457 |
458 | // disk caching of queries
459 | $this->store_cache($query, $this->is_insert);
460 |
461 | // If debug ALL queries
462 | $this->trace || $this->debugAll ? $this->debug() : null;
463 |
464 | // Keep tack of how long all queries have taken
465 | $this->timer_update_global($this->numQueries);
466 |
467 | // Trace all queries
468 | if ($this->useTraceLog) {
469 | $this->traceLog[] = $this->debug(false);
470 | }
471 |
472 | return $this->return_val;
473 | } // query
474 |
475 | /**
476 | * Close the database connection
477 | */
478 | public function disconnect()
479 | {
480 | if ($this->dbh) {
481 | $this->dbh = null;
482 | $this->_connected = false;
483 | }
484 | }
485 |
486 | /**
487 | * Reset database handle
488 | */
489 | public function reset()
490 | {
491 | $this->dbh = null;
492 | }
493 |
494 | /**
495 | * Get connection handle
496 | */
497 | public function handle()
498 | {
499 | return $this->dbh;
500 | }
501 |
502 | /**
503 | * Begin PDO Transaction
504 | */
505 | public function beginTransaction()
506 | {
507 | $this->dbh->beginTransaction();
508 | $this->isTransactional = true;
509 | }
510 |
511 | public function commit()
512 | {
513 | $this->dbh->commit();
514 | $this->isTransactional = false;
515 | }
516 |
517 | public function rollback()
518 | {
519 | $this->dbh->rollback();
520 | $this->isTransactional = false;
521 | }
522 | } // ez_pdo
523 |
--------------------------------------------------------------------------------
/lib/Database/ez_pgsql.php:
--------------------------------------------------------------------------------
1 | database = $settings;
46 |
47 | if (!Db::has('ez' . \PGSQL))
48 | Db::set('ez' . \PGSQL, $this);
49 | Db::set('global', $this);
50 | } // __construct
51 |
52 | public function settings()
53 | {
54 | return $this->database;
55 | }
56 |
57 | /**
58 | * In the case of PostgreSQL quick_connect is not really needed because std.
59 | * connect already does what quick connect does - but for the sake of
60 | * consistency it has been included
61 | *
62 | * @param string $user The database user name
63 | * @param string $password The database users password
64 | * @param string $name The name of the database
65 | * @param string $host The host name or IP address of the database server.
66 | * Default is localhost
67 | * @param string $port The database TCP/IP port
68 | * Default is PostgreSQL default port 5432
69 | * @return boolean
70 | */
71 | public function quick_connect($user = '', $password = '', $name = '', $host = 'localhost', $port = '5432')
72 | {
73 | if (!$this->connect($user, $password, $name, $host, $port));
74 | return $this->_connected;
75 | } // quick_connect
76 |
77 | /**
78 | * Try to connect to PostgreSQL database server
79 | *
80 | * @param string $user The database user name
81 | * @param string $password The database users password
82 | * @param string $name The name of the database
83 | * @param string $host The host name or IP address of the database server.
84 | * Default is localhost
85 | * @param string $port The database TCP/IP port
86 | * Default is PostgreSQL default port 5432
87 | * @return boolean
88 | */
89 | public function connect(
90 | string $user = '',
91 | string $password = '',
92 | string $name = '',
93 | string $host = 'localhost',
94 | string $port = '5432'
95 | ) {
96 | $this->_connected = false;
97 |
98 | $user = empty($user) ? $this->database->getUser() : $user;
99 | $password = empty($password) ? $this->database->getPassword() : $password;
100 | $name = empty($name) ? $this->database->getName() : $name;
101 | $host = ($host != 'localhost') ? $host : $this->database->getHost();
102 | $port = ($port != '5432') ? $port : $this->database->getPort();
103 |
104 | $connect_string = "host=" . $host . " port=" . $port . " dbname=" . $name . " user=" . $user . " password=" . $password;
105 |
106 | // Try to establish the server database handle
107 | if (!$this->dbh = \pg_connect($connect_string, \PGSQL_CONNECT_FORCE_NEW)) {
108 | $this->register_error(\FAILED_CONNECTION . ' in ' . __FILE__ . ' on line ' . __LINE__);
109 | } else {
110 | $this->_connected = true;
111 | }
112 |
113 | return $this->_connected;
114 | } // connect
115 |
116 | /**
117 | * Format a mySQL string correctly for safe mySQL insert
118 | * (no matter if magic quotes are on or not)
119 | *
120 | * @param string $str
121 | * @return string
122 | */
123 | public function escape(string $str)
124 | {
125 | return \pg_escape_string(\stripslashes($str));
126 | } // escape
127 |
128 | /**
129 | * Return PostgreSQL specific system date syntax
130 | * i.e. Oracle: SYSDATE Mysql: NOW()
131 | *
132 | * @return string
133 | */
134 | public function sysDate()
135 | {
136 | return 'NOW()';
137 | }
138 |
139 | /**
140 | * Creates a prepared query, binds the given parameters and returns the result of the executed
141 | *
142 | * @param string $query
143 | * @param array $param
144 | * @return bool|mixed
145 | */
146 | public function query_prepared(string $query, array $param = null)
147 | {
148 | $result = @\pg_query_params($this->dbh, $query, $param);
149 | return ($this->shortcutUsed) ? $result : $this->processQueryResult($query, $result);
150 | }
151 |
152 | /**
153 | * Perform post processing on SQL query call
154 | *
155 | * @param string $query
156 | * @param mixed $result
157 | * @return bool|void
158 | */
159 | private function processQueryResult(string $query, $result = null)
160 | {
161 | $this->shortcutUsed = false;
162 |
163 | if (!empty($result))
164 | $this->result = $result;
165 |
166 | try {
167 | // If there is an error then take note of it..
168 | if ($str = @\pg_last_error($this->dbh)) {
169 | return $this->register_error($str);
170 | }
171 | } catch (\Throwable $ex) {
172 | return $this->register_error($ex->getMessage());
173 | }
174 |
175 | // Query was an insert, delete, update, replace
176 | $this->is_insert = false;
177 | if (\preg_match("/^(insert|delete|update|replace)\s+/i", $query)) {
178 | $this->is_insert = true;
179 |
180 | if (\is_bool($this->result))
181 | return false;
182 |
183 | $this->_affectedRows = @\pg_affected_rows($this->result);
184 |
185 | // Take note of the insert_id
186 | if (\preg_match("/^(insert|replace)\s+/i", $query)) {
187 | //$this->insert_id = @postgresql_insert_id($this->dbh);
188 | //$this->insert_id = pg_last_oid($this->result);
189 |
190 | // Thx. Rafael Bernal
191 | $insert_query = \pg_query("SELECT lastval();");
192 | $insert_row = \pg_fetch_row($insert_query);
193 | $this->insertId = $insert_row[0];
194 | }
195 |
196 | // Return number for rows affected
197 | $this->return_val = $this->_affectedRows;
198 |
199 | if (\preg_match("/returning/smi", $query)) {
200 | while ($row = @\pg_fetch_object($this->result)) {
201 | $return_affected[] = $row;
202 | }
203 | $this->return_val = $return_affected;
204 | }
205 | } else {
206 | // Query was a select
207 | $num_rows = 0;
208 | //may be needed but my tests did not
209 | if ($this->result) {
210 | // Take note of column info
211 | $i = 0;
212 | while ($i < @\pg_num_fields($this->result)) {
213 | $this->colInfo[$i] = new \stdClass();
214 | $this->colInfo[$i]->name = \pg_field_name($this->result, $i);
215 | $this->colInfo[$i]->type = \pg_field_type($this->result, $i);
216 | $this->colInfo[$i]->size = \pg_field_size($this->result, $i);
217 | $i++;
218 | }
219 |
220 | /**
221 | * Store Query Results
222 | * while ( $row = @pg_fetch_object($this->result, $i, PGSQL_ASSOC) ) doesn't work? donno
223 | * while ( $row = @pg_fetch_object($this->result,$num_rows) ) does work
224 | */
225 | while ($row = @\pg_fetch_object($this->result)) {
226 | // Store results as an objects within main array
227 | $this->lastResult[$num_rows] = $row;
228 | $num_rows++;
229 | }
230 |
231 | @\pg_free_result($this->result);
232 | }
233 | // Log number of rows the query returned
234 | $this->numRows = $num_rows;
235 |
236 | // Return number of rows selected
237 | $this->return_val = $this->numRows;
238 | }
239 | }
240 |
241 | /**
242 | * Perform PostgreSQL query and try to determine result value
243 | *
244 | * @param string
245 | * @param bool
246 | * @return bool|mixed
247 | */
248 | public function query(string $query, bool $use_prepare = false)
249 | {
250 | $param = [];
251 | if ($use_prepare) {
252 | $param = $this->prepareValues();
253 | }
254 |
255 | // check for ezQuery placeholder tag and replace tags with proper prepare tag
256 | if (!empty($param) && \is_array($param) && ($this->isPrepareOn()) && (\strpos($query, \_TAG) !== false)) {
257 | foreach ($param as $i => $value) {
258 | $parameterized = $i + 1;
259 | $needle = \_TAG;
260 | $pos = \strpos($query, $needle);
261 | if ($pos !== false) {
262 | $query = \substr_replace($query, '$' . $parameterized, $pos, \strlen($needle));
263 | }
264 | }
265 | }
266 |
267 | // Initialize return
268 | $this->return_val = 0;
269 |
270 | // Flush cached values..
271 | $this->flush();
272 |
273 | // For reg expressions
274 | $query = \trim($query);
275 |
276 | // Log how the function was called
277 | $this->log_query("\$db->query(\"$query\")");
278 |
279 | // Keep track of the last query for debug..
280 | $this->lastQuery = $query;
281 |
282 | // Count how many queries there have been
283 | $this->count(true, true);
284 |
285 | // Use core file cache function
286 | if ($cache = $this->get_cache($query)) {
287 | return $cache;
288 | }
289 |
290 | // If there is no existing database connection then try to connect
291 | if (!isset($this->dbh) || !$this->dbh) {
292 | $this->connect(
293 | $this->database->getUser(),
294 | $this->database->getPassword(),
295 | $this->database->getName(),
296 | $this->database->getHost(),
297 | $this->database->getPort()
298 | );
299 | }
300 |
301 | // Perform the query via std postgresql_query function..
302 | if (!empty($param) && \is_array($param) && ($this->isPrepareOn())) {
303 | $this->shortcutUsed = true;
304 | $this->result = $this->query_prepared($query, $param);
305 | } else {
306 | try {
307 | $this->result = @\pg_query($this->dbh, $query);
308 | } catch (\Throwable $ex) {
309 | //
310 | }
311 | }
312 |
313 | if ($this->processQueryResult($query) === false) {
314 | if ($this->isTransactional)
315 | throw new \Exception($this->getLastError());
316 |
317 | return false;
318 | }
319 |
320 | // disk caching of queries
321 | $this->store_cache($query, $this->is_insert);
322 |
323 | // If debug ALL queries
324 | $this->trace || $this->debugAll ? $this->debug() : null;
325 |
326 | return $this->return_val;
327 | } // query
328 |
329 | /**
330 | * Close the database connection
331 | */
332 | public function disconnect()
333 | {
334 | if ($this->dbh) {
335 | \pg_close($this->dbh);
336 | $this->_connected = false;
337 | }
338 | }
339 |
340 | /**
341 | * Reset database handle
342 | */
343 | public function reset()
344 | {
345 | $this->dbh = null;
346 | }
347 |
348 | /**
349 | * Get connection handle
350 | */
351 | public function handle()
352 | {
353 | return $this->dbh;
354 | }
355 |
356 | /**
357 | * Returns the current database server host
358 | *
359 | * @return string
360 | */
361 | public function getHost()
362 | {
363 | return $this->database->getHost();
364 | } // getDBHost
365 |
366 | /**
367 | * Returns the current TCP/IP port
368 | *
369 | * @return string
370 | */
371 | public function getPort()
372 | {
373 | return $this->database->getPort();
374 | } // getPort
375 |
376 | /**
377 | * Begin Postgresql Transaction
378 | */
379 | public function beginTransaction()
380 | {
381 | @\pg_query($this->dbh, "BEGIN");
382 | $this->isTransactional = true;
383 | }
384 |
385 | public function commit()
386 | {
387 | @\pg_query($this->dbh, "COMMIT");
388 | $this->isTransactional = false;
389 | }
390 |
391 | public function rollback()
392 | {
393 | @\pg_query($this->dbh, "ROLLBACK");
394 | $this->isTransactional = false;
395 | }
396 | } // ez_pgsql
397 |
--------------------------------------------------------------------------------
/lib/Database/ez_sqlite3.php:
--------------------------------------------------------------------------------
1 | database = $settings;
50 |
51 | // Turn on track errors
52 | ini_set('track_errors', '1');
53 |
54 | if (!Db::has('ez' . \SQLITE3))
55 | Db::set('ez' . \SQLITE3, $this);
56 | Db::set('global', $this);
57 | }
58 |
59 | public function settings()
60 | {
61 | return $this->database;
62 | }
63 |
64 | /**
65 | * Try to connect to SQLite database server
66 | */
67 | public function connect($path = '', $name = '')
68 | {
69 | $this->_connected = false;
70 |
71 | $path = empty($path) ? $this->database->getPath() : $path;
72 | $name = empty($name) ? $this->database->getName() : $name;
73 |
74 | // Try to establish the server database handle
75 | if (!$this->dbh = @new \SQLite3($path . $name)) {
76 | //$this->register_error(\FAILED_CONNECTION);
77 | //$this->show_errors ? \trigger_error(\FAILED_CONNECTION, \E_USER_WARNING) : null;
78 | } else {
79 | $this->connQueries = 0;
80 | $this->_connected = true;
81 | }
82 |
83 | return $this->_connected;
84 | }
85 |
86 | /**
87 | * In the case of SQLite quick_connect is not really needed
88 | * because std. connect already does what quick connect does -
89 | * but for the sake of consistency it has been included
90 | */
91 | public function quick_connect($path = '', $name = '')
92 | {
93 | return $this->connect($path, $name);
94 | }
95 |
96 | /**
97 | * Format a SQLite string correctly for safe SQLite insert
98 | * (no mater if magic quotes are on or not)
99 | * @param string $str
100 | * @return string
101 | */
102 | public function escape(string $str)
103 | {
104 | return $this->dbh->escapeString(\stripslashes(\preg_replace("/[\r\n]/", '', $str)));
105 | }
106 |
107 | /**
108 | * Return SQLite specific system date syntax
109 | * i.e. Oracle: SYSDATE Mysql: NOW()
110 | */
111 | public function sysDate()
112 | {
113 | return 'now';
114 | }
115 |
116 | // Get the data type of the value to bind.
117 | public function getArgType($arg)
118 | {
119 | switch (\gettype($arg)) {
120 | case 'double':
121 | return \SQLITE3_FLOAT;
122 | case 'integer':
123 | return \SQLITE3_INTEGER;
124 | case 'boolean':
125 | return \SQLITE3_INTEGER;
126 | case 'NULL':
127 | return \SQLITE3_NULL;
128 | case 'string':
129 | return \SQLITE3_TEXT;
130 | case 'string':
131 | return \SQLITE3_TEXT;
132 | default:
133 | $type_error = 'Argument is of invalid type ' . \gettype($arg);
134 | return $this->register_error($type_error);
135 | }
136 | }
137 |
138 | /**
139 | * Creates a prepared query, binds the given parameters and returns the result of the executed
140 | *
141 | * @param string $query
142 | * @param array $param
143 | * @return bool \SQLite3Result
144 | */
145 | public function query_prepared(string $query, array $param = null)
146 | {
147 | $stmt = $this->dbh->prepare($query);
148 | if (!$stmt instanceof \SQLite3Stmt) {
149 | if ($this->isTransactional)
150 | throw new \Exception($this->getLastError());
151 |
152 | return false;
153 | }
154 |
155 | foreach ($param as $index => $val) {
156 | // indexing start from 1 in Sqlite3 statement
157 | if (\is_array($val)) {
158 | $ok = $stmt->bindParam($index + 1, $val);
159 | } else {
160 | $ok = $stmt->bindValue($index + 1, $val, $this->getArgType($val));
161 | }
162 |
163 | if (!$ok) {
164 | $type_error = "Unable to bind param: $val";
165 | return $this->register_error($type_error);
166 | }
167 | }
168 |
169 | $result = $stmt->execute();
170 | if ($this->shortcutUsed)
171 | return $result;
172 |
173 | $this->processQueryResult($query, $result);
174 | if ((\strpos($query, 'SELECT ') !== false) || (\strpos($query, 'select ') !== false))
175 | $this->result->finalize();
176 |
177 | return $this->return_val;
178 | }
179 |
180 | /**
181 | * Perform post processing on SQL query call
182 | *
183 | * @param string $query
184 | * @param mixed $result
185 | * @param array $param
186 | * @return bool|void
187 | */
188 | private function processQueryResult(string $query, $result = null)
189 | {
190 | $this->shortcutUsed = false;
191 |
192 | if (!empty($result))
193 | $this->result = $result;
194 |
195 | $this->count(true, true);
196 |
197 | // If there is an error then take note of it..
198 | if (@$this->dbh->lastErrorCode()) {
199 | $err_str = $this->dbh->lastErrorMsg();
200 | return $this->register_error($err_str);
201 | }
202 |
203 | // Query was an insert, delete, update, replace
204 | if (\preg_match("/^(insert|delete|update|replace)\s+/i", $query)) {
205 | $this->_affectedRows = @$this->dbh->changes();
206 |
207 | // Take note of the insert id
208 | if (\preg_match("/^(insert|replace)\s+/i", $query)) {
209 | $this->insertId = @$this->dbh->lastInsertRowID();
210 | }
211 |
212 | // Return number of rows affected
213 | $this->return_val = $this->_affectedRows;
214 |
215 | // Query was an select
216 | } else {
217 | // Take note of column info
218 | $i = 0;
219 | $this->colInfo = array();
220 | while ($i < @$this->result->numColumns()) {
221 | $this->colInfo[$i] = new \stdClass;
222 | $this->colInfo[$i]->name = $this->result->columnName($i);
223 | $this->colInfo[$i]->type = null;
224 | $this->colInfo[$i]->max_length = null;
225 | $i++;
226 | }
227 |
228 | // Store Query Results
229 | $num_rows = 0;
230 | while ($row = @$this->result->fetchArray(\SQLITE3_ASSOC)) {
231 | // Store result as an objects within main array
232 | $obj = (object) $row; //convert to object
233 | $this->lastResult[$num_rows] = $obj;
234 | $num_rows++;
235 | }
236 |
237 | // Log number of rows the query returned
238 | $this->numRows = $num_rows;
239 |
240 | // Return number of rows selected
241 | $this->return_val = $this->numRows;
242 | }
243 | }
244 |
245 | /**
246 | * Perform SQLite query and try to determine result value
247 | * Basic Query - see docs for more detail
248 | * @param string
249 | * @param bool
250 | * @return bool|mixed
251 | */
252 | public function query(string $query, bool $use_prepare = false)
253 | {
254 | $param = [];
255 | if ($use_prepare) {
256 | $param = $this->prepareValues();
257 | }
258 |
259 | // check for ezQuery placeholder tag and replace tags with proper prepare tag
260 | $query = \str_replace(\_TAG, '?', $query);
261 |
262 | // For reg expressions
263 | $query = \str_replace("/[\n\r]/", '', \trim($query));
264 |
265 | // initialize return
266 | $this->return_val = 0;
267 |
268 | // Flush cached values..
269 | $this->flush();
270 |
271 | // Log how the function was called
272 | $this->log_query("\$db->query(\"$query\")");
273 |
274 | // Keep track of the last query for debug..
275 | $this->lastQuery = $query;
276 |
277 | // If there is no existing database connection then try to connect
278 | if (!isset($this->dbh) || !$this->dbh) {
279 | $this->connect($this->database->getPath(), $this->database->getName());
280 | }
281 |
282 | // Perform the query via std SQLite3 query or SQLite3 prepare function..
283 | if (!empty($param) && \is_array($param) && ($this->isPrepareOn())) {
284 | $this->shortcutUsed = true;
285 | $this->result = $this->query_prepared($query, $param);
286 | } else {
287 | $this->result = $this->dbh->query($query);
288 | }
289 |
290 | if ($this->processQueryResult($query) === false) {
291 | if ($this->isTransactional)
292 | throw new \Exception($this->getLastError());
293 |
294 | return false;
295 | }
296 |
297 | if (!empty($param) && \is_array($param) && $this->isPrepareOn())
298 | $this->result->finalize();
299 |
300 | // If debug ALL queries
301 | $this->trace || $this->debugAll ? $this->debug() : null;
302 |
303 | return $this->return_val;
304 | }
305 |
306 | /**
307 | * Close the database connection
308 | */
309 | public function disconnect()
310 | {
311 | if ($this->dbh) {
312 | $this->dbh = null;
313 | $this->_connected = false;
314 | }
315 | }
316 |
317 | /**
318 | * Reset database handle
319 | */
320 | public function reset()
321 | {
322 | $this->dbh = null;
323 | }
324 |
325 | /**
326 | * Get connection handle
327 | */
328 | public function handle()
329 | {
330 | return $this->dbh;
331 | }
332 |
333 | /**
334 | * Begin sqlite3 Transaction
335 | */
336 | public function beginTransaction()
337 | {
338 | $this->dbh->exec('BEGIN;');
339 | $this->isTransactional = true;
340 | }
341 |
342 | public function commit()
343 | {
344 | $this->dbh->exec('COMMIT;');
345 | $this->isTransactional = false;
346 | }
347 |
348 | public function rollback()
349 | {
350 | $this->dbh->exec('ROLLBACK;');
351 | $this->isTransactional = false;
352 | }
353 | }
354 |
--------------------------------------------------------------------------------
/lib/Database/ez_sqlsrv.php:
--------------------------------------------------------------------------------
1 | 'bigint', -7 => 'bit', 1 => 'char', 91 => 'date', -155 => 'datetimeoffset', 6 => 'float', -4 => 'image', 4 => 'int', -8 => 'nchar',
25 | -10 => 'ntext', 2 => 'numeric', -9 => 'nvarchar', 7 => 'real', 5 => 'smallint', -1 => 'text', -154 => 'time', -6 => 'tinyint', -151 => 'udt',
26 | -11 => 'uniqueidentifier', -3 => 'varbinary', 12 => 'varchar', -152 => 'xml',
27 | );
28 |
29 | /**
30 | * Database connection handle
31 | * @var resource
32 | */
33 | private $dbh;
34 |
35 | /**
36 | * Query result
37 | * @var mixed
38 | */
39 | private $result;
40 |
41 | /**
42 | * Database configuration setting
43 | * @var ConfigInterface
44 | */
45 | private $database;
46 |
47 | public function __construct(ConfigInterface $settings = null)
48 | {
49 | if (empty($settings)) {
50 | throw new Exception(\MISSING_CONFIGURATION);
51 | }
52 |
53 | parent::__construct();
54 | $this->database = $settings;
55 |
56 | if (!Db::has('ez' . \SQLSRV))
57 | Db::set('ez' . \SQLSRV, $this);
58 | Db::set('global', $this);
59 | }
60 |
61 | public function settings()
62 | {
63 | return $this->database;
64 | }
65 |
66 | /**
67 | * Short hand way to connect to sqlsrv database server
68 | * and select a sqlsrv database at the same time
69 | */
70 | public function quick_connect($user = '', $password = '', $name = '', $host = 'localhost')
71 | {
72 | $return_val = false;
73 | $this->_connected = false;
74 | if (!$this->connect($user, $password, $name, $host));
75 | else {
76 | $return_val = true;
77 | $this->_connected = true;
78 | }
79 | return $return_val;
80 | }
81 |
82 | /**
83 | * Try to connect to sqlsrv database server
84 | */
85 | public function connect($user = '', $password = '', $name = '', $host = 'localhost')
86 | {
87 | $this->_connected = false;
88 |
89 | $user = empty($user) ? $this->database->getUser() : $user;
90 | $password = empty($password) ? $this->database->getPassword() : $password;
91 | $name = empty($name) ? $this->database->getName() : $name;
92 | $host = ($host != 'localhost') ? $this->database->getHost() : $host;
93 |
94 | // Blank user assumes Windows Authentication
95 | if ($this->isSecure) {
96 | $connectionOptions = array(
97 | "UID" => $user,
98 | "PWD" => $password,
99 | "Database" => $name,
100 | "ReturnDatesAsStrings" => true,
101 | "Encrypt" => true,
102 | "TrustServerCertificate" => true,
103 | );
104 | } else {
105 | $connectionOptions = array(
106 | "UID" => $user,
107 | "PWD" => $password,
108 | "Database" => $name,
109 | "ReturnDatesAsStrings" => true,
110 | );
111 | }
112 |
113 | // Try to establish the server database handle
114 | if (($this->dbh = @\sqlsrv_connect($host, $connectionOptions)) === false) {
115 | $this->register_error(\FAILED_CONNECTION . ' in ' . __FILE__ . ' on line ' . __LINE__);
116 | } else {
117 | $this->_connected = true;
118 | $this->connQueries = 0;
119 | }
120 |
121 | return $this->_connected;
122 | }
123 |
124 | /**
125 | * Return sqlsrv specific system date syntax
126 | * i.e. Oracle: SYSDATE sqlsrv: NOW(), MS-SQL : getDate()
127 | *
128 | * The SQLSRV drivers pull back the data into a Date class. Converted
129 | * it to a string inside of SQL in order to prevent this from occurring
130 | * ** make sure to use " AS