pax_global_header00006660000000000000000000000064127037243040014514gustar00rootroot0000000000000052 comment=c9fa8fdab194093fff58e4f1180c7e15d80a2cb5 zend-db-release-2.8.1/000077500000000000000000000000001270372430400144655ustar00rootroot00000000000000zend-db-release-2.8.1/CHANGELOG.md000066400000000000000000000144011270372430400162760ustar00rootroot00000000000000# Changelog All notable changes to this project will be documented in this file, in reverse chronological order by release. ## 2.8.1 - 2016-04-14 ### Added - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [#100](https://github.com/zendframework/zend-db/pull/100) fixes the JOIN behavior to re-allow selecting an empty column set from the joined table. - [#106](https://github.com/zendframework/zend-db/pull/106) fixes an issue in the test suite when ext/pgsql is enabled, but no databases are avaiable. ## 2.8.0 - 2016-04-12 ### Added - [#92](https://github.com/zendframework/zend-db/pull/92) adds the class `Zend\Db\Sql\Join` for creating and aggregating JOIN specifications. This is now consumed by all `Zend\Db\Sql` implementations in order to represent JOIN statements. - [#92](https://github.com/zendframework/zend-db/pull/92) adds support for JOIN operations to UPDATE statements. - [#92](https://github.com/zendframework/zend-db/pull/92) adds support for joins to `AbstractTableGateway::update`; you can now pass an array of specifications via a third argument to the method. - [#96](https://github.com/zendframework/zend-db/pull/96) exposes the package as config-provider/component, but adding: - `Zend\Db\ConfigProvider`, which maps the `AdapterInterface` to the `AdapterServiceFactory`, and enables the `AdapterAbstractServiceFactory`. - `Zend\Db\Module`, which does the same, for a zend-mvc context. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - Nothing. ## 2.7.1 - 2016-04-12 ### Added - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [#71](https://github.com/zendframework/zend-db/pull/71) updates the `Pgsql` adapter to allow passing the connection charset; this can be done with the `charset` option when creating your adapter. - [#76](https://github.com/zendframework/zend-db/pull/76) fixes the behavior of `Zend\Db\Sql\Insert` when an array of names is used for columns to ensure the string names are used, and not the array indices. - [#91](https://github.com/zendframework/zend-db/pull/91) fixes the behavior of the `Oci8` adapter when initializing a result set; previously, it was improperly assigning the count of affected rows to the generated value. - [#95](https://github.com/zendframework/zend-db/pull/95) fixes the `IbmDb2` platform's `quoteIdentifier()` method to properly allow `#` characters in identifiers (as they are commonly used on that platform). ## 2.7.0 - 2016-02-22 ### Added - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [#85](https://github.com/zendframework/zend-db/pull/85) and [#87](https://github.com/zendframework/zend-db/pull/87) update the code base to be forwards compatible with: - zend-eventmanager v3 - zend-hydrator v2.1 - zend-servicemanager v3 - zend-stdlib v3 ## 2.6.2 - 2015-12-09 ### Added - [#49](https://github.com/zendframework/zend-db/pull/49) Add docbook documentation. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [#55](https://github.com/zendframework/zend-db/pull/55) Implement FeatureSet canCallMagicCall and callMagicCall methods - [#56](https://github.com/zendframework/zend-db/pull/56) AbstractResultSet::current now does validation to ensure an array. - [#58](https://github.com/zendframework/zend-db/pull/58) Fix unbuffered result on MySQLi. - [#59](https://github.com/zendframework/zend-db/pull/59) Allow unix_socket parameter ## 2.6.1 - 2015-10-14 ### Added - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [#31](https://github.com/zendframework/zend-db/pull/31) fixes table gateway update when there is a table alias utilized. ## 2.6.1 - 2015-10-14 ### Added - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - [#43](https://github.com/zendframework/zend-db/pull/43) unset and get during an insert operation would throw an InvalidArgumentException during an insert. ## 2.6.0 - 2015-09-22 ### Added - [#42](https://github.com/zendframework/zend-db/pull/42) updates the component to use zend-hydrator for hydrator functionality; this provides forward compatibility with zend-hydrator, and backwards compatibility with hydrators from older versions of zend-stdlib. - [#15](https://github.com/zendframework/zend-db/pull/15) adds a new predicate, `Zend\Db\Sql\Predicate\NotBetween`, which can be invoked via `Sql` instances: `$sql->notBetween($field, $min, $max)`. - [#22](https://github.com/zendframework/zend-db/pull/22) extracts a factory, `Zend\Db\Metadata\Source\Factory`, from `Zend\Db\Metadata\Metadata`, removing the (non-public) `createSourceFromAdapter()` method from that class. Additionally, it extracts `Zend\Db\Metadata\MetadataInterface`, to allow creating alternate implementations. ### Deprecated - [#27](https://github.com/zendframework/zend-db/pull/27) deprecates the constants `JOIN_OUTER_LEFT` and `JOIN_OUTER_RIGHT` in favor of `JOIN_LEFT_OUTER` and `JOIN_RIGHT_OUTER`. ### Removed - Nothing. ### Fixed - Nothing. ## 2.5.2 - 2015-09-22 ### Added - Nothing. ### Deprecated - Nothing. ### Removed - [#29](https://github.com/zendframework/zend-db/pull/29) removes the required second argument to `Zend\Db\Predicate\Predicate::expression()`, allowing it to be nullable, and mirroring the constructor of `Zend\Db\Predicate\Expression`. ### Fixed - [#40](https://github.com/zendframework/zend-db/pull/40) updates the zend-stdlib dependency to reference `>=2.5.0,<2.7.0` to ensure hydrators will work as expected following extraction of hydrators to the zend-hydrator repository. - [#34](https://github.com/zendframework/zend-db/pull/34) fixes retrieval of constraint metadata in the Oracle adapter. - [#41](https://github.com/zendframework/zend-db/pull/41) removes hard dependency on EventManager in AbstractTableGateway. - [#17](https://github.com/zendframework/zend-db/pull/17) removes an executable bit on a regular file. - [#3](https://github.com/zendframework/zend-db/pull/3) updates the code to use closure binding (now that we're on 5.5+, this is possible). - [#9](https://github.com/zendframework/zend-db/pull/9) thoroughly audits the OCI8 (Oracle) driver, ensuring it provides feature parity with other drivers, and fixes issues with subselects, limits, and offsets. zend-db-release-2.8.1/CONDUCT.md000066400000000000000000000045121270372430400161100ustar00rootroot00000000000000# Contributor Code of Conduct The Zend Framework project adheres to [The Code Manifesto](http://codemanifesto.com) as its guidelines for contributor interactions. ## The Code Manifesto We want to work in an ecosystem that empowers developers to reach their potential — one that encourages growth and effective collaboration. A space that is safe for all. A space such as this benefits everyone that participates in it. It encourages new developers to enter our field. It is through discussion and collaboration that we grow, and through growth that we improve. In the effort to create such a place, we hold to these values: 1. **Discrimination limits us.** This includes discrimination on the basis of race, gender, sexual orientation, gender identity, age, nationality, technology and any other arbitrary exclusion of a group of people. 2. **Boundaries honor us.** Your comfort levels are not everyone’s comfort levels. Remember that, and if brought to your attention, heed it. 3. **We are our biggest assets.** None of us were born masters of our trade. Each of us has been helped along the way. Return that favor, when and where you can. 4. **We are resources for the future.** As an extension of #3, share what you know. Make yourself a resource to help those that come after you. 5. **Respect defines us.** Treat others as you wish to be treated. Make your discussions, criticisms and debates from a position of respectfulness. Ask yourself, is it true? Is it necessary? Is it constructive? Anything less is unacceptable. 6. **Reactions require grace.** Angry responses are valid, but abusive language and vindictive actions are toxic. When something happens that offends you, handle it assertively, but be respectful. Escalate reasonably, and try to allow the offender an opportunity to explain themselves, and possibly correct the issue. 7. **Opinions are just that: opinions.** Each and every one of us, due to our background and upbringing, have varying opinions. The fact of the matter, is that is perfectly acceptable. Remember this: if you respect your own opinions, you should respect the opinions of others. 8. **To err is human.** You might not intend it, but mistakes do happen and contribute to build experience. Tolerate honest mistakes, and don't hesitate to apologize if you make one yourself. zend-db-release-2.8.1/CONTRIBUTING.md000066400000000000000000000222611270372430400167210ustar00rootroot00000000000000# CONTRIBUTING ## RESOURCES If you wish to contribute to Zend Framework, please be sure to read/subscribe to the following resources: - [Coding Standards](https://github.com/zendframework/zf2/wiki/Coding-Standards) - [Contributor's Guide](http://framework.zend.com/participate/contributor-guide) - ZF Contributor's mailing list: Archives: http://zend-framework-community.634137.n4.nabble.com/ZF-Contributor-f680267.html Subscribe: zf-contributors-subscribe@lists.zend.com - ZF Contributor's IRC channel: #zftalk.dev on Freenode.net If you are working on new features or refactoring [create a proposal](https://github.com/zendframework/zend-db/issues/new). ## Reporting Potential Security Issues If you have encountered a potential security vulnerability, please **DO NOT** report it on the public issue tracker: send it to us at [zf-security@zend.com](mailto:zf-security@zend.com) instead. We will work with you to verify the vulnerability and patch it as soon as possible. When reporting issues, please provide the following information: - Component(s) affected - A description indicating how to reproduce the issue - A summary of the security vulnerability and impact We request that you contact us via the email address above and give the project contributors a chance to resolve the vulnerability and issue a new release prior to any public exposure; this helps protect users and provides them with a chance to upgrade and/or update in order to protect their applications. For sensitive email communications, please use [our PGP key](http://framework.zend.com/zf-security-pgp-key.asc). ## RUNNING TESTS > ### Note: testing versions prior to 2.4 > > This component originates with Zend Framework 2. During the lifetime of ZF2, > testing infrastructure migrated from PHPUnit 3 to PHPUnit 4. In most cases, no > changes were necessary. However, due to the migration, tests may not run on > versions < 2.4. As such, you may need to change the PHPUnit dependency if > attempting a fix on such a version. To run tests: - Clone the repository: ```console $ git clone git@github.com:zendframework/zend-db.git $ cd ``` - Install dependencies via composer: ```console $ curl -sS https://getcomposer.org/installer | php -- $ ./composer.phar install ``` If you don't have `curl` installed, you can also download `composer.phar` from https://getcomposer.org/ - Run the tests via `phpunit` and the provided PHPUnit config, like in this example: ```console $ ./vendor/bin/phpunit ``` You can turn on conditional tests with the phpunit.xml file. To do so: - Copy `phpunit.xml.dist` file to `phpunit.xml` - Edit `phpunit.xml` to enable any specific functionality you want to test, as well as to provide test values to utilize. ### Execute tests against real database servers This projects provides a [Vagrant](https://www.vagrantup.com/) virtual machine definition with a MySQL and PostgreSQL servers installed and configured. For to execute the tests against this server do the following steps (assume you have Vagrant > 1.6 installed) 1. Run the virtual machine: `vagrant up` 2. Copy `phpunit.xml.dist` file to `phpunit.xml`. 3. Enable online tests by setting the following config options: * `TESTS_ZEND_DB_ADAPTER_DRIVER_MYSQL_HOSTNAME` value to `localhost` * `TESTS_ZEND_DB_ADAPTER_DRIVER_PGSQL_HOSTNAME` value to `localhost` 4. Run `./vendor/bin/phpunit`. When done, you can halt the test servers using `vagrant halt`. > ### Alternate ports > > Pay attention to the output from your `vagrant up` command. If you have MySQL or PostgreSQL > running locally, Vagrant will detect that the port is in use, and forward an alternate port to the > virtual machine's database server(s). You'll likely see output like the following: > > ``` > ==> default: Forwarding ports... > default: 3306 => 2200 (adapter 1) > default: 5432 => 5432 (adapter 1) > default: 22 => 2222 (adapter 1) > ``` > > In the above example, local port 2200 is forwarded to guest 3306; in other words, for testing > MySQL, port 2200 should be used. > > To specify the alternate port, append it to the hostname, separated by a colon: `localhost:2200`. > ### Alternate testing approach > > The PHPUnit config file defines environment variables, which allows users on unix-like systems to > simplify steps 2-4 to: > > ```console > $ TESTS_ZEND_DB_ADAPTER_DRIVER_MYSQL_HOSTNAME=localhost \ > > TESTS_ZEND_DB_ADAPTER_DRIVER_PGSQL_HOSTNAME=localhost \ > > ./vendor/bin/phpunit > ``` ## Running Coding Standards Checks This component uses [php-cs-fixer](http://cs.sensiolabs.org/) for coding standards checks, and provides configuration for our selected checks. `php-cs-fixer` is installed by default via Composer. To run checks only: ```console $ ./vendor/bin/php-cs-fixer fix . -v --diff --dry-run --config-file=.php_cs ``` To have `php-cs-fixer` attempt to fix problems for you, omit the `--dry-run` flag: ```console $ ./vendor/bin/php-cs-fixer fix . -v --diff --config-file=.php_cs ``` If you allow php-cs-fixer to fix CS issues, please re-run the tests to ensure they pass, and make sure you add and commit the changes after verification. ## Recommended Workflow for Contributions Your first step is to establish a public repository from which we can pull your work into the master repository. We recommend using [GitHub](https://github.com), as that is where the component is already hosted. 1. Setup a [GitHub account](http://github.com/), if you haven't yet 2. Fork the repository (http://github.com/zendframework/zend-db) 3. Clone the canonical repository locally and enter it. ```console $ git clone git://github.com:zendframework/zend-db.git $ cd zend-db ``` 4. Add a remote to your fork; substitute your GitHub username in the command below. ```console $ git remote add {username} git@github.com:{username}/zend-db.git $ git fetch {username} ``` ### Keeping Up-to-Date Periodically, you should update your fork or personal repository to match the canonical ZF repository. Assuming you have setup your local repository per the instructions above, you can do the following: ```console $ git checkout master $ git fetch origin $ git rebase origin/master # OPTIONALLY, to keep your remote up-to-date - $ git push {username} master:master ``` If you're tracking other branches -- for example, the "develop" branch, where new feature development occurs -- you'll want to do the same operations for that branch; simply substitute "develop" for "master". ### Working on a patch We recommend you do each new feature or bugfix in a new branch. This simplifies the task of code review as well as the task of merging your changes into the canonical repository. A typical workflow will then consist of the following: 1. Create a new local branch based off either your master or develop branch. 2. Switch to your new local branch. (This step can be combined with the previous step with the use of `git checkout -b`.) 3. Do some work, commit, repeat as necessary. 4. Push the local branch to your remote repository. 5. Send a pull request. The mechanics of this process are actually quite trivial. Below, we will create a branch for fixing an issue in the tracker. ```console $ git checkout -b hotfix/9295 Switched to a new branch 'hotfix/9295' ``` ... do some work ... ```console $ git commit ``` ... write your log message ... ```console $ git push {username} hotfix/9295:hotfix/9295 Counting objects: 38, done. Delta compression using up to 2 threads. Compression objects: 100% (18/18), done. Writing objects: 100% (20/20), 8.19KiB, done. Total 20 (delta 12), reused 0 (delta 0) To ssh://git@github.com/{username}/zend-db.git b5583aa..4f51698 HEAD -> master ``` To send a pull request, you have two options. If using GitHub, you can do the pull request from there. Navigate to your repository, select the branch you just created, and then select the "Pull Request" button in the upper right. Select the user/organization "zendframework" as the recipient. If using your own repository - or even if using GitHub - you can use `git format-patch` to create a patchset for us to apply; in fact, this is **recommended** for security-related patches. If you use `format-patch`, please send the patches as attachments to: - zf-devteam@zend.com for patches without security implications - zf-security@zend.com for security patches #### What branch to issue the pull request against? Which branch should you issue a pull request against? - For fixes against the stable release, issue the pull request against the "master" branch. - For new features, or fixes that introduce new elements to the public API (such as new public methods or properties), issue the pull request against the "develop" branch. ### Branch Cleanup As you might imagine, if you are a frequent contributor, you'll start to get a ton of branches both locally and on your remote. Once you know that your changes have been accepted to the master repository, we suggest doing some cleanup of these branches. - Local branch cleanup ```console $ git branch -d ``` - Remote branch removal ```console $ git push {username} : ``` ## Conduct Please see our [CONDUCT.md](CONDUCT.md) to understand expected behavior when interacting with others in the project. zend-db-release-2.8.1/LICENSE.md000066400000000000000000000027551270372430400161020ustar00rootroot00000000000000Copyright (c) 2005-2016, Zend Technologies USA, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Zend Technologies USA, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. zend-db-release-2.8.1/README.md000066400000000000000000000013351270372430400157460ustar00rootroot00000000000000# zend-db [![Build Status](https://secure.travis-ci.org/zendframework/zend-db.svg?branch=master)](https://secure.travis-ci.org/zendframework/zend-db) [![Coverage Status](https://coveralls.io/repos/zendframework/zend-db/badge.svg?branch=master)](https://coveralls.io/r/zendframework/zend-db?branch=master) `Zend\Db` is a component that abstract the access to a Database using an object oriented API to build the queries. `Zend\Db` consumes different storage adapters to access different database vendors such as MySQL, PostgreSQL, Oracle, IBM DB2, Microsoft Sql Server, PDO, etc. - File issues at https://github.com/zendframework/zend-db/issues - Documentation is at http://framework.zend.com/manual/current/en/index.html#zend-db zend-db-release-2.8.1/composer.json000066400000000000000000000025301270372430400172070ustar00rootroot00000000000000{ "name": "zendframework/zend-db", "description": " ", "license": "BSD-3-Clause", "keywords": [ "zf2", "db" ], "homepage": "https://github.com/zendframework/zend-db", "autoload": { "psr-4": { "Zend\\Db\\": "src/" } }, "require": { "php": "^5.5 || ^7.0", "zendframework/zend-stdlib": "^2.7 || ^3.0" }, "require-dev": { "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", "zendframework/zend-hydrator": "^1.1 || ^2.1", "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", "fabpot/php-cs-fixer": "1.7.*", "phpunit/PHPUnit": "~4.0" }, "suggest": { "zendframework/zend-eventmanager": "Zend\\EventManager component", "zendframework/zend-hydrator": "Zend\\Hydrator component for using HydratingResultSets", "zendframework/zend-servicemanager": "Zend\\ServiceManager component" }, "minimum-stability": "dev", "prefer-stable": true, "extra": { "branch-alias": { "dev-master": "2.8-dev", "dev-develop": "2.9-dev" }, "zf": { "component": "Zend\\Db", "config-provider": "Zend\\Db\\ConfigProvider" } }, "autoload-dev": { "psr-4": { "ZendTest\\Db\\": "test/" } } } zend-db-release-2.8.1/doc/000077500000000000000000000000001270372430400152325ustar00rootroot00000000000000zend-db-release-2.8.1/doc/book/000077500000000000000000000000001270372430400161645ustar00rootroot00000000000000zend-db-release-2.8.1/doc/book/zend.db.adapter.md000066400000000000000000000361721270372430400214620ustar00rootroot00000000000000# Zend\\Db\\Adapter The Adapter object is the most important sub-component of `Zend\Db`. It is responsible for adapting any code written in or for Zend\\Db to the targeted php extensions and vendor databases. In doing this, it creates an abstraction layer for the PHP extensions, which is called the "Driver" portion of the `Zend\Db` adapter. It also creates a lightweight abstraction layer, called the "Platform" portion of the adapter, for the various idiosyncrasies that each vendor-specific platform might have in its SQL/RDBMS implementation. ## Creating an Adapter - Quickstart Creating an adapter can simply be done by instantiating the `Zend\Db\Adapter\Adapter` class. The most common use case, while not the most explicit, is to pass an array of configuration to the `Adapter`. ```php $adapter = new Zend\Db\Adapter\Adapter($configArray); ``` This driver array is an abstraction for the extension level required parameters. Here is a table for the key-value pairs that should be in configuration array. Key | Is Required? | Value -----------|------------------------|------ `driver` | required | `Mysqli`, `Sqlsrv`, `Pdo_Sqlite`, `Pdo_Mysql`, `Pdo`(= Other PDO Driver) `database` | generally required | the name of the database (schema) `username` | generally required | the connection username `password` | generally required | the connection password `hostname` | not generally required | the IP address or hostname to connect to `port` | not generally required | the port to connect to (if applicable) `charset` | not generally required | the character set to use > ### Options are adapter-dependent > > Other names will work as well. Effectively, if the PHP manual uses a > particular naming, this naming will be supported by our Driver. For example, > dbname in most cases will also work for 'database'. Another example is that > in the case of Sqlsrv, UID will work in place of username. Which format you > choose is up to you, but the above table represents the official abstraction > names. So, for example, a MySQL connection using ext/mysqli: ```php $adapter = new Zend\Db\Adapter\Adapter([ 'driver' => 'Mysqli', 'database' => 'zend_db_example', 'username' => 'developer', 'password' => 'developer-password', ]); ``` Another example, of a Sqlite connection via PDO: ```php $adapter = new Zend\Db\Adapter\Adapter([ 'driver' => 'Pdo_Sqlite', 'database' => 'path/to/sqlite.db', ]); ``` It is important to know that by using this style of adapter creation, the `Adapter` will attempt to create any dependencies that were not explicitly provided. A Driver object will be created from the configuration array provided in the constructor. A Platform object will be created based off the type of Driver class that was instantiated. And lastly, a default ResultSet object is created and utilized. Any of these objects can be injected, to do this, see the next section. The list of officially supported drivers: * `Mysqli`: The ext/mysqli driver * `Pgsql`: The ext/pgsql driver * `Sqlsrv`: The ext/sqlsrv driver (from Microsoft) * `Pdo_Mysql`: MySQL through the PDO extension * `Pdo_Sqlite`: SQLite though the PDO extension * `Pdo_Pgsql`: PostgreSQL through the PDO extension ## Creating an Adapter Using Dependency Injection The more expressive and explicit way of creating an adapter is by injecting all your dependencies up front. `Zend\Db\Adapter\Adapter` uses constructor injection, and all required dependencies are injected through the constructor, which has the following signature (in pseudo-code): ```php use Zend\Db\Adapter\Platform\PlatformInterface; use Zend\Db\ResultSet\ResultSet; class Zend\Db\Adapter\Adapter { public function __construct( $driver, PlatformInterface $platform = null, ResultSet $queryResultSetPrototype = null ) } ``` What can be injected: - $driver - an array of connection parameters (see above) or an instance of `Zend\Db\Adapter\Driver\DriverInterface` - $platform - (optional) an instance of `Zend\Db\Platform\PlatformInterface`, the default will be created based off the driver implementation - $queryResultSetPrototype - (optional) an instance of `Zend\Db\ResultSet\ResultSet`, to understand this object's role, see the section below on querying through the adapter ## Query Preparation Through Zend\\Db\\Adapter\\Adapter::query() By default, query() prefers that you use "preparation" as a means for processing SQL statements. This generally means that you will supply a SQL statement with the values substituted by placeholders, and then the parameters for those placeholders are supplied separately. An example of this workflow with `Zend\Db\Adapter\Adapter` is: ```php $adapter->query('SELECT * FROM `artist` WHERE `id` = ?', [5]); ``` The above example will go through the following steps: - create a new Statement object - prepare an array into a ParameterContainer if necessary - inject the ParameterContainer into the Statement object - execute the Statement object, producing a Result object - check the Result object to check if the supplied sql was a "query", or a result set producing statement - if it is a result set producing query, clone the ResultSet prototype, inject Result as datasource, return it - else, return the Result ## Query Execution Through Zend\\Db\\Adapter\\Adapter::query() In some cases, you have to execute statements directly. The primary purpose for needing to execute sql instead of prepare and execute a sql statement, might be because you are attempting to execute a DDL statement (which in most extensions and vendor platforms), are un-preparable. An example of executing: ```php $adapter->query( 'ALTER TABLE ADD INDEX(`foo_index`) ON (`foo_column`)', Adapter::QUERY_MODE_EXECUTE ); ``` The primary difference to notice is that you must provide the Adapter::QUERY\_MODE\_EXECUTE (execute) as the second parameter. ## Creating Statements While query() is highly useful for one-off and quick querying of a database through Adapter, it generally makes more sense to create a statement and interact with it directly, so that you have greater control over the prepare-then-execute workflow. To do this, Adapter gives you a routine called createStatement() that allows you to create a Driver specific Statement to use so you can manage your own prepare-then-execute workflow. ```php // with optional parameters to bind up-front $statement = $adapter->createStatement($sql, $optionalParameters); $result = $statement->execute(); ``` ## Using the Driver Object The Driver object is the primary place where `Zend\Db\Adapter\Adapter` implements the connection level abstraction making it possible to use all of ZendDb's interfaces via the various ext/mysqli, ext/sqlsrv, PDO, and other PHP level drivers. To make this possible, each driver is composed of 3 objects: * A connection: `Zend\Db\Adapter\Driver\ConnectionInterface` * A statement: `Zend\Db\Adapter\Driver\StatementInterface` * A result: `Zend\Db\Adapter\Driver\ResultInterface` Each of the built-in drivers practices "prototyping" as a means of creating objects when new instances are requested. The workflow looks like this: * An adapter is created with a set of connection parameters * The adapter chooses the proper driver to instantiate, for example `Zend\Db\Adapter\Driver\Mysqli` * That driver class is instantiated * If no connection, statement or result objects are injected, defaults are instantiated This driver is now ready to be called on when particular workflows are requested. Here is what the Driver API looks like: ```php namespace Zend\Db\Adapter\Driver; interface DriverInterface { const PARAMETERIZATION_POSITIONAL = 'positional'; const PARAMETERIZATION_NAMED = 'named'; const NAME_FORMAT_CAMELCASE = 'camelCase'; const NAME_FORMAT_NATURAL = 'natural'; public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE); public function checkEnvironment(); public function getConnection(); public function createStatement($sqlOrResource = null); public function createResult($resource); public function getPrepareType(); public function formatParameterName($name, $type = null); public function getLastGeneratedValue(); } ``` From this DriverInterface, you can - Determine the name of the platform this driver supports (useful for choosing the proper platform object) - Check that the environment can support this driver - Return the Connection object - Create a Statement object which is optionally seeded by an SQL statement (this will generally be a clone of a prototypical statement object) - Create a Result object which is optionally seeded by a statement resource (this will generally be a clone of a prototypical result object) - Format parameter names, important to distinguish the difference between the various ways parameters are named between extensions - Retrieve the overall last generated value (such as an auto-increment value) Statement objects generally look like this: ```php namespace Zend\Db\Adapter\Driver; interface StatementInterface extends StatementContainerInterface { public function getResource(); public function prepare($sql = null); public function isPrepared(); public function execute($parameters = null); /** Inherited from StatementContainerInterface */ public function setSql($sql); public function getSql(); public function setParameterContainer(ParameterContainer $parameterContainer); public function getParameterContainer(); } ``` Result objects generally look like this: ```php namespace Zend\Db\Adapter\Driver; use Countable; use Iterator; interface ResultInterface extends Countable, Iterator { public function buffer(); public function isQueryResult(); public function getAffectedRows(); public function getGeneratedValue(); public function getResource(); public function getFieldCount(); } ``` ## Using The Platform Object The Platform object provides an API to assist in crafting queries in a way that is specific to the SQL implementation of a particular vendor. Nuances such as how identifiers or values are quoted, or what the identifier separator character is are handled by this object. To get an idea of the capabilities, the interface for a platform object looks like this: ```php namespace Zend\Db\Adapter\Platform; interface PlatformInterface { public function getName(); public function getQuoteIdentifierSymbol(); public function quoteIdentifier($identifier); public function quoteIdentifierChain($identiferChain) public function getQuoteValueSymbol(); public function quoteValue($value); public function quoteValueList($valueList); public function getIdentifierSeparator(); public function quoteIdentifierInFragment($identifier, array $additionalSafeWords = []); } ``` While one can instantiate your own Platform object, generally speaking, it is easier to get the proper Platform instance from the configured adapter (by default the Platform type will match the underlying driver implementation): ```php $platform = $adapter->getPlatform(); // or $platform = $adapter->platform; // magic property access ``` The following is a couple of example of Platform usage: ```php /** @var $adapter Zend\Db\Adapter\Adapter */ /** @var $platform Zend\Db\Adapter\Platform\Sql92 */ $platform = $adapter->getPlatform(); // "first_name" echo $platform->quoteIdentifier('first_name'); // " echo $platform->getQuoteIdentifierSymbol(); // "schema"."mytable" echo $platform->quoteIdentifierChain(['schema', 'mytable']); // ' echo $platform->getQuoteValueSymbol(); // 'myvalue' echo $platform->quoteValue('myvalue'); // 'value', 'Foo O\\'Bar' echo $platform->quoteValueList(['value', "Foo O'Bar"]); // . echo $platform->getIdentifierSeparator(); // "foo" as "bar" echo $platform->quoteIdentifierInFragment('foo as bar'); // additionally, with some safe words: // ("foo"."bar" = "boo"."baz") echo $platform->quoteIdentifierInFragment('(foo.bar = boo.baz)', ['(', ')', '=']); ``` ## Using The Parameter Container The ParameterContainer object is a container for the various parameters that need to be passed into a Statement object to fulfill all the various parameterized parts of the SQL statement. This object implements the ArrayAccess interface. Below is the ParameterContainer API: ```php namespace Zend\Db\Adapter; use ArrayAccess; use Countable; use Iterator; class ParameterContainer implements Iterator, ArrayAccess, Countable { public function __construct(array $data = []) /** methods to interact with values */ public function offsetExists($name) public function offsetGet($name) public function offsetSetReference($name, $from) public function offsetSet($name, $value, $errata = null) public function offsetUnset($name) /** set values from array (will reset first) */ public function setFromArray(Array $data) /** methods to interact with value errata */ public function offsetSetErrata($name, $errata) public function offsetGetErrata($name) public function offsetHasErrata($name) public function offsetUnsetErrata($name) /** errata only iterator */ public function getErrataIterator() /** get array with named keys */ public function getNamedArray() /** get array with int keys, ordered by position */ public function getPositionalArray() /** iterator: */ public function count() public function current() public function next() public function key() public function valid() public function rewind() /** merge existing array of parameters with existing parameters */ public function merge($parameters) } ``` In addition to handling parameter names and values, the container will assist in tracking parameter types for PHP type to SQL type handling. For example, it might be important that: ```php $container->offsetSet('limit', 5); ``` be bound as an integer. To achieve this, pass in the ParameterContainer::TYPE\_INTEGER constant as the 3rd parameter: ```php $container->offsetSet('limit', 5, $container::TYPE_INTEGER); ``` This will ensure that if the underlying driver supports typing of bound parameters, that this translated information will also be passed along to the actual php database driver. ## Examples Creating a Driver and Vendor portable Query, Preparing and Iterating Result ```php $adapter = new Zend\Db\Adapter\Adapter($driverConfig); $qi = function ($name) use ($adapter) { return $adapter->platform->quoteIdentifier($name); }; $fp = function ($name) use ($adapter) { return $adapter->driver->formatParameterName($name); }; $sql = 'UPDATE ' . $qi('artist') . ' SET ' . $qi('name') . ' = ' . $fp('name') . ' WHERE ' . $qi('id') . ' = ' . $fp('id'); /** @var $statement Zend\Db\Adapter\Driver\StatementInterface */ $statement = $adapter->query($sql); $parameters = [ 'name' => 'Updated Artist', 'id' => 1, ]; $statement->execute($parameters); // DATA INSERTED, NOW CHECK /** @var $statement Zend\Db\Adapter\DriverStatementInterface */ $statement = $adapter->query('SELECT * FROM ' . $qi('artist') . ' WHERE id = ' . $fp('id')); /** @var $results Zend\Db\ResultSet\ResultSet */ $results = $statement->execute(['id' => 1]); $row = $results->current(); $name = $row['name']; ``` zend-db-release-2.8.1/doc/book/zend.db.metadata.md000066400000000000000000000201021270372430400216040ustar00rootroot00000000000000# Zend\\Db\\Metadata `Zend\Db\Metadata` is as sub-component of Zend\\Db that makes it possible to get metadata information about tables, columns, constraints, triggers, and other information from a database in a standardized way. The primary interface for the Metadata objects is: ```php interface MetadataInterface { public function getSchemas(); public function getTableNames($schema = null, $includeViews = false); public function getTables($schema = null, $includeViews = false); public function getTable($tableName, $schema = null); public function getViewNames($schema = null); public function getViews($schema = null); public function getView($viewName, $schema = null); public function getColumnNames($table, $schema = null); public function getColumns($table, $schema = null); public function getColumn($columnName, $table, $schema = null); public function getConstraints($table, $schema = null); public function getConstraint($constraintName, $table, $schema = null); public function getConstraintKeys($constraint, $table, $schema = null); public function getTriggerNames($schema = null); public function getTriggers($schema = null); public function getTrigger($triggerName, $schema = null); } ``` ## Basic Usage Usage of `Zend\Db\Metadata` is very straight forward. The top level class Zend\\Db\\Metadata\\Metadata will, given an adapter, choose the best strategy (based on the database platform being used) for retrieving metadata. In most cases, information will come from querying the INFORMATION\_SCHEMA tables generally accessible to all database connections about the currently accessible schema. Metadata::get\*Names() methods will return an array of strings, while the other methods will return specific value objects with the containing information. This is best demonstrated by the script below. ```php $metadata = new Zend\Db\Metadata\Metadata($adapter); // get the table names $tableNames = $metadata->getTableNames(); foreach ($tableNames as $tableName) { echo 'In Table ' . $tableName . PHP_EOL; $table = $metadata->getTable($tableName); echo ' With columns: ' . PHP_EOL; foreach ($table->getColumns() as $column) { echo ' ' . $column->getName() . ' -> ' . $column->getDataType() . PHP_EOL; } echo PHP_EOL; echo ' With constraints: ' . PHP_EOL; foreach ($metadata->getConstraints($tableName) as $constraint) { /** @var $constraint Zend\Db\Metadata\Object\ConstraintObject */ echo ' ' . $constraint->getName() . ' -> ' . $constraint->getType() . PHP_EOL; if (!$constraint->hasColumns()) { continue; } echo ' column: ' . implode(', ', $constraint->getColumns()); if ($constraint->isForeignKey()) { $fkCols = []; foreach ($constraint->getReferencedColumns() as $refColumn) { $fkCols[] = $constraint->getReferencedTableName() . '.' . $refColumn; } echo ' => ' . implode(', ', $fkCols); } echo PHP_EOL; } echo '----' . PHP_EOL; } ``` Metadata returns value objects that provide an interface to help developers better explore the metadata. Below is the API for the various value objects: The TableObject: ```php class Zend\Db\Metadata\Object\TableObject { public function __construct($name); public function setColumns(array $columns); public function getColumns(); public function setConstraints($constraints); public function getConstraints(); public function setName($name); public function getName(); } ``` The ColumnObject: ```php class Zend\Db\Metadata\Object\ColumnObject { public function __construct($name, $tableName, $schemaName = null); public function setName($name); public function getName(); public function getTableName(); public function setTableName($tableName); public function setSchemaName($schemaName); public function getSchemaName(); public function getOrdinalPosition(); public function setOrdinalPosition($ordinalPosition); public function getColumnDefault(); public function setColumnDefault($columnDefault); public function getIsNullable(); public function setIsNullable($isNullable); public function isNullable(); public function getDataType(); public function setDataType($dataType); public function getCharacterMaximumLength(); public function setCharacterMaximumLength($characterMaximumLength); public function getCharacterOctetLength(); public function setCharacterOctetLength($characterOctetLength); public function getNumericPrecision(); public function setNumericPrecision($numericPrecision); public function getNumericScale(); public function setNumericScale($numericScale); public function getNumericUnsigned(); public function setNumericUnsigned($numericUnsigned); public function isNumericUnsigned(); public function getErratas(); public function setErratas(array $erratas); public function getErrata($errataName); public function setErrata($errataName, $errataValue); } ``` The ConstraintObject: ```php class Zend\Db\Metadata\Object\ConstraintObject { public function __construct($name, $tableName, $schemaName = null); public function setName($name); public function getName(); public function setSchemaName($schemaName); public function getSchemaName(); public function getTableName(); public function setTableName($tableName); public function setType($type); public function getType(); public function hasColumns(); public function getColumns(); public function setColumns(array $columns); public function getReferencedTableSchema(); public function setReferencedTableSchema($referencedTableSchema); public function getReferencedTableName(); public function setReferencedTableName($referencedTableName); public function getReferencedColumns(); public function setReferencedColumns(array $referencedColumns); public function getMatchOption(); public function setMatchOption($matchOption); public function getUpdateRule(); public function setUpdateRule($updateRule); public function getDeleteRule(); public function setDeleteRule($deleteRule); public function getCheckClause(); public function setCheckClause($checkClause); public function isPrimaryKey(); public function isUnique(); public function isForeignKey(); public function isCheck(); } ``` The TriggerObject: ```php class Zend\Db\Metadata\Object\TriggerObject { public function getName(); public function setName($name); public function getEventManipulation(); public function setEventManipulation($eventManipulation); public function getEventObjectCatalog(); public function setEventObjectCatalog($eventObjectCatalog); public function getEventObjectSchema(); public function setEventObjectSchema($eventObjectSchema); public function getEventObjectTable(); public function setEventObjectTable($eventObjectTable); public function getActionOrder(); public function setActionOrder($actionOrder); public function getActionCondition(); public function setActionCondition($actionCondition); public function getActionStatement(); public function setActionStatement($actionStatement); public function getActionOrientation(); public function setActionOrientation($actionOrientation); public function getActionTiming(); public function setActionTiming($actionTiming); public function getActionReferenceOldTable(); public function setActionReferenceOldTable($actionReferenceOldTable); public function getActionReferenceNewTable(); public function setActionReferenceNewTable($actionReferenceNewTable); public function getActionReferenceOldRow(); public function setActionReferenceOldRow($actionReferenceOldRow); public function getActionReferenceNewRow(); public function setActionReferenceNewRow($actionReferenceNewRow); public function getCreated(); public function setCreated($created); } ``` zend-db-release-2.8.1/doc/book/zend.db.result-set.md000066400000000000000000000107261270372430400221460ustar00rootroot00000000000000# Zend\\Db\\ResultSet `Zend\Db\ResultSet` is a sub-component of Zend\\Db for abstracting the iteration of rowset producing queries. While data sources for this can be anything that is iterable, generally a `Zend\Db\Adapter\Driver\ResultInterface` based object is the primary source for retrieving data. `Zend\Db\ResultSet`'s must implement the `Zend\Db\ResultSet\ResultSetInterface` and all sub-components of Zend\\Db that return a ResultSet as part of their API will assume an instance of a `ResultSetInterface` should be returned. In most casts, the Prototype pattern will be used by consuming object to clone a prototype of a ResultSet and return a specialized ResultSet with a specific data source injected. The interface of ResultSetInterface looks like this: ```php use Countable; use Traversable; interface ResultSetInterface extends Traversable, Countable { public function initialize($dataSource); public function getFieldCount(); } ``` ## Quickstart `Zend\Db\ResultSet\ResultSet` is the most basic form of a ResultSet object that will expose each row as either an ArrayObject-like object or an array of row data. By default, `Zend\Db\Adapter\Adapter` will use a prototypical `Zend\Db\ResultSet\ResultSet` object for iterating when using the `Zend\Db\Adapter\Adapter::query()` method. The following is an example workflow similar to what one might find inside `Zend\Db\Adapter\Adapter::query()`: ```php use Zend\Db\Adapter\Driver\ResultInterface; use Zend\Db\ResultSet\ResultSet; $stmt = $driver->createStatement('SELECT * FROM users'); $stmt->prepare(); $result = $stmt->execute($parameters); if ($result instanceof ResultInterface && $result->isQueryResult()) { $resultSet = new ResultSet; $resultSet->initialize($result); foreach ($resultSet as $row) { echo $row->my_column . PHP_EOL; } } ``` ## Zend\\Db\\ResultSet\\ResultSet and Zend\\Db\\ResultSet\\AbstractResultSet For most purposes, either a instance of `Zend\Db\ResultSet\ResultSet` or a derivative of `Zend\Db\ResultSet\AbstractResultSet` will be being used. The implementation of the `AbstractResultSet` offers the following core functionality: ```php namespace Zend\Db\ResultSet; use Iterator; abstract class AbstractResultSet implements Iterator, ResultSetInterface { public function initialize($dataSource) public function getDataSource() public function getFieldCount() /** Iterator */ public function next() public function key() public function current() public function valid() public function rewind() /** countable */ public function count() /** get rows as array */ public function toArray() } ``` ## Zend\\Db\\ResultSet\\HydratingResultSet `Zend\Db\ResultSet\HydratingResultSet` is a more flexible `ResultSet` object that allows the developer to choose an appropriate "hydration strategy" for getting row data into a target object. While iterating over results, `HydratingResultSet` will take a prototype of a target object and clone it once for each row. The `HydratingResultSet` will then hydrate that clone with the row data. In the example below, rows from the database will be iterated, and during iteration, `HydratingRowSet` will use the Reflection based hydrator to inject the row data directly into the protected members of the cloned UserEntity object: ```php use Zend\Db\Adapter\Driver\ResultInterface; use Zend\Db\ResultSet\HydratingResultSet; use Zend\Stdlib\Hydrator\Reflection as ReflectionHydrator; class UserEntity { protected $first_name; protected $last_name; public function getFirstName() { return $this->first_name; } public function getLastName() { return $this->last_name; } public function setFirstName($first_name) { $this->first_name = $first_name; } public function setLastName($last_name) { $this->last_name = $last_name; } } $stmt = $driver->createStatement($sql); $stmt->prepare($parameters); $result = $stmt->execute(); if ($result instanceof ResultInterface && $result->isQueryResult()) { $resultSet = new HydratingResultSet(new ReflectionHydrator, new UserEntity); $resultSet->initialize($result); foreach ($resultSet as $user) { echo $user->getFirstName() . ' ' . $user->getLastName() . PHP_EOL; } } ``` For more information, see the [zend-hydrator](https://zendframework.github.io/zend-hydrator/) documentation to get a better sense of the different strategies that can be employed in order to populate a target object. zend-db-release-2.8.1/doc/book/zend.db.row-gateway.md000066400000000000000000000056421270372430400223060ustar00rootroot00000000000000# Zend\\Db\\RowGateway `Zend\Db\RowGateway` is a sub-component of Zend\\Db that implements the Row Gateway pattern from PoEAA. This effectively means that Row Gateway objects primarily model a row in a database, and have methods such as save() and delete() that will help persist this row-as-an-object in the database itself. Likewise, after a row from the database is retrieved, it can then be manipulated and save()'d back to the database in the same position (row), or it can be delete()'d from the table. The interface for a Row Gateway object simply adds save() and delete() and this is the interface that should be assumed when a component has a dependency that is expected to be an instance of a RowGateway object: ```php interface RowGatewayInterface { public function save(); public function delete(); } ``` ## Quickstart While most of the time, RowGateway will be used in conjunction with other Zend\\Db\\ResultSet producing objects, it is possible to use it standalone. To use it standalone, you simply need an Adapter and a set of data to work with. The following use case demonstrates Zend\\Db\\RowGateway\\RowGateway usage in its simplest form: ```php use Zend\Db\RowGateway\RowGateway; // query the database $resultSet = $adapter->query('SELECT * FROM `user` WHERE `id` = ?', [2]); // get array of data $rowData = $resultSet->current()->getArrayCopy(); // row gateway $rowGateway = new RowGateway('id', 'my_table', $adapter); $rowGateway->populate($rowData, true); $rowGateway->first_name = 'New Name'; $rowGateway->save(); // or delete this row: $rowGateway->delete(); ``` The workflow described above is greatly simplified when RowGateway is used in conjunction with the TableGateway feature. What this achieves is a Table Gateway object that when select()'ing from a table, will produce a ResultSet that is then capable of producing valid Row Gateway objects. Its usage looks like this: ```php use Zend\Db\TableGateway\Feature\RowGatewayFeature; use Zend\Db\TableGateway\TableGateway; $table = new TableGateway('artist', $adapter, new RowGatewayFeature('id')); $results = $table->select(['id' => 2]); $artistRow = $results->current(); $artistRow->name = 'New Name'; $artistRow->save(); ``` ## ActiveRecord Style Objects If you wish to have custom behaviour for your RowGateway objects (essentially making them behave similarly to the ActiveRecord pattern), pass a prototype object implementing the `RowGatewayInterface` to the `RowGatewayFeature` constructor instead of a primary key: ```php use Zend\Db\TableGateway\Feature\RowGatewayFeature; use Zend\Db\TableGateway\TableGateway; use Zend\Db\RowGateway\RowGatewayInterface; class Artist implements RowGatewayInterface { protected $adapter; public function __construct($adapter) { $this->adapter = $adapter; } // ... save() and delete() implementations } $table = new TableGateway('artist', $adapter, new RowGatewayFeature(new Artist($adapter))); ``` zend-db-release-2.8.1/doc/book/zend.db.sql.ddl.md000066400000000000000000000130071270372430400213730ustar00rootroot00000000000000# Zend\\Db\\Sql\\Ddl `Zend\Db\Sql\Ddl` is a sub-component of `Zend\Db\Sql` that allows consumers to create statement objects that will produce DDL (Data Definition Language) SQL statements. When combined with a platform specific `Zend\Db\Sql\Sql` object, these DDL objects are capable of producing platform-specific `CREATE TABLE` statements, with specialized data types, constraints, and indexes for a database/schema. The following platforms have platform specializations for DDL: * MySQL * All databases compatible with ANSI SQL92 ## Creating Tables Like `Zend\Db\Sql` objects, each statement type is represented by a class. For example, `CREATE TABLE` is modeled by a `CreateTable` object; this is likewise the same for `ALTER TABLE` (as `AlterTable`), and `DROP TABLE` (as `DropTable`). These classes exist in the `Zend\Db\Sql\Ddl` namespace. To initiate the building of a DDL statement, such as `CreateTable`, one needs to instantiate the object. There are a couple of valid patterns for this: ```php use Zend\Db\Sql\Ddl; $table = new Ddl\CreateTable(); // or with table $table = new Ddl\CreateTable('bar'); // optionally, as a temporary table $table = new Ddl\CreateTable('bar', true); ``` You can also set the table after instantiation: ```php $table->setTable('bar'); ``` Currently, columns are added by creating a column object, described in the data type table in the data type section below: ```php use Zend\Db\Sql\Ddl\Column; $table->addColumn(new Column\Integer('id')); $table->addColumn(new Column\Varchar('name', 255)); ``` Beyond adding columns to a table, constraints can also be added: ```php use Zend\Db\Sql\Ddl\Constraint; $table->addConstraint(new Constraint\PrimaryKey('id')); $table->addConstraint( new Constraint\UniqueKey(['name', 'foo'], 'my_unique_key') ); ``` ## Altering Tables Similarly to `CreateTable`, you may also instantiate `AlterTable`: ```php use Zend\Db\Sql\Ddl; $table = new Ddl\AlterTable(); // or with table $table = new Ddl\AlterTable('bar'); // optionally, as a temporary table $table = new Ddl\AlterTable('bar', true); ``` The primary difference between a `CreateTable` and `AlterTable` is that the `AlterTable` takes into account that the table and its assets already exist. Therefore, while you still have `addColumn()` and `addConstraint()`, you will also see the ability to change existing columns: ```php use Zend\Db\Sql\Ddl\Column; $table->changeColumn('name', Column\Varchar('new_name', 50)); ``` You may also drop existing columns or constraints: ```php $table->dropColumn('foo'); $table->dropConstraint('my_index'); ``` ## Dropping Tables To drop a table, create a `DropTable` statement object: ```php $drop = new Ddl\DropTable('bar'); ``` ## Executing DDL Statements After a DDL statement object has been created and configured, at some point you will want to execute the statement. To do this, you will need two other objects: an `Adapter` instance, and a properly seeded `Sql` instance. The workflow looks something like this, with `$ddl` being a `CreateTable`, `AlterTable`, or `DropTable` instance: ```php use Zend\Db\Sql\Sql; // existence of $adapter is assumed $sql = new Sql($adapter); $adapter->query( $sql->getSqlStringForSqlObject($ddl), $adapter::QUERY_MODE_EXECUTE ); ``` By passing the `$ddl` object through the `$sql` object's `getSqlStringForSqlObject()` method, we ensure that any platform specific specializations/modifications are utilized to create a platform specific SQL statement. Next, using the constant `Zend\Db\Adapter\Adapter::QUERY_MODE_EXECUTE` ensures that the SQL statement is not prepared, as many DDL statements on a variety of platforms cannot be prepared, only executed. ## Currently Supported Data Types These types exist in the `Zend\Db\Sql\Ddl\Column` namespace. Data types must implement `Zend\Db\Sql\Ddl\Column\ColumnInterface`. In alphabetical order: Type | Arguments For Construction -----------------|--------------------------- BigInteger | `$name`, `$nullable = false`, `$default = null`, `array $options = array()` Blob | `$name`, `$length`, `nullable = false`, `$default = null`, `array $options = array()` Boolean | `$name` Char | `$name`, `length` Column (generic) | `$name = null` Date | `$name` Decimal | `$name`, `$precision`, `$scale = null` Float | `$name`, `$digits`, `$decimal` (Note: this class is deprecated as of 2.4.0; use Floating instead) Floating | `$name`, `$digits`, `$decimal` Integer | `$name`, `$nullable = false`, `default = null`, `array $options = array()` Time | `$name` Varchar | `$name`, `$length` Each of the above types can be utilized in any place that accepts a `Column\ColumnInterface` instance. Currently, this is primarily in `CreateTable::addColumn()` and `AlterTable`'s `addColumn()` and `changeColumn()` methods. ## Currently Supported Constraint Types These types exist in the `Zend\Db\Sql\Ddl\Constraint` namespace. Data types must implement `Zend\Db\Sql\Ddl\Constraint\ConstraintInterface`. In alphabetical order: Type | Arguments For Construction -----------|--------------------------- Check | `$expression`, `$name` ForeignKey | `$name`, `$column`, `$referenceTable`, `$referenceColumn`, `$onDeleteRule = null`, `$onUpdateRule = null` PrimaryKey | `$columns` UniqueKey | `$column`, `$name = null` Each of the above types can be utilized in any place that accepts a `Column\ConstraintInterface` instance. Currently, this is primarily in `CreateTable::addConstraint()` and `AlterTable::addConstraint()`. zend-db-release-2.8.1/doc/book/zend.db.sql.md000066400000000000000000000452561270372430400206440ustar00rootroot00000000000000# Zend\\Db\\Sql `Zend\Db\Sql` is a SQL abstraction layer for building platform specific SQL queries via an object-oriented API. The end result of an `Zend\Db\Sql` object will be to either produce a Statement and Parameter container that represents the target query, or a full string that can be directly executed against the database platform. To achieve this, `Zend\Db\Sql` objects require a `Zend\Db\Adapter\Adapter` object in order to produce the desired results. ## Zend\\Db\\Sql\\Sql (Quickstart) As there are four primary tasks associated with interacting with a database (from the DML, or Data Manipulation Language): selecting, inserting, updating and deleting. As such, there are four primary objects that developers can interact or building queries, `Zend\Db\Sql\Select`, `Insert`, `Update` and `Delete`. Since these four tasks are so closely related, and generally used together within the same application, `Zend\Db\Sql\Sql` objects help you create them and produce the result you are attempting to achieve. ```php use Zend\Db\Sql\Sql; $sql = new Sql($adapter); $select = $sql->select(); // @return Zend\Db\Sql\Select $insert = $sql->insert(); // @return Zend\Db\Sql\Insert $update = $sql->update(); // @return Zend\Db\Sql\Update $delete = $sql->delete(); // @return Zend\Db\Sql\Delete ``` As a developer, you can now interact with these objects, as described in the sections below, to specialize each query. Once they have been populated with values, they are ready to either be prepared or executed. To prepare (using a Select object): ```php use Zend\Db\Sql\Sql; $sql = new Sql($adapter); $select = $sql->select(); $select->from('foo'); $select->where(['id' => 2]); $statement = $sql->prepareStatementForSqlObject($select); $results = $statement->execute(); ``` To execute (using a Select object) ```php use Zend\Db\Sql\Sql; $sql = new Sql($adapter); $select = $sql->select(); $select->from('foo'); $select->where(['id' => 2]); $selectString = $sql->buildSqlString($select); $results = $adapter->query($selectString, $adapter::QUERY_MODE_EXECUTE); ``` `Zend\\Db\\Sql\\Sql` objects can also be bound to a particular table so that in getting a select, insert, update, or delete object, they are all primarily seeded with the same table when produced. ```php use Zend\Db\Sql\Sql; $sql = new Sql($adapter, 'foo'); $select = $sql->select(); $select->where(['id' => 2]); // $select already has the from('foo') applied ``` ## Zend\\Db\\Sql's Select, Insert, Update and Delete Each of these objects implements the following (2) interfaces: ```php interface PreparableSqlInterface { public function prepareStatement(Adapter $adapter, StatementInterface $statement); } interface SqlInterface { public function getSqlString(PlatformInterface $adapterPlatform = null); } ``` These are the functions you can call to either produce (a) a prepared statement, or (b) a string to be executed. ## Zend\\Db\\Sql\\Select `Zend\Db\Sql\Select` is an object with the primary function of presenting a unified API for building platform specific SQL SELECT queries. The class can be instantiated and consumed without `Zend\Db\Sql\Sql`: ```php use Zend\Db\Sql\Select; $select = new Select(); // or, to produce a $select bound to a specific table $select = new Select('foo'); ``` If a table is provided to the Select object, then `from()` cannot be called later to change the name of the table. Once you have a valid Select object, the following API can be used to further specify various select statement parts: ```php class Select extends AbstractSql implements SqlInterface, PreparableSqlInterface { const JOIN_INNER = 'inner'; const JOIN_OUTER = 'outer'; const JOIN_LEFT = 'left'; const JOIN_RIGHT = 'right'; const SQL_STAR = '*'; const ORDER_ASCENDING = 'ASC'; const ORDER_DESCENDING = 'DESC'; public $where; // @param Where $where public function __construct($table = null); public function from($table); public function columns(array $columns, $prefixColumnsWithTable = true); public function join($name, $on, $columns = self::SQL_STAR, $type = self::JOIN_INNER); public function where($predicate, $combination = Predicate\PredicateSet::OP_AND); public function group($group); public function having($predicate, $combination = Predicate\PredicateSet::OP_AND); public function order($order); public function limit($limit); public function offset($offset); } ``` ### from(): ```php // as a string: $select->from('foo'); // as an array to specify an alias: // produces SELECT "t".* FROM "table" AS "t" $select->from(['t' => 'table']); // using a Sql\TableIdentifier: // same output as above $select->from(new TableIdentifier(['t' => 'table'])); ``` ### columns(): ```php // as array of names $select->columns(['foo', 'bar']); // as an associative array with aliases as the keys: // produces 'bar' AS 'foo', 'bax' AS 'baz' $select->columns(['foo' => 'bar', 'baz' => 'bax']); ``` ### join(): ```php $select->join( 'foo', // table name 'id = bar.id', // expression to join on (will be quoted by platform object before insertion), ['bar', 'baz'], // (optional) list of columns, same requirements as columns() above $select::JOIN_OUTER // (optional), one of inner, outer, left, right also represented by constants in the API ); $select ->from(['f' => 'foo']) // base table ->join( ['b' => 'bar'], // join table with alias 'f.foo_id = b.foo_id' // join expression ); ``` ### where(), having(): The `Zend\Db\Sql\Select` object provides bit of flexibility as it regards to what kind of parameters are acceptable when calling where() or having(). The method signature is listed as: ```php /** * Create where clause * * @param Where|\Closure|string|array $predicate * @param string $combination One of the OP_* constants from Predicate\PredicateSet * @return Select */ public function where($predicate, $combination = Predicate\PredicateSet::OP_AND); ``` As you can see, there are a number of different ways to pass criteria to both having() and where(). If you provide a `Zend\Db\Sql\Where` object to where() or a `Zend\Db\Sql\Having` object to having(), the internal objects for Select will be replaced completely. When the where/having() is processed, this object will be iterated to produce the WHERE or HAVING section of the SELECT statement. If you provide a `Closure` to where() or having(), this function will be called with the Select's `Where` object as the only parameter. So the following is possible: ```php $spec = function (Where $where) { $where->like('username', 'ralph%'); }; $select->where($spec); ``` If you provide a string, this string will be used to instantiate a `Zend\Db\Sql\Predicate\Expression` object so that it's contents will be applied as is. This means that there will be no quoting in the fragment provided. Consider the following code: ```php // SELECT "foo".* FROM "foo" WHERE x = 5 $select->from('foo')->where('x = 5'); ``` If you provide an array who's values are keyed by an integer, the value can either be a string that will be then used to build a `Predicate\Expression` or any object that implements `Predicate\PredicateInterface`. These objects are pushed onto the Where stack with the $combination provided. Consider the following code: ```php // SELECT "foo".* FROM "foo" WHERE x = 5 AND y = z $select->from('foo')->where(['x = 5', 'y = z']); ``` If you provide an array with values keyed as strings, these values will be handled in the following: - PHP value nulls will be made into a `Predicate\IsNull` object - PHP value array()s will be made into a `Predicate\In` object - PHP value strings will be made into a `Predicate\Operator` object such that the string key will be identifier, and the value will target value. Consider the following code: ```php // SELECT "foo".* FROM "foo" WHERE "c1" IS NULL AND "c2" IN (?, ?, ?) AND "c3" IS NOT NULL $select->from('foo')->where([ 'c1' => null, 'c2' => [1, 2, 3], new \Zend\Db\Sql\Predicate\IsNotNull('c3'), ]); ``` ### order(): ```php $select = new Select; $select->order('id DESC'); // produces 'id' DESC $select = new Select; $select ->order('id DESC') ->order('name ASC, age DESC'); // produces 'id' DESC, 'name' ASC, 'age' DESC $select = new Select; $select->order(['name ASC', 'age DESC']); // produces 'name' ASC, 'age' DESC ``` ### limit() and offset(): ```php $select = new Select; $select->limit(5); // always takes an integer/numeric $select->offset(10); // similarly takes an integer/numeric ``` ## Zend\\Db\\Sql\\Insert The Insert API: ```php class Insert implements SqlInterface, PreparableSqlInterface { const VALUES_MERGE = 'merge'; const VALUES_SET = 'set'; public function __construct($table = null); public function into($table); public function columns(array $columns); public function values(array $values, $flag = self::VALUES_SET); } ``` Similarly to Select objects, the table can be set at construction time or via into(). ### columns(): ```php $insert->columns(['foo', 'bar']); // set the valid columns ``` ### values(): ```php // default behavior of values is to set the values // successive calls will not preserve values from previous calls $insert->values([ 'col_1' => 'value1', 'col_2' => 'value2', ]); ``` ```php // merging values with previous calls $insert->values(['col_2' => 'value2'], $insert::VALUES_MERGE); ``` ## Zend\\Db\\Sql\\Update ```php class Update { const VALUES_MERGE = 'merge'; const VALUES_SET = 'set'; public $where; // @param Where $where public function __construct($table = null); public function table($table); public function set(array $values, $flag = self::VALUES_SET); public function where($predicate, $combination = Predicate\PredicateSet::OP_AND); } ``` ### set(): ```php $update->set(['foo' => 'bar', 'baz' => 'bax']); ``` ### where(): See where section below. ## Zend\\Db\\Sql\\Delete ```php class Delete { public $where; // @param Where $where public function __construct($table = null); public function from($table); public function where($predicate, $combination = Predicate\PredicateSet::OP_AND); } ``` ### where(): See where section below. ## Zend\\Db\\Sql\\Where & Zend\\Db\\Sql\\Having In the following, we will talk about Where, Having is implies as being the same API. Effectively, Where and Having extend from the same base object, a Predicate (and PredicateSet). All of the parts that make up a where or having that are and'ed or or'd together are called predicates. The full set of predicates is called a PredicateSet. This object set generally contains the values (and identifiers) separate from the fragment they belong to until the last possible moment when the statement is either used to be prepared (parameteritized), or executed. In parameterization, the parameters will be replaced with their proper placeholder (a named or positional parameter), and the values stored inside a Adapter\\ParameterContainer. When executed, the values will be interpolated into the fragments they belong to and properly quoted. It is important to know that in this API, a distinction is made between what elements are considered identifiers (TYPE\_IDENTIFIER) and which of those is a value (TYPE\_VALUE). There is also a special use case type for literal values (TYPE\_LITERAL). These are all exposed via the `Zend\Db\Sql\ExpressionInterface` interface. > ### Literals > > In ZF 2.1, an actual `Literal` type was added. `Zend\Db\Sql` now makes the distinction that Literals > will not have any parameters that need interpolating whereas it is expected that `Expression` > objects *might* have parameters that need interpolating. In cases where there are parameters in an > `Expression`, `Zend\Db\Sql\AbstractSql` will do its best to identify placeholders when the > Expression is processed during statement creation. In short, if you don't have parameters, use > `Literal` objects. The Zend\\Db\\Sql\\Where (Predicate/PredicateSet) API: ```php // Where & Having: class Predicate extends PredicateSet { public $and; public $or; public $AND; public $OR; public $NEST; public $UNNEST; public function nest(); public function setUnnest(Predicate $predicate); public function unnest(); public function equalTo( $left, $right, $leftType = self::TYPE_IDENTIFIER, $rightType = self::TYPE_VALUE ); public function notEqualTo( $left, $right, $leftType = self::TYPE_IDENTIFIER, $rightType = self::TYPE_VALUE ); public function lessThan( $left, $right, $leftType = self::TYPE_IDENTIFIER, $rightType = self::TYPE_VALUE ); public function greaterThan( $left, $right, $leftType = self::TYPE_IDENTIFIER, $rightType = self::TYPE_VALUE ); public function lessThanOrEqualTo( $left, $right, $leftType = self::TYPE_IDENTIFIER, $rightType = self::TYPE_VALUE ); public function greaterThanOrEqualTo( $left, $right, $leftType = self::TYPE_IDENTIFIER, $rightType = self::TYPE_VALUE ); public function like($identifier, $like); public function literal($literal); public function expression($expression, $parameter); public function isNull($identifier); public function isNotNull($identifier); public function in($identifier, array $valueSet = []); public function between($identifier, $minValue, $maxValue); // Inherited From PredicateSet public function addPredicate(PredicateInterface $predicate, $combination = null); public function getPredicates(); public function orPredicate(PredicateInterface $predicate); public function andPredicate(PredicateInterface $predicate); public function getExpressionData(); public function count(); } ``` Each method in the Where API will produce a corresponding Predicate object of a similarly named type, described below, with the full API of the object: ### equalTo(), lessThan(), greaterThan(), lessThanOrEqualTo(), greaterThanOrEqualTo(): ```php $where->equalTo('id', 5); // same as the following workflow $where->addPredicate( new Predicate\Operator($left, Operator::OPERATOR_EQUAL_TO, $right, $leftType, $rightType) ); class Operator implements PredicateInterface { const OPERATOR_EQUAL_TO = '='; const OP_EQ = '='; const OPERATOR_NOT_EQUAL_TO = '!='; const OP_NE = '!='; const OPERATOR_LESS_THAN = '<'; const OP_LT = '<'; const OPERATOR_LESS_THAN_OR_EQUAL_TO = '<='; const OP_LTE = '<='; const OPERATOR_GREATER_THAN = '>'; const OP_GT = '>'; const OPERATOR_GREATER_THAN_OR_EQUAL_TO = '>='; const OP_GTE = '>='; public function __construct( $left = null, $operator = self::OPERATOR_EQUAL_TO, $right = null, $leftType = self::TYPE_IDENTIFIER, $rightType = self::TYPE_VALUE ); public function setLeft($left); public function getLeft(); public function setLeftType($type); public function getLeftType(); public function setOperator($operator); public function getOperator(); public function setRight($value); public function getRight(); public function setRightType($type); public function getRightType(); public function getExpressionData(); } ``` ### like($identifier, $like): ```php $where->like($identifier, $like): // same as $where->addPredicate( new Predicate\Like($identifier, $like) ); // full API class Like implements PredicateInterface { public function __construct($identifier = null, $like = null); public function setIdentifier($identifier); public function getIdentifier(); public function setLike($like); public function getLike(); } ``` ### literal($literal); ```php $where->literal($literal); // same as $where->addPredicate( new Predicate\Literal($literal) ); // full API class Literal implements ExpressionInterface, PredicateInterface { const PLACEHOLDER = '?'; public function __construct($literal = ''); public function setLiteral($literal); public function getLiteral(); } ``` ### expression($expression, $parameter); ```php $where->expression($expression, $parameter); // same as $where->addPredicate( new Predicate\Expression($expression, $parameter) ); // full API class Expression implements ExpressionInterface, PredicateInterface { const PLACEHOLDER = '?'; public function __construct( $expression = null, $valueParameter = null /* [, $valueParameter, ... ] */ ); public function setExpression($expression); public function getExpression(); public function setParameters($parameters); public function getParameters(); public function setTypes(array $types); public function getTypes(); } ``` ### isNull($identifier); ```php $where->isNull($identifier); // same as $where->addPredicate( new Predicate\IsNull($identifier) ); // full API class IsNull implements PredicateInterface { public function __construct($identifier = null); public function setIdentifier($identifier); public function getIdentifier(); } ``` ### isNotNull($identifier); ```php $where->isNotNull($identifier); // same as $where->addPredicate( new Predicate\IsNotNull($identifier) ); // full API class IsNotNull implements PredicateInterface { public function __construct($identifier = null); public function setIdentifier($identifier); public function getIdentifier(); } ``` ### in($identifier, array $valueSet = []); ```php $where->in($identifier, array $valueSet = []); // same as $where->addPredicate( new Predicate\In($identifier, $valueSet) ); // full API class In implements PredicateInterface { public function __construct($identifier = null, array $valueSet = []); public function setIdentifier($identifier); public function getIdentifier(); public function setValueSet(array $valueSet); public function getValueSet(); } ``` ### between($identifier, $minValue, $maxValue); ```php $where->between($identifier, $minValue, $maxValue); // same as $where->addPredicate( new Predicate\Between($identifier, $minValue, $maxValue) ); // full API class Between implements PredicateInterface { public function __construct($identifier = null, $minValue = null, $maxValue = null); public function setIdentifier($identifier); public function getIdentifier(); public function setMinValue($minValue); public function getMinValue(); public function setMaxValue($maxValue); public function getMaxValue(); public function setSpecification($specification); } ``` zend-db-release-2.8.1/doc/book/zend.db.table-gateway.md000066400000000000000000000157371270372430400225740ustar00rootroot00000000000000# Zend\\Db\\TableGateway The Table Gateway object is intended to provide an object that represents a table in a database, and the methods of this object mirror the most common operations on a database table. In code, the interface for such an object looks like this: ```php interface Zend\Db\TableGateway\TableGatewayInterface { public function getTable(); public function select($where = null); public function insert($set); public function update($set, $where = null); public function delete($where); } ``` There are two primary implementations of the `TableGatewayInterface` that are of the most useful: `AbstractTableGateway` and `TableGateway`. The `AbstractTableGateway` is an abstract basic implementation that provides functionality for `select()`, `insert()`, `update()`, `delete()`, as well as an additional API for doing these same kinds of tasks with explicit SQL objects. These methods are `selectWith()`, `insertWith()`, `updateWith()` and `deleteWith()`. In addition, AbstractTableGateway also implements a "Feature" API, that allows for expanding the behaviors of the base `TableGateway` implementation without having to extend the class with this new functionality. The `TableGateway` concrete implementation simply adds a sensible constructor to the `AbstractTableGateway` class so that out-of-the-box, `TableGateway` does not need to be extended in order to be consumed and utilized to its fullest. ## Basic Usage The quickest way to get up and running with `Zend\Db\TableGateway` is to configure and utilize the concrete implementation of the `TableGateway`. The API of the concrete `TableGateway` is: ```php class TableGateway extends AbstractTableGateway { public $lastInsertValue; public $table; public $adapter; public function __construct( $table, Adapter $adapter, $features = null, ResultSet $resultSetPrototype = null, Sql $sql = null ); /** Inherited from AbstractTableGateway */ public function isInitialized(); public function initialize(); public function getTable(); public function getAdapter(); public function getColumns(); public function getFeatureSet(); public function getResultSetPrototype(); public function getSql(); public function select($where = null); public function selectWith(Select $select); public function insert($set); public function insertWith(Insert $insert); public function update($set, $where = null); public function updateWith(Update $update); public function delete($where); public function deleteWith(Delete $delete); public function getLastInsertValue(); } ``` The concrete `TableGateway` object practices constructor injection for getting dependencies and options into the instance. The table name and an instance of an Adapter are all that is needed to setup a working `TableGateway` object. Out of the box, this implementation makes no assumptions about table structure or metadata, and when `select()` is executed, a simple ResultSet object with the populated Adapter's Result (the datasource) will be returned and ready for iteration. ```php use Zend\Db\TableGateway\TableGateway; $projectTable = new TableGateway('project', $adapter); $rowset = $projectTable->select(['type' => 'PHP']); echo 'Projects of type PHP: '; foreach ($rowset as $projectRow) { echo $projectRow['name'] . PHP_EOL; } // or, when expecting a single row: $artistTable = new TableGateway('artist', $adapter); $rowset = $artistTable->select(['id' => 2]); $artistRow = $rowset->current(); var_dump($artistRow); ``` The `select()` method takes the same arguments as `Zend\Db\Sql\Select::where()` with the addition of also being able to accept a closure, which in turn, will be passed the current Select object that is being used to build the SELECT query. The following usage is possible: ```php use Zend\Db\TableGateway\TableGateway; use Zend\Db\Sql\Select; $artistTable = new TableGateway('artist', $adapter); // search for at most 2 artists who's name starts with Brit, ascending $rowset = $artistTable->select(function (Select $select) { $select->where->like('name', 'Brit%'); $select->order('name ASC')->limit(2); }); ``` ## TableGateway Features The Features API allows for extending the functionality of the base `TableGateway` object without having to polymorphically extend the base class. This allows for a wider array of possible mixing and matching of features to achieve a particular behavior that needs to be attained to make the base implementation of `TableGateway` useful for a particular problem. With the `TableGateway` object, features should be injected though the constructor. The constructor can take Features in 3 different forms: as a single feature object, as a FeatureSet object, or as an array of Feature objects. There are a number of features built-in and shipped with Zend\\Db: - GlobalAdapterFeature: the ability to use a global/static adapter without needing to inject it into a `TableGateway` instance. This is more useful when you are extending the `AbstractTableGateway` implementation: ```php use Zend\Db\TableGateway\AbstractTableGateway; use Zend\Db\TableGateway\Feature; class MyTableGateway extends AbstractTableGateway { public function __construct() { $this->table = 'my_table'; $this->featureSet = new Feature\FeatureSet(); $this->featureSet->addFeature(new Feature\GlobalAdapterFeature()); $this->initialize(); } } // elsewhere in code, in a bootstrap Zend\Db\TableGateway\Feature\GlobalAdapterFeature::setStaticAdapter($adapter); // in a controller, or model somewhere $table = new MyTableGateway(); // adapter is statically loaded ``` - MasterSlaveFeature: the ability to use a master adapter for insert(), update(), and delete() while using a slave adapter for all select() operations. ```php $table = new TableGateway('artist', $adapter, new Feature\MasterSlaveFeature($slaveAdapter)); ``` - MetadataFeature: the ability populate `TableGateway` with column information from a Metadata object. It will also store the primary key information in case RowGatewayFeature needs to consume this information. ```php $table = new TableGateway('artist', $adapter, new Feature\MetadataFeature()); ``` - EventFeature: the ability utilize a `TableGateway` object with Zend\\EventManager and to be able to subscribe to various events in a `TableGateway` lifecycle. ```php $table = new TableGateway('artist', $adapter, new Feature\EventFeature($eventManagerInstance)); ``` - RowGatewayFeature: the ability for `select()` to return a ResultSet object that upon iteration will return a `RowGateway` object for each row. ```php $table = new TableGateway('artist', $adapter, new Feature\RowGatewayFeature('id')); $results = $table->select(['id' => 2]); $artistRow = $results->current(); $artistRow->name = 'New Name'; $artistRow->save(); ``` zend-db-release-2.8.1/doc/bookdown.json000066400000000000000000000005101270372430400177430ustar00rootroot00000000000000{ "title": "Zend\\Db", "target": "html/", "content": [ "book/zend.db.adapter.md", "book/zend.db.result-set.md", "book/zend.db.sql.md", "book/zend.db.sql.ddl.md", "book/zend.db.table-gateway.md", "book/zend.db.row-gateway.md", "book/zend.db.metadata.md" ] }zend-db-release-2.8.1/src/000077500000000000000000000000001270372430400152545ustar00rootroot00000000000000zend-db-release-2.8.1/src/Adapter/000077500000000000000000000000001270372430400166345ustar00rootroot00000000000000zend-db-release-2.8.1/src/Adapter/Adapter.php000066400000000000000000000326401270372430400207320ustar00rootroot00000000000000createProfiler($parameters); } $driver = $this->createDriver($parameters); } elseif (!$driver instanceof Driver\DriverInterface) { throw new Exception\InvalidArgumentException( 'The supplied or instantiated driver object does not implement Zend\Db\Adapter\Driver\DriverInterface' ); } $driver->checkEnvironment(); $this->driver = $driver; if ($platform === null) { $platform = $this->createPlatform($parameters); } $this->platform = $platform; $this->queryResultSetPrototype = ($queryResultPrototype) ?: new ResultSet\ResultSet(); if ($profiler) { $this->setProfiler($profiler); } } /** * @param Profiler\ProfilerInterface $profiler * @return Adapter */ public function setProfiler(Profiler\ProfilerInterface $profiler) { $this->profiler = $profiler; if ($this->driver instanceof Profiler\ProfilerAwareInterface) { $this->driver->setProfiler($profiler); } return $this; } /** * @return null|Profiler\ProfilerInterface */ public function getProfiler() { return $this->profiler; } /** * getDriver() * * @throws Exception\RuntimeException * @return Driver\DriverInterface */ public function getDriver() { if ($this->driver === null) { throw new Exception\RuntimeException('Driver has not been set or configured for this adapter.'); } return $this->driver; } /** * @return Platform\PlatformInterface */ public function getPlatform() { return $this->platform; } /** * @return ResultSet\ResultSetInterface */ public function getQueryResultSetPrototype() { return $this->queryResultSetPrototype; } public function getCurrentSchema() { return $this->driver->getConnection()->getCurrentSchema(); } /** * query() is a convenience function * * @param string $sql * @param string|array|ParameterContainer $parametersOrQueryMode * @param \Zend\Db\ResultSet\ResultSetInterface $resultPrototype * @throws Exception\InvalidArgumentException * @return Driver\StatementInterface|ResultSet\ResultSet */ public function query($sql, $parametersOrQueryMode = self::QUERY_MODE_PREPARE, ResultSet\ResultSetInterface $resultPrototype = null) { if (is_string($parametersOrQueryMode) && in_array($parametersOrQueryMode, [self::QUERY_MODE_PREPARE, self::QUERY_MODE_EXECUTE])) { $mode = $parametersOrQueryMode; $parameters = null; } elseif (is_array($parametersOrQueryMode) || $parametersOrQueryMode instanceof ParameterContainer) { $mode = self::QUERY_MODE_PREPARE; $parameters = $parametersOrQueryMode; } else { throw new Exception\InvalidArgumentException('Parameter 2 to this method must be a flag, an array, or ParameterContainer'); } if ($mode == self::QUERY_MODE_PREPARE) { $this->lastPreparedStatement = null; $this->lastPreparedStatement = $this->driver->createStatement($sql); $this->lastPreparedStatement->prepare(); if (is_array($parameters) || $parameters instanceof ParameterContainer) { $this->lastPreparedStatement->setParameterContainer((is_array($parameters)) ? new ParameterContainer($parameters) : $parameters); $result = $this->lastPreparedStatement->execute(); } else { return $this->lastPreparedStatement; } } else { $result = $this->driver->getConnection()->execute($sql); } if ($result instanceof Driver\ResultInterface && $result->isQueryResult()) { $resultSet = clone ($resultPrototype ?: $this->queryResultSetPrototype); $resultSet->initialize($result); return $resultSet; } return $result; } /** * Create statement * * @param string $initialSql * @param ParameterContainer $initialParameters * @return Driver\StatementInterface */ public function createStatement($initialSql = null, $initialParameters = null) { $statement = $this->driver->createStatement($initialSql); if ($initialParameters === null || !$initialParameters instanceof ParameterContainer && is_array($initialParameters)) { $initialParameters = new ParameterContainer((is_array($initialParameters) ? $initialParameters : [])); } $statement->setParameterContainer($initialParameters); return $statement; } public function getHelpers(/* $functions */) { $functions = []; $platform = $this->platform; foreach (func_get_args() as $arg) { switch ($arg) { case self::FUNCTION_QUOTE_IDENTIFIER: $functions[] = function ($value) use ($platform) { return $platform->quoteIdentifier($value); }; break; case self::FUNCTION_QUOTE_VALUE: $functions[] = function ($value) use ($platform) { return $platform->quoteValue($value); }; break; } } } /** * @param $name * @throws Exception\InvalidArgumentException * @return Driver\DriverInterface|Platform\PlatformInterface */ public function __get($name) { switch (strtolower($name)) { case 'driver': return $this->driver; case 'platform': return $this->platform; default: throw new Exception\InvalidArgumentException('Invalid magic property on adapter'); } } /** * @param array $parameters * @return Driver\DriverInterface * @throws \InvalidArgumentException * @throws Exception\InvalidArgumentException */ protected function createDriver($parameters) { if (!isset($parameters['driver'])) { throw new Exception\InvalidArgumentException(__FUNCTION__ . ' expects a "driver" key to be present inside the parameters'); } if ($parameters['driver'] instanceof Driver\DriverInterface) { return $parameters['driver']; } if (!is_string($parameters['driver'])) { throw new Exception\InvalidArgumentException(__FUNCTION__ . ' expects a "driver" to be a string or instance of DriverInterface'); } $options = []; if (isset($parameters['options'])) { $options = (array) $parameters['options']; unset($parameters['options']); } $driverName = strtolower($parameters['driver']); switch ($driverName) { case 'mysqli': $driver = new Driver\Mysqli\Mysqli($parameters, null, null, $options); break; case 'sqlsrv': $driver = new Driver\Sqlsrv\Sqlsrv($parameters); break; case 'oci8': $driver = new Driver\Oci8\Oci8($parameters); break; case 'pgsql': $driver = new Driver\Pgsql\Pgsql($parameters); break; case 'ibmdb2': $driver = new Driver\IbmDb2\IbmDb2($parameters); break; case 'pdo': default: if ($driverName == 'pdo' || strpos($driverName, 'pdo') === 0) { $driver = new Driver\Pdo\Pdo($parameters); } } if (!isset($driver) || !$driver instanceof Driver\DriverInterface) { throw new Exception\InvalidArgumentException('DriverInterface expected', null, null); } return $driver; } /** * @param array $parameters * @return Platform\PlatformInterface */ protected function createPlatform(array $parameters) { if (isset($parameters['platform'])) { $platformName = $parameters['platform']; } elseif ($this->driver instanceof Driver\DriverInterface) { $platformName = $this->driver->getDatabasePlatformName(Driver\DriverInterface::NAME_FORMAT_CAMELCASE); } else { throw new Exception\InvalidArgumentException('A platform could not be determined from the provided configuration'); } // currently only supported by the IbmDb2 & Oracle concrete implementations $options = (isset($parameters['platform_options'])) ? $parameters['platform_options'] : []; switch ($platformName) { case 'Mysql': // mysqli or pdo_mysql driver $driver = ($this->driver instanceof Driver\Mysqli\Mysqli || $this->driver instanceof Driver\Pdo\Pdo) ? $this->driver : null; return new Platform\Mysql($driver); case 'SqlServer': // PDO is only supported driver for quoting values in this platform return new Platform\SqlServer(($this->driver instanceof Driver\Pdo\Pdo) ? $this->driver : null); case 'Oracle': $driver = ($this->driver instanceof Driver\Oci8\Oci8 || $this->driver instanceof Driver\Pdo\Pdo) ? $this->driver : null; return new Platform\Oracle($options, $driver); case 'Sqlite': // PDO is only supported driver for quoting values in this platform return new Platform\Sqlite(($this->driver instanceof Driver\Pdo\Pdo) ? $this->driver : null); case 'Postgresql': // pgsql or pdo postgres driver $driver = ($this->driver instanceof Driver\Pgsql\Pgsql || $this->driver instanceof Driver\Pdo\Pdo) ? $this->driver : null; return new Platform\Postgresql($driver); case 'IbmDb2': // ibm_db2 driver escaping does not need an action connection return new Platform\IbmDb2($options); default: return new Platform\Sql92(); } } /** * * @param array $parameters * @return Profiler\ProfilerInterface * @throws Exception\InvalidArgumentException */ protected function createProfiler($parameters) { if ($parameters['profiler'] instanceof Profiler\ProfilerInterface) { $profiler = $parameters['profiler']; } elseif (is_bool($parameters['profiler'])) { $profiler = ($parameters['profiler'] == true) ? new Profiler\Profiler : null; } else { throw new Exception\InvalidArgumentException( '"profiler" parameter must be an instance of ProfilerInterface or a boolean' ); } return $profiler; } /** * @param array $parameters * @return Driver\DriverInterface * @throws \InvalidArgumentException * @throws Exception\InvalidArgumentException * @deprecated */ protected function createDriverFromParameters(array $parameters) { return $this->createDriver($parameters); } /** * @param Driver\DriverInterface $driver * @return Platform\PlatformInterface * @deprecated */ protected function createPlatformFromDriver(Driver\DriverInterface $driver) { return $this->createPlatform($driver); } } zend-db-release-2.8.1/src/Adapter/AdapterAbstractServiceFactory.php000066400000000000000000000064671270372430400252770ustar00rootroot00000000000000getConfig($container); if (empty($config)) { return false; } return ( isset($config[$requestedName]) && is_array($config[$requestedName]) && ! empty($config[$requestedName]) ); } /** * Determine if we can create a service with name (SM v2 compatibility) * * @param serviceLocator $serviceLocator * @param string $name * @param string $requestedName * @return bool */ public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) { return $this->canCreate($serviceLocator, $requestedName); } /** * Create a DB adapter * * @param ContainerInterface $container * @param string $requestedName * @param array $options * @return Adapter */ public function __invoke(ContainerInterface $container, $requestedName, array $options = null) { $config = $this->getConfig($container); return new Adapter($config[$requestedName]); } /** * Create service with name * * @param ServiceLocatorInterface $serviceLocator * @param string $name * @param string $requestedName * @return Adapter */ public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) { return $this($serviceLocator, $requestedName); } /** * Get db configuration, if any * * @param ContainerInterface $container * @return array */ protected function getConfig(ContainerInterface $container) { if ($this->config !== null) { return $this->config; } if (! $container->has('config')) { $this->config = []; return $this->config; } $config = $container->get('config'); if (! isset($config['db']) || ! is_array($config['db']) ) { $this->config = []; return $this->config; } $config = $config['db']; if (! isset($config['adapters']) || ! is_array($config['adapters']) ) { $this->config = []; return $this->config; } $this->config = $config['adapters']; return $this->config; } } zend-db-release-2.8.1/src/Adapter/AdapterAwareInterface.php000066400000000000000000000010331270372430400235230ustar00rootroot00000000000000adapter = $adapter; return $this; } } zend-db-release-2.8.1/src/Adapter/AdapterInterface.php000066400000000000000000000012171270372430400225470ustar00rootroot00000000000000get('config'); return new Adapter($config['db']); } /** * Create db adapter service (v2) * * @param ServiceLocatorInterface $container * @return Adapter */ public function createService(ServiceLocatorInterface $container) { return $this($container, Adapter::class); } } zend-db-release-2.8.1/src/Adapter/Driver/000077500000000000000000000000001270372430400200675ustar00rootroot00000000000000zend-db-release-2.8.1/src/Adapter/Driver/AbstractConnection.php000066400000000000000000000047651270372430400243770ustar00rootroot00000000000000isConnected()) { $this->resource = null; } return $this; } /** * Get connection parameters * * @return array */ public function getConnectionParameters() { return $this->connectionParameters; } /** * Get driver name * * @return null|string */ public function getDriverName() { return $this->driverName; } /** * @return null|ProfilerInterface */ public function getProfiler() { return $this->profiler; } /** * {@inheritDoc} * * @return resource */ public function getResource() { if (!$this->isConnected()) { $this->connect(); } return $this->resource; } /** * Checks whether the connection is in transaction state. * * @return boolean */ public function inTransaction() { return $this->inTransaction; } /** * @param array $connectionParameters * @return self */ public function setConnectionParameters(array $connectionParameters) { $this->connectionParameters = $connectionParameters; return $this; } /** * {@inheritDoc} * * @return self */ public function setProfiler(ProfilerInterface $profiler) { $this->profiler = $profiler; return $this; } } zend-db-release-2.8.1/src/Adapter/Driver/ConnectionInterface.php000066400000000000000000000027761270372430400245340ustar00rootroot00000000000000driver = $driver; } /** * Get name * * @return string */ abstract public function getName(); } zend-db-release-2.8.1/src/Adapter/Driver/Feature/DriverFeatureInterface.php000066400000000000000000000015241270372430400265650ustar00rootroot00000000000000setConnectionParameters($connectionParameters); } elseif (is_resource($connectionParameters)) { $this->setResource($connectionParameters); } elseif (null !== $connectionParameters) { throw new Exception\InvalidArgumentException( '$connection must be an array of parameters, a db2 connection resource or null' ); } } /** * Set driver * * @param IbmDb2 $driver * @return self */ public function setDriver(IbmDb2 $driver) { $this->driver = $driver; return $this; } /** * @param resource $resource DB2 resource * @return self */ public function setResource($resource) { if (!is_resource($resource) || get_resource_type($resource) !== 'DB2 Connection') { throw new Exception\InvalidArgumentException('The resource provided must be of type "DB2 Connection"'); } $this->resource = $resource; return $this; } /** * {@inheritDoc} */ public function getCurrentSchema() { if (!$this->isConnected()) { $this->connect(); } $info = db2_server_info($this->resource); return (isset($info->DB_NAME) ? $info->DB_NAME : ''); } /** * {@inheritDoc} */ public function connect() { if (is_resource($this->resource)) { return $this; } // localize $p = $this->connectionParameters; // given a list of key names, test for existence in $p $findParameterValue = function (array $names) use ($p) { foreach ($names as $name) { if (isset($p[$name])) { return $p[$name]; } } return; }; $database = $findParameterValue(['database', 'db']); $username = $findParameterValue(['username', 'uid', 'UID']); $password = $findParameterValue(['password', 'pwd', 'PWD']); $isPersistent = $findParameterValue(['persistent', 'PERSISTENT', 'Persistent']); $options = (isset($p['driver_options']) ? $p['driver_options'] : []); $connect = ((bool) $isPersistent) ? 'db2_pconnect' : 'db2_connect'; $this->resource = $connect($database, $username, $password, $options); if ($this->resource === false) { throw new Exception\RuntimeException(sprintf( '%s: Unable to connect to database', __METHOD__ )); } return $this; } /** * {@inheritDoc} */ public function isConnected() { return ($this->resource !== null); } /** * {@inheritDoc} */ public function disconnect() { if ($this->resource) { db2_close($this->resource); $this->resource = null; } return $this; } /** * {@inheritDoc} */ public function beginTransaction() { if ($this->isI5() && !ini_get('ibm_db2.i5_allow_commit')) { throw new Exception\RuntimeException( 'DB2 transactions are not enabled, you need to set the ibm_db2.i5_allow_commit=1 in your php.ini' ); } if (!$this->isConnected()) { $this->connect(); } $this->prevAutocommit = db2_autocommit($this->resource); db2_autocommit($this->resource, DB2_AUTOCOMMIT_OFF); $this->inTransaction = true; return $this; } /** * {@inheritDoc} */ public function commit() { if (!$this->isConnected()) { $this->connect(); } if (!db2_commit($this->resource)) { throw new Exception\RuntimeException("The commit has not been successful"); } if ($this->prevAutocommit) { db2_autocommit($this->resource, $this->prevAutocommit); } $this->inTransaction = false; return $this; } /** * Rollback * * @return Connection */ public function rollback() { if (!$this->isConnected()) { throw new Exception\RuntimeException('Must be connected before you can rollback.'); } if (!$this->inTransaction()) { throw new Exception\RuntimeException('Must call beginTransaction() before you can rollback.'); } if (!db2_rollback($this->resource)) { throw new Exception\RuntimeException('The rollback has not been successful'); } if ($this->prevAutocommit) { db2_autocommit($this->resource, $this->prevAutocommit); } $this->inTransaction = false; return $this; } /** * {@inheritDoc} */ public function execute($sql) { if (!$this->isConnected()) { $this->connect(); } if ($this->profiler) { $this->profiler->profilerStart($sql); } set_error_handler(function () {}, E_WARNING); // suppress warnings $resultResource = db2_exec($this->resource, $sql); restore_error_handler(); if ($this->profiler) { $this->profiler->profilerFinish($sql); } // if the returnValue is something other than a pg result resource, bypass wrapping it if ($resultResource === false) { throw new Exception\InvalidQueryException(db2_stmt_errormsg()); } return $this->driver->createResult(($resultResource === true) ? $this->resource : $resultResource); } /** * {@inheritDoc} */ public function getLastGeneratedValue($name = null) { return db2_last_insert_id($this->resource); } /** * Determine if the OS is OS400 (AS400, IBM i) * * @return bool */ protected function isI5() { if (isset($this->i5)) { return $this->i5; } $this->i5 = (php_uname('s') == 'OS400'); return $this->i5; } } zend-db-release-2.8.1/src/Adapter/Driver/IbmDb2/IbmDb2.php000066400000000000000000000126561270372430400227100ustar00rootroot00000000000000registerConnection($connection); $this->registerStatementPrototype(($statementPrototype) ?: new Statement()); $this->registerResultPrototype(($resultPrototype) ?: new Result()); } /** * @param Profiler\ProfilerInterface $profiler * @return IbmDb2 */ public function setProfiler(Profiler\ProfilerInterface $profiler) { $this->profiler = $profiler; if ($this->connection instanceof Profiler\ProfilerAwareInterface) { $this->connection->setProfiler($profiler); } if ($this->statementPrototype instanceof Profiler\ProfilerAwareInterface) { $this->statementPrototype->setProfiler($profiler); } return $this; } /** * @return null|Profiler\ProfilerInterface */ public function getProfiler() { return $this->profiler; } /** * @param Connection $connection * @return IbmDb2 */ public function registerConnection(Connection $connection) { $this->connection = $connection; $this->connection->setDriver($this); return $this; } /** * @param Statement $statementPrototype * @return IbmDb2 */ public function registerStatementPrototype(Statement $statementPrototype) { $this->statementPrototype = $statementPrototype; $this->statementPrototype->setDriver($this); return $this; } /** * @param Result $resultPrototype * @return IbmDb2 */ public function registerResultPrototype(Result $resultPrototype) { $this->resultPrototype = $resultPrototype; return $this; } /** * Get database platform name * * @param string $nameFormat * @return string */ public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE) { if ($nameFormat == self::NAME_FORMAT_CAMELCASE) { return 'IbmDb2'; } else { return 'IBM DB2'; } } /** * Check environment * * @return bool */ public function checkEnvironment() { if (!extension_loaded('ibm_db2')) { throw new Exception\RuntimeException('The ibm_db2 extension is required by this driver.'); } } /** * Get connection * * @return Connection */ public function getConnection() { return $this->connection; } /** * Create statement * * @param string|resource $sqlOrResource * @return Statement */ public function createStatement($sqlOrResource = null) { $statement = clone $this->statementPrototype; if (is_resource($sqlOrResource) && get_resource_type($sqlOrResource) == 'DB2 Statement') { $statement->setResource($sqlOrResource); } else { if (is_string($sqlOrResource)) { $statement->setSql($sqlOrResource); } elseif ($sqlOrResource !== null) { throw new Exception\InvalidArgumentException( __FUNCTION__ . ' only accepts an SQL string or an ibm_db2 resource' ); } if (!$this->connection->isConnected()) { $this->connection->connect(); } $statement->initialize($this->connection->getResource()); } return $statement; } /** * Create result * * @param resource $resource * @return Result */ public function createResult($resource) { $result = clone $this->resultPrototype; $result->initialize($resource, $this->connection->getLastGeneratedValue()); return $result; } /** * Get prepare type * * @return string */ public function getPrepareType() { return self::PARAMETERIZATION_POSITIONAL; } /** * Format parameter name * * @param string $name * @param mixed $type * @return string */ public function formatParameterName($name, $type = null) { return '?'; } /** * Get last generated value * * @return mixed */ public function getLastGeneratedValue() { return $this->connection->getLastGeneratedValue(); } } zend-db-release-2.8.1/src/Adapter/Driver/IbmDb2/Result.php000066400000000000000000000073011270372430400231160ustar00rootroot00000000000000resource = $resource; $this->generatedValue = $generatedValue; return $this; } /** * (PHP 5 >= 5.0.0)
* Return the current element * @link http://php.net/manual/en/iterator.current.php * @return mixed Can return any type. */ public function current() { if ($this->currentComplete) { return $this->currentData; } $this->currentData = db2_fetch_assoc($this->resource); return $this->currentData; } /** * @return mixed */ public function next() { $this->currentData = db2_fetch_assoc($this->resource); $this->currentComplete = true; $this->position++; return $this->currentData; } /** * @return int|string */ public function key() { return $this->position; } /** * @return bool */ public function valid() { return ($this->currentData !== false); } /** * (PHP 5 >= 5.0.0)
* Rewind the Iterator to the first element * @link http://php.net/manual/en/iterator.rewind.php * @return void Any returned value is ignored. */ public function rewind() { if ($this->position > 0) { throw new Exception\RuntimeException( 'This result is a forward only result set, calling rewind() after moving forward is not supported' ); } $this->currentData = db2_fetch_assoc($this->resource); $this->currentComplete = true; $this->position = 1; } /** * Force buffering * * @return void */ public function buffer() { return; } /** * Check if is buffered * * @return bool|null */ public function isBuffered() { return false; } /** * Is query result? * * @return bool */ public function isQueryResult() { return (db2_num_fields($this->resource) > 0); } /** * Get affected rows * * @return int */ public function getAffectedRows() { return db2_num_rows($this->resource); } /** * Get generated value * * @return mixed|null */ public function getGeneratedValue() { return $this->generatedValue; } /** * Get the resource * * @return mixed */ public function getResource() { return $this->resource; } /** * Get field count * * @return int */ public function getFieldCount() { return db2_num_fields($this->resource); } /** * @return null|int */ public function count() { return; } } zend-db-release-2.8.1/src/Adapter/Driver/IbmDb2/Statement.php000066400000000000000000000123241270372430400236050ustar00rootroot00000000000000db2 = $resource; return $this; } /** * @param IbmDb2 $driver * @return Statement */ public function setDriver(IbmDb2 $driver) { $this->driver = $driver; return $this; } /** * @param Profiler\ProfilerInterface $profiler * @return Statement */ public function setProfiler(Profiler\ProfilerInterface $profiler) { $this->profiler = $profiler; return $this; } /** * @return null|Profiler\ProfilerInterface */ public function getProfiler() { return $this->profiler; } /** * Set sql * * @param $sql * @return mixed */ public function setSql($sql) { $this->sql = $sql; return $this; } /** * Get sql * * @return mixed */ public function getSql() { return $this->sql; } /** * Set parameter container * * @param ParameterContainer $parameterContainer * @return mixed */ public function setParameterContainer(ParameterContainer $parameterContainer) { $this->parameterContainer = $parameterContainer; return $this; } /** * Get parameter container * * @return mixed */ public function getParameterContainer() { return $this->parameterContainer; } /** * @param $resource * @throws \Zend\Db\Adapter\Exception\InvalidArgumentException */ public function setResource($resource) { if (get_resource_type($resource) !== 'DB2 Statement') { throw new Exception\InvalidArgumentException('Resource must be of type DB2 Statement'); } $this->resource = $resource; } /** * Get resource * * @return resource */ public function getResource() { return $this->resource; } /** * Prepare sql * * @param string|null $sql * @return Statement */ public function prepare($sql = null) { if ($this->isPrepared) { throw new Exception\RuntimeException('This statement has been prepared already'); } if ($sql === null) { $sql = $this->sql; } $this->resource = db2_prepare($this->db2, $sql); if ($this->resource === false) { throw new Exception\RuntimeException(db2_stmt_errormsg(), db2_stmt_error()); } $this->isPrepared = true; return $this; } /** * Check if is prepared * * @return bool */ public function isPrepared() { return $this->isPrepared; } /** * Execute * * @param null|array|ParameterContainer $parameters * @return Result */ public function execute($parameters = null) { if (!$this->isPrepared) { $this->prepare(); } /** START Standard ParameterContainer Merging Block */ if (!$this->parameterContainer instanceof ParameterContainer) { if ($parameters instanceof ParameterContainer) { $this->parameterContainer = $parameters; $parameters = null; } else { $this->parameterContainer = new ParameterContainer(); } } if (is_array($parameters)) { $this->parameterContainer->setFromArray($parameters); } /** END Standard ParameterContainer Merging Block */ if ($this->profiler) { $this->profiler->profilerStart($this); } set_error_handler(function () {}, E_WARNING); // suppress warnings $response = db2_execute($this->resource, $this->parameterContainer->getPositionalArray()); restore_error_handler(); if ($this->profiler) { $this->profiler->profilerFinish(); } if ($response === false) { throw new Exception\RuntimeException(db2_stmt_errormsg($this->resource)); } $result = $this->driver->createResult($this->resource); return $result; } } zend-db-release-2.8.1/src/Adapter/Driver/Mysqli/000077500000000000000000000000001270372430400213455ustar00rootroot00000000000000zend-db-release-2.8.1/src/Adapter/Driver/Mysqli/Connection.php000066400000000000000000000144201270372430400241560ustar00rootroot00000000000000setConnectionParameters($connectionInfo); } elseif ($connectionInfo instanceof \mysqli) { $this->setResource($connectionInfo); } elseif (null !== $connectionInfo) { throw new Exception\InvalidArgumentException('$connection must be an array of parameters, a mysqli object or null'); } } /** * @param Mysqli $driver * @return self */ public function setDriver(Mysqli $driver) { $this->driver = $driver; return $this; } /** * {@inheritDoc} */ public function getCurrentSchema() { if (!$this->isConnected()) { $this->connect(); } /** @var $result \mysqli_result */ $result = $this->resource->query('SELECT DATABASE()'); $r = $result->fetch_row(); return $r[0]; } /** * Set resource * * @param \mysqli $resource * @return self */ public function setResource(\mysqli $resource) { $this->resource = $resource; return $this; } /** * {@inheritDoc} */ public function connect() { if ($this->resource instanceof \mysqli) { return $this; } // localize $p = $this->connectionParameters; // given a list of key names, test for existence in $p $findParameterValue = function (array $names) use ($p) { foreach ($names as $name) { if (isset($p[$name])) { return $p[$name]; } } return; }; $hostname = $findParameterValue(['hostname', 'host']); $username = $findParameterValue(['username', 'user']); $password = $findParameterValue(['password', 'passwd', 'pw']); $database = $findParameterValue(['database', 'dbname', 'db', 'schema']); $port = (isset($p['port'])) ? (int) $p['port'] : null; $socket = (isset($p['socket'])) ? $p['socket'] : null; $this->resource = new \mysqli(); $this->resource->init(); if (!empty($p['driver_options'])) { foreach ($p['driver_options'] as $option => $value) { if (is_string($option)) { $option = strtoupper($option); if (!defined($option)) { continue; } $option = constant($option); } $this->resource->options($option, $value); } } $this->resource->real_connect($hostname, $username, $password, $database, $port, $socket); if ($this->resource->connect_error) { throw new Exception\RuntimeException( 'Connection error', null, new Exception\ErrorException($this->resource->connect_error, $this->resource->connect_errno) ); } if (!empty($p['charset'])) { $this->resource->set_charset($p['charset']); } return $this; } /** * {@inheritDoc} */ public function isConnected() { return ($this->resource instanceof \mysqli); } /** * {@inheritDoc} */ public function disconnect() { if ($this->resource instanceof \mysqli) { $this->resource->close(); } $this->resource = null; } /** * {@inheritDoc} */ public function beginTransaction() { if (!$this->isConnected()) { $this->connect(); } $this->resource->autocommit(false); $this->inTransaction = true; return $this; } /** * {@inheritDoc} */ public function commit() { if (!$this->isConnected()) { $this->connect(); } $this->resource->commit(); $this->inTransaction = false; $this->resource->autocommit(true); return $this; } /** * {@inheritDoc} */ public function rollback() { if (!$this->isConnected()) { throw new Exception\RuntimeException('Must be connected before you can rollback.'); } if (!$this->inTransaction) { throw new Exception\RuntimeException('Must call beginTransaction() before you can rollback.'); } $this->resource->rollback(); $this->resource->autocommit(true); $this->inTransaction = false; return $this; } /** * {@inheritDoc} * * @throws Exception\InvalidQueryException */ public function execute($sql) { if (!$this->isConnected()) { $this->connect(); } if ($this->profiler) { $this->profiler->profilerStart($sql); } $resultResource = $this->resource->query($sql); if ($this->profiler) { $this->profiler->profilerFinish($sql); } // if the returnValue is something other than a mysqli_result, bypass wrapping it if ($resultResource === false) { throw new Exception\InvalidQueryException($this->resource->error); } $resultPrototype = $this->driver->createResult(($resultResource === true) ? $this->resource : $resultResource); return $resultPrototype; } /** * {@inheritDoc} */ public function getLastGeneratedValue($name = null) { return $this->resource->insert_id; } } zend-db-release-2.8.1/src/Adapter/Driver/Mysqli/Mysqli.php000066400000000000000000000143751270372430400233460ustar00rootroot00000000000000 false ]; /** * Constructor * * @param array|Connection|\mysqli $connection * @param null|Statement $statementPrototype * @param null|Result $resultPrototype * @param array $options */ public function __construct($connection, Statement $statementPrototype = null, Result $resultPrototype = null, array $options = []) { if (!$connection instanceof Connection) { $connection = new Connection($connection); } $options = array_intersect_key(array_merge($this->options, $options), $this->options); $this->registerConnection($connection); $this->registerStatementPrototype(($statementPrototype) ?: new Statement($options['buffer_results'])); $this->registerResultPrototype(($resultPrototype) ?: new Result()); } /** * @param Profiler\ProfilerInterface $profiler * @return Mysqli */ public function setProfiler(Profiler\ProfilerInterface $profiler) { $this->profiler = $profiler; if ($this->connection instanceof Profiler\ProfilerAwareInterface) { $this->connection->setProfiler($profiler); } if ($this->statementPrototype instanceof Profiler\ProfilerAwareInterface) { $this->statementPrototype->setProfiler($profiler); } return $this; } /** * @return null|Profiler\ProfilerInterface */ public function getProfiler() { return $this->profiler; } /** * Register connection * * @param Connection $connection * @return Mysqli */ public function registerConnection(Connection $connection) { $this->connection = $connection; $this->connection->setDriver($this); // needs access to driver to createStatement() return $this; } /** * Register statement prototype * * @param Statement $statementPrototype */ public function registerStatementPrototype(Statement $statementPrototype) { $this->statementPrototype = $statementPrototype; $this->statementPrototype->setDriver($this); // needs access to driver to createResult() } /** * Get statement prototype * * @return null|Statement */ public function getStatementPrototype() { return $this->statementPrototype; } /** * Register result prototype * * @param Result $resultPrototype */ public function registerResultPrototype(Result $resultPrototype) { $this->resultPrototype = $resultPrototype; } /** * @return null|Result */ public function getResultPrototype() { return $this->resultPrototype; } /** * Get database platform name * * @param string $nameFormat * @return string */ public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE) { if ($nameFormat == self::NAME_FORMAT_CAMELCASE) { return 'Mysql'; } return 'MySQL'; } /** * Check environment * * @throws Exception\RuntimeException * @return void */ public function checkEnvironment() { if (!extension_loaded('mysqli')) { throw new Exception\RuntimeException('The Mysqli extension is required for this adapter but the extension is not loaded'); } } /** * Get connection * * @return Connection */ public function getConnection() { return $this->connection; } /** * Create statement * * @param string $sqlOrResource * @return Statement */ public function createStatement($sqlOrResource = null) { /** * @todo Resource tracking if (is_resource($sqlOrResource) && !in_array($sqlOrResource, $this->resources, true)) { $this->resources[] = $sqlOrResource; } */ $statement = clone $this->statementPrototype; if ($sqlOrResource instanceof mysqli_stmt) { $statement->setResource($sqlOrResource); } else { if (is_string($sqlOrResource)) { $statement->setSql($sqlOrResource); } if (!$this->connection->isConnected()) { $this->connection->connect(); } $statement->initialize($this->connection->getResource()); } return $statement; } /** * Create result * * @param resource $resource * @param null|bool $isBuffered * @return Result */ public function createResult($resource, $isBuffered = null) { $result = clone $this->resultPrototype; $result->initialize($resource, $this->connection->getLastGeneratedValue(), $isBuffered); return $result; } /** * Get prepare type * * @return string */ public function getPrepareType() { return self::PARAMETERIZATION_POSITIONAL; } /** * Format parameter name * * @param string $name * @param mixed $type * @return string */ public function formatParameterName($name, $type = null) { return '?'; } /** * Get last generated value * * @return mixed */ public function getLastGeneratedValue() { return $this->getConnection()->getLastGeneratedValue(); } } zend-db-release-2.8.1/src/Adapter/Driver/Mysqli/Result.php000066400000000000000000000200511270372430400233320ustar00rootroot00000000000000 null, 'values' => []]; /** * @var mixed */ protected $generatedValue = null; /** * Initialize * * @param mixed $resource * @param mixed $generatedValue * @param bool|null $isBuffered * @throws Exception\InvalidArgumentException * @return Result */ public function initialize($resource, $generatedValue, $isBuffered = null) { if (!$resource instanceof \mysqli && !$resource instanceof \mysqli_result && !$resource instanceof \mysqli_stmt) { throw new Exception\InvalidArgumentException('Invalid resource provided.'); } if ($isBuffered !== null) { $this->isBuffered = $isBuffered; } else { if ($resource instanceof \mysqli || $resource instanceof \mysqli_result || $resource instanceof \mysqli_stmt && $resource->num_rows != 0) { $this->isBuffered = true; } } $this->resource = $resource; $this->generatedValue = $generatedValue; return $this; } /** * Force buffering * * @throws Exception\RuntimeException */ public function buffer() { if ($this->resource instanceof \mysqli_stmt && $this->isBuffered !== true) { if ($this->position > 0) { throw new Exception\RuntimeException('Cannot buffer a result set that has started iteration.'); } $this->resource->store_result(); $this->isBuffered = true; } } /** * Check if is buffered * * @return bool|null */ public function isBuffered() { return $this->isBuffered; } /** * Return the resource * * @return mixed */ public function getResource() { return $this->resource; } /** * Is query result? * * @return bool */ public function isQueryResult() { return ($this->resource->field_count > 0); } /** * Get affected rows * * @return int */ public function getAffectedRows() { if ($this->resource instanceof \mysqli || $this->resource instanceof \mysqli_stmt) { return $this->resource->affected_rows; } return $this->resource->num_rows; } /** * Current * * @return mixed */ public function current() { if ($this->currentComplete) { return $this->currentData; } if ($this->resource instanceof \mysqli_stmt) { $this->loadDataFromMysqliStatement(); return $this->currentData; } else { $this->loadFromMysqliResult(); return $this->currentData; } } /** * Mysqli's binding and returning of statement values * * Mysqli requires you to bind variables to the extension in order to * get data out. These values have to be references: * @see http://php.net/manual/en/mysqli-stmt.bind-result.php * * @throws Exception\RuntimeException * @return bool */ protected function loadDataFromMysqliStatement() { // build the default reference based bind structure, if it does not already exist if ($this->statementBindValues['keys'] === null) { $this->statementBindValues['keys'] = []; $resultResource = $this->resource->result_metadata(); foreach ($resultResource->fetch_fields() as $col) { $this->statementBindValues['keys'][] = $col->name; } $this->statementBindValues['values'] = array_fill(0, count($this->statementBindValues['keys']), null); $refs = []; foreach ($this->statementBindValues['values'] as $i => &$f) { $refs[$i] = &$f; } call_user_func_array([$this->resource, 'bind_result'], $this->statementBindValues['values']); } if (($r = $this->resource->fetch()) === null) { if (!$this->isBuffered) { $this->resource->close(); } return false; } elseif ($r === false) { throw new Exception\RuntimeException($this->resource->error); } // dereference for ($i = 0, $count = count($this->statementBindValues['keys']); $i < $count; $i++) { $this->currentData[$this->statementBindValues['keys'][$i]] = $this->statementBindValues['values'][$i]; } $this->currentComplete = true; $this->nextComplete = true; $this->position++; return true; } /** * Load from mysqli result * * @return bool */ protected function loadFromMysqliResult() { $this->currentData = null; if (($data = $this->resource->fetch_assoc()) === null) { return false; } $this->position++; $this->currentData = $data; $this->currentComplete = true; $this->nextComplete = true; $this->position++; return true; } /** * Next * * @return void */ public function next() { $this->currentComplete = false; if ($this->nextComplete == false) { $this->position++; } $this->nextComplete = false; } /** * Key * * @return mixed */ public function key() { return $this->position; } /** * Rewind * * @throws Exception\RuntimeException * @return void */ public function rewind() { if ($this->position !== 0) { if ($this->isBuffered === false) { throw new Exception\RuntimeException('Unbuffered results cannot be rewound for multiple iterations'); } } $this->resource->data_seek(0); // works for both mysqli_result & mysqli_stmt $this->currentComplete = false; $this->position = 0; } /** * Valid * * @return bool */ public function valid() { if ($this->currentComplete) { return true; } if ($this->resource instanceof \mysqli_stmt) { return $this->loadDataFromMysqliStatement(); } return $this->loadFromMysqliResult(); } /** * Count * * @throws Exception\RuntimeException * @return int */ public function count() { if ($this->isBuffered === false) { throw new Exception\RuntimeException('Row count is not available in unbuffered result sets.'); } return $this->resource->num_rows; } /** * Get field count * * @return int */ public function getFieldCount() { return $this->resource->field_count; } /** * Get generated value * * @return mixed|null */ public function getGeneratedValue() { return $this->generatedValue; } } zend-db-release-2.8.1/src/Adapter/Driver/Mysqli/Statement.php000066400000000000000000000163171270372430400240320ustar00rootroot00000000000000bufferResults = (bool) $bufferResults; } /** * Set driver * * @param Mysqli $driver * @return Statement */ public function setDriver(Mysqli $driver) { $this->driver = $driver; return $this; } /** * @param Profiler\ProfilerInterface $profiler * @return Statement */ public function setProfiler(Profiler\ProfilerInterface $profiler) { $this->profiler = $profiler; return $this; } /** * @return null|Profiler\ProfilerInterface */ public function getProfiler() { return $this->profiler; } /** * Initialize * * @param \mysqli $mysqli * @return Statement */ public function initialize(\mysqli $mysqli) { $this->mysqli = $mysqli; return $this; } /** * Set sql * * @param string $sql * @return Statement */ public function setSql($sql) { $this->sql = $sql; return $this; } /** * Set Parameter container * * @param ParameterContainer $parameterContainer * @return Statement */ public function setParameterContainer(ParameterContainer $parameterContainer) { $this->parameterContainer = $parameterContainer; return $this; } /** * Get resource * * @return mixed */ public function getResource() { return $this->resource; } /** * Set resource * * @param \mysqli_stmt $mysqliStatement * @return Statement */ public function setResource(\mysqli_stmt $mysqliStatement) { $this->resource = $mysqliStatement; $this->isPrepared = true; return $this; } /** * Get sql * * @return string */ public function getSql() { return $this->sql; } /** * Get parameter count * * @return ParameterContainer */ public function getParameterContainer() { return $this->parameterContainer; } /** * Is prepared * * @return bool */ public function isPrepared() { return $this->isPrepared; } /** * Prepare * * @param string $sql * @throws Exception\InvalidQueryException * @throws Exception\RuntimeException * @return Statement */ public function prepare($sql = null) { if ($this->isPrepared) { throw new Exception\RuntimeException('This statement has already been prepared'); } $sql = ($sql) ?: $this->sql; $this->resource = $this->mysqli->prepare($sql); if (!$this->resource instanceof \mysqli_stmt) { throw new Exception\InvalidQueryException( 'Statement couldn\'t be produced with sql: ' . $sql, null, new Exception\ErrorException($this->mysqli->error, $this->mysqli->errno) ); } $this->isPrepared = true; return $this; } /** * Execute * * @param null|array|ParameterContainer $parameters * @throws Exception\RuntimeException * @return mixed */ public function execute($parameters = null) { if (!$this->isPrepared) { $this->prepare(); } /** START Standard ParameterContainer Merging Block */ if (!$this->parameterContainer instanceof ParameterContainer) { if ($parameters instanceof ParameterContainer) { $this->parameterContainer = $parameters; $parameters = null; } else { $this->parameterContainer = new ParameterContainer(); } } if (is_array($parameters)) { $this->parameterContainer->setFromArray($parameters); } if ($this->parameterContainer->count() > 0) { $this->bindParametersFromContainer(); } /** END Standard ParameterContainer Merging Block */ if ($this->profiler) { $this->profiler->profilerStart($this); } $return = $this->resource->execute(); if ($this->profiler) { $this->profiler->profilerFinish(); } if ($return === false) { throw new Exception\RuntimeException($this->resource->error); } if ($this->bufferResults === true) { $this->resource->store_result(); $this->isPrepared = false; $buffered = true; } else { $buffered = false; } $result = $this->driver->createResult($this->resource, $buffered); return $result; } /** * Bind parameters from container * * @return void */ protected function bindParametersFromContainer() { $parameters = $this->parameterContainer->getNamedArray(); $type = ''; $args = []; foreach ($parameters as $name => &$value) { if ($this->parameterContainer->offsetHasErrata($name)) { switch ($this->parameterContainer->offsetGetErrata($name)) { case ParameterContainer::TYPE_DOUBLE: $type .= 'd'; break; case ParameterContainer::TYPE_NULL: $value = null; // as per @see http://www.php.net/manual/en/mysqli-stmt.bind-param.php#96148 case ParameterContainer::TYPE_INTEGER: $type .= 'i'; break; case ParameterContainer::TYPE_STRING: default: $type .= 's'; break; } } else { $type .= 's'; } $args[] = &$value; } if ($args) { array_unshift($args, $type); call_user_func_array([$this->resource, 'bind_param'], $args); } } } zend-db-release-2.8.1/src/Adapter/Driver/Oci8/000077500000000000000000000000001270372430400206715ustar00rootroot00000000000000zend-db-release-2.8.1/src/Adapter/Driver/Oci8/Connection.php000066400000000000000000000155571270372430400235160ustar00rootroot00000000000000setConnectionParameters($connectionInfo); } elseif ($connectionInfo instanceof \oci8) { $this->setResource($connectionInfo); } elseif (null !== $connectionInfo) { throw new Exception\InvalidArgumentException('$connection must be an array of parameters, an oci8 resource or null'); } } /** * @param Oci8 $driver * @return self */ public function setDriver(Oci8 $driver) { $this->driver = $driver; return $this; } /** * {@inheritDoc} */ public function getCurrentSchema() { if (!$this->isConnected()) { $this->connect(); } $query = "SELECT sys_context('USERENV', 'CURRENT_SCHEMA') as \"current_schema\" FROM DUAL"; $stmt = oci_parse($this->resource, $query); oci_execute($stmt); $dbNameArray = oci_fetch_array($stmt, OCI_ASSOC); return $dbNameArray['current_schema']; } /** * Set resource * * @param resource $resource * @return self */ public function setResource($resource) { if (!is_resource($resource) || get_resource_type($resource) !== 'oci8 connection') { throw new Exception\InvalidArgumentException('A resource of type "oci8 connection" was expected'); } $this->resource = $resource; return $this; } /** * {@inheritDoc} */ public function connect() { if (is_resource($this->resource)) { return $this; } // localize $p = $this->connectionParameters; // given a list of key names, test for existence in $p $findParameterValue = function (array $names) use ($p) { foreach ($names as $name) { if (isset($p[$name])) { return $p[$name]; } } return; }; // http://www.php.net/manual/en/function.oci-connect.php $username = $findParameterValue(['username']); $password = $findParameterValue(['password']); $connectionString = $findParameterValue(['connection_string', 'connectionstring', 'connection', 'hostname', 'instance']); $characterSet = $findParameterValue(['character_set', 'charset', 'encoding']); $sessionMode = $findParameterValue(['session_mode']); // connection modifiers $isUnique = $findParameterValue(['unique']); $isPersistent = $findParameterValue(['persistent']); if ($isUnique == true) { $this->resource = oci_new_connect($username, $password, $connectionString, $characterSet, $sessionMode); } elseif ($isPersistent == true) { $this->resource = oci_pconnect($username, $password, $connectionString, $characterSet, $sessionMode); } else { $this->resource = oci_connect($username, $password, $connectionString, $characterSet, $sessionMode); } if (!$this->resource) { $e = oci_error(); throw new Exception\RuntimeException( 'Connection error', null, new Exception\ErrorException($e['message'], $e['code']) ); } return $this; } /** * {@inheritDoc} */ public function isConnected() { return (is_resource($this->resource)); } /** * {@inheritDoc} */ public function disconnect() { if (is_resource($this->resource)) { oci_close($this->resource); } } /** * {@inheritDoc} */ public function beginTransaction() { if (!$this->isConnected()) { $this->connect(); } // A transaction begins when the first SQL statement that changes data is executed with oci_execute() using the OCI_NO_AUTO_COMMIT flag. $this->inTransaction = true; return $this; } /** * {@inheritDoc} */ public function commit() { if (!$this->isConnected()) { $this->connect(); } if ($this->inTransaction()) { $valid = oci_commit($this->resource); if ($valid === false) { $e = oci_error($this->resource); throw new Exception\InvalidQueryException($e['message'], $e['code']); } $this->inTransaction = false; } return $this; } /** * {@inheritDoc} */ public function rollback() { if (!$this->isConnected()) { throw new Exception\RuntimeException('Must be connected before you can rollback.'); } if (!$this->inTransaction()) { throw new Exception\RuntimeException('Must call commit() before you can rollback.'); } $valid = oci_rollback($this->resource); if ($valid === false) { $e = oci_error($this->resource); throw new Exception\InvalidQueryException($e['message'], $e['code']); } $this->inTransaction = false; return $this; } /** * {@inheritDoc} */ public function execute($sql) { if (!$this->isConnected()) { $this->connect(); } if ($this->profiler) { $this->profiler->profilerStart($sql); } $ociStmt = oci_parse($this->resource, $sql); if ($this->inTransaction) { $valid = @oci_execute($ociStmt, OCI_NO_AUTO_COMMIT); } else { $valid = @oci_execute($ociStmt, OCI_COMMIT_ON_SUCCESS); } if ($this->profiler) { $this->profiler->profilerFinish($sql); } if ($valid === false) { $e = oci_error($ociStmt); throw new Exception\InvalidQueryException($e['message'], $e['code']); } $resultPrototype = $this->driver->createResult($ociStmt); return $resultPrototype; } /** * {@inheritDoc} */ public function getLastGeneratedValue($name = null) { // @todo Get Last Generated Value in Connection (this might not apply) return; } } zend-db-release-2.8.1/src/Adapter/Driver/Oci8/Feature/000077500000000000000000000000001270372430400222645ustar00rootroot00000000000000zend-db-release-2.8.1/src/Adapter/Driver/Oci8/Feature/RowCounter.php000066400000000000000000000041171270372430400251070ustar00rootroot00000000000000getSql(); if ($sql == '' || stripos(strtolower($sql), 'select') === false) { return; } $countSql = 'SELECT COUNT(*) as "count" FROM (' . $sql . ')'; $countStmt->prepare($countSql); $result = $countStmt->execute(); $countRow = $result->current(); return $countRow['count']; } /** * @param string $sql * @return null|int */ public function getCountForSql($sql) { if (stripos(strtolower($sql), 'select') === false) { return; } $countSql = 'SELECT COUNT(*) as "count" FROM (' . $sql . ')'; $result = $this->driver->getConnection()->execute($countSql); $countRow = $result->current(); return $countRow['count']; } /** * @param \Zend\Db\Adapter\Driver\Oci8\Statement|string $context * @return callable */ public function getRowCountClosure($context) { $rowCounter = $this; return function () use ($rowCounter, $context) { /** @var $rowCounter RowCounter */ return ($context instanceof Statement) ? $rowCounter->getCountForStatement($context) : $rowCounter->getCountForSql($context); }; } } zend-db-release-2.8.1/src/Adapter/Driver/Oci8/Oci8.php000066400000000000000000000172131270372430400222100ustar00rootroot00000000000000options, $options), $this->options); $this->registerConnection($connection); $this->registerStatementPrototype(($statementPrototype) ?: new Statement()); $this->registerResultPrototype(($resultPrototype) ?: new Result()); if (is_array($features)) { foreach ($features as $name => $feature) { $this->addFeature($name, $feature); } } elseif ($features instanceof AbstractFeature) { $this->addFeature($features->getName(), $features); } elseif ($features === self::FEATURES_DEFAULT) { $this->setupDefaultFeatures(); } } /** * @param Profiler\ProfilerInterface $profiler * @return Oci8 */ public function setProfiler(Profiler\ProfilerInterface $profiler) { $this->profiler = $profiler; if ($this->connection instanceof Profiler\ProfilerAwareInterface) { $this->connection->setProfiler($profiler); } if ($this->statementPrototype instanceof Profiler\ProfilerAwareInterface) { $this->statementPrototype->setProfiler($profiler); } return $this; } /** * @return null|Profiler\ProfilerInterface */ public function getProfiler() { return $this->profiler; } /** * Register connection * * @param Connection $connection * @return Oci8 */ public function registerConnection(Connection $connection) { $this->connection = $connection; $this->connection->setDriver($this); // needs access to driver to createStatement() return $this; } /** * Register statement prototype * * @param Statement $statementPrototype * @return Oci8 */ public function registerStatementPrototype(Statement $statementPrototype) { $this->statementPrototype = $statementPrototype; $this->statementPrototype->setDriver($this); // needs access to driver to createResult() return $this; } /** * @return null|Statement */ public function getStatementPrototype() { return $this->statementPrototype; } /** * Register result prototype * * @param Result $resultPrototype * @return Oci8 */ public function registerResultPrototype(Result $resultPrototype) { $this->resultPrototype = $resultPrototype; return $this; } /** * @return null|Result */ public function getResultPrototype() { return $this->resultPrototype; } /** * Add feature * * @param string $name * @param AbstractFeature $feature * @return self */ public function addFeature($name, $feature) { if ($feature instanceof AbstractFeature) { $name = $feature->getName(); // overwrite the name, just in case $feature->setDriver($this); } $this->features[$name] = $feature; return $this; } /** * Setup the default features for Pdo * * @return self */ public function setupDefaultFeatures() { $this->addFeature(null, new Feature\RowCounter()); return $this; } /** * Get feature * * @param string $name * @return AbstractFeature|false */ public function getFeature($name) { if (isset($this->features[$name])) { return $this->features[$name]; } return false; } /** * Get database platform name * * @param string $nameFormat * @return string */ public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE) { return 'Oracle'; } /** * Check environment */ public function checkEnvironment() { if (!extension_loaded('oci8')) { throw new Exception\RuntimeException( 'The Oci8 extension is required for this adapter but the extension is not loaded' ); } } /** * @return Connection */ public function getConnection() { return $this->connection; } /** * @param string $sqlOrResource * @return Statement */ public function createStatement($sqlOrResource = null) { $statement = clone $this->statementPrototype; if (is_resource($sqlOrResource) && get_resource_type($sqlOrResource) == 'oci8 statement') { $statement->setResource($sqlOrResource); } else { if (is_string($sqlOrResource)) { $statement->setSql($sqlOrResource); } elseif ($sqlOrResource !== null) { throw new Exception\InvalidArgumentException( 'Oci8 only accepts an SQL string or an oci8 resource in ' . __FUNCTION__ ); } if (!$this->connection->isConnected()) { $this->connection->connect(); } $statement->initialize($this->connection->getResource()); } return $statement; } /** * @param resource $resource * @param null $context * @return Result */ public function createResult($resource, $context = null) { $result = clone $this->resultPrototype; $rowCount = null; // special feature, oracle Oci counter if ($context && ($rowCounter = $this->getFeature('RowCounter')) && oci_num_fields($resource) > 0) { $rowCount = $rowCounter->getRowCountClosure($context); } $result->initialize($resource, null, $rowCount); return $result; } /** * @return string */ public function getPrepareType() { return self::PARAMETERIZATION_NAMED; } /** * @param string $name * @param mixed $type * @return string */ public function formatParameterName($name, $type = null) { return ':' . $name; } /** * @return mixed */ public function getLastGeneratedValue() { return $this->getConnection()->getLastGeneratedValue(); } } zend-db-release-2.8.1/src/Adapter/Driver/Oci8/Result.php000066400000000000000000000110121270372430400226530ustar00rootroot00000000000000 null, 'values' => []]; /** * @var mixed */ protected $generatedValue = null; /** * Initialize * @param resource $resource * @param null|int $generatedValue * @param null|int $rowCount * @return Result */ public function initialize($resource, $generatedValue = null, $rowCount = null) { if (!is_resource($resource) && get_resource_type($resource) !== 'oci8 statement') { throw new Exception\InvalidArgumentException('Invalid resource provided.'); } $this->resource = $resource; $this->generatedValue = $generatedValue; $this->rowCount = $rowCount; return $this; } /** * Force buffering at driver level * * Oracle does not support this, to my knowledge (@ralphschindler) * * @throws Exception\RuntimeException */ public function buffer() { return; } /** * Is the result buffered? * * @return bool */ public function isBuffered() { return false; } /** * Return the resource * @return mixed */ public function getResource() { return $this->resource; } /** * Is query result? * * @return bool */ public function isQueryResult() { return (oci_num_fields($this->resource) > 0); } /** * Get affected rows * @return int */ public function getAffectedRows() { return oci_num_rows($this->resource); } /** * Current * @return mixed */ public function current() { if ($this->currentComplete == false) { if ($this->loadData() === false) { return false; } } return $this->currentData; } /** * Load from oci8 result * * @return bool */ protected function loadData() { $this->currentComplete = true; $this->currentData = oci_fetch_assoc($this->resource); if ($this->currentData !== false) { $this->position++; return true; } return false; } /** * Next */ public function next() { return $this->loadData(); } /** * Key * @return mixed */ public function key() { return $this->position; } /** * Rewind */ public function rewind() { if ($this->position > 0) { throw new Exception\RuntimeException('Oci8 results cannot be rewound for multiple iterations'); } } /** * Valid * @return bool */ public function valid() { if ($this->currentComplete) { return ($this->currentData !== false); } return $this->loadData(); } /** * Count * @return null|int */ public function count() { if (is_int($this->rowCount)) { return $this->rowCount; } if (is_callable($this->rowCount)) { $this->rowCount = (int) call_user_func($this->rowCount); return $this->rowCount; } return; } /** * @return int */ public function getFieldCount() { return oci_num_fields($this->resource); } /** * @return null */ public function getGeneratedValue() { // @todo OCI8 generated value in Driver Result return; } } zend-db-release-2.8.1/src/Adapter/Driver/Oci8/Statement.php000066400000000000000000000200221270372430400233420ustar00rootroot00000000000000driver = $driver; return $this; } /** * @param Profiler\ProfilerInterface $profiler * @return Statement */ public function setProfiler(Profiler\ProfilerInterface $profiler) { $this->profiler = $profiler; return $this; } /** * @return null|Profiler\ProfilerInterface */ public function getProfiler() { return $this->profiler; } /** * Initialize * * @param resource $oci8 * @return Statement */ public function initialize($oci8) { $this->oci8 = $oci8; return $this; } /** * Set sql * * @param string $sql * @return Statement */ public function setSql($sql) { $this->sql = $sql; return $this; } /** * Set Parameter container * * @param ParameterContainer $parameterContainer * @return Statement */ public function setParameterContainer(ParameterContainer $parameterContainer) { $this->parameterContainer = $parameterContainer; return $this; } /** * Get resource * * @return mixed */ public function getResource() { return $this->resource; } /** * Set resource * * @param resource $oci8Statement * @return Statement */ public function setResource($oci8Statement) { $type = oci_statement_type($oci8Statement); if (false === $type || 'UNKNOWN' == $type) { throw new Exception\InvalidArgumentException(sprintf( 'Invalid statement provided to %s', __METHOD__ )); } $this->resource = $oci8Statement; $this->isPrepared = true; return $this; } /** * Get sql * * @return string */ public function getSql() { return $this->sql; } /** * @return ParameterContainer */ public function getParameterContainer() { return $this->parameterContainer; } /** * @return bool */ public function isPrepared() { return $this->isPrepared; } /** * @param string $sql * @return Statement */ public function prepare($sql = null) { if ($this->isPrepared) { throw new Exception\RuntimeException('This statement has already been prepared'); } $sql = ($sql) ?: $this->sql; // get oci8 statement resource $this->resource = oci_parse($this->oci8, $sql); if (!$this->resource) { $e = oci_error($this->oci8); throw new Exception\InvalidQueryException( 'Statement couldn\'t be produced with sql: ' . $sql, null, new Exception\ErrorException($e['message'], $e['code']) ); } $this->isPrepared = true; return $this; } /** * Execute * * @param null|array|ParameterContainer $parameters * @return mixed */ public function execute($parameters = null) { if (!$this->isPrepared) { $this->prepare(); } /** START Standard ParameterContainer Merging Block */ if (!$this->parameterContainer instanceof ParameterContainer) { if ($parameters instanceof ParameterContainer) { $this->parameterContainer = $parameters; $parameters = null; } else { $this->parameterContainer = new ParameterContainer(); } } if (is_array($parameters)) { $this->parameterContainer->setFromArray($parameters); } if ($this->parameterContainer->count() > 0) { $this->bindParametersFromContainer(); } /** END Standard ParameterContainer Merging Block */ if ($this->profiler) { $this->profiler->profilerStart($this); } if ($this->driver->getConnection()->inTransaction()) { $ret = @oci_execute($this->resource, OCI_NO_AUTO_COMMIT); } else { $ret = @oci_execute($this->resource, OCI_COMMIT_ON_SUCCESS); } if ($this->profiler) { $this->profiler->profilerFinish(); } if ($ret === false) { $e = oci_error($this->resource); throw new Exception\RuntimeException($e['message'], $e['code']); } $result = $this->driver->createResult($this->resource, $this); return $result; } /** * Bind parameters from container * * @param ParameterContainer $pContainer */ protected function bindParametersFromContainer() { $parameters = $this->parameterContainer->getNamedArray(); foreach ($parameters as $name => &$value) { if ($this->parameterContainer->offsetHasErrata($name)) { switch ($this->parameterContainer->offsetGetErrata($name)) { case ParameterContainer::TYPE_NULL: $type = null; $value = null; break; case ParameterContainer::TYPE_DOUBLE: case ParameterContainer::TYPE_INTEGER: $type = SQLT_INT; if (is_string($value)) { $value = (int) $value; } break; case ParameterContainer::TYPE_BINARY: $type = SQLT_BIN; break; case ParameterContainer::TYPE_LOB: $type = OCI_B_CLOB; $clob = oci_new_descriptor($this->driver->getConnection()->getResource(), OCI_DTYPE_LOB); $clob->writetemporary($value, OCI_TEMP_CLOB); $value = $clob; break; case ParameterContainer::TYPE_STRING: default: $type = SQLT_CHR; break; } } else { $type = SQLT_CHR; } $maxLength = -1; if ($this->parameterContainer->offsetHasMaxLength($name)) { $maxLength = $this->parameterContainer->offsetGetMaxLength($name); } oci_bind_by_name($this->resource, $name, $value, $maxLength, $type); } } /** * Perform a deep clone */ public function __clone() { $this->isPrepared = false; $this->parametersBound = false; $this->resource = null; if ($this->parameterContainer) { $this->parameterContainer = clone $this->parameterContainer; } } } zend-db-release-2.8.1/src/Adapter/Driver/Pdo/000077500000000000000000000000001270372430400206115ustar00rootroot00000000000000zend-db-release-2.8.1/src/Adapter/Driver/Pdo/Connection.php000066400000000000000000000271721270372430400234320ustar00rootroot00000000000000setConnectionParameters($connectionParameters); } elseif ($connectionParameters instanceof \PDO) { $this->setResource($connectionParameters); } elseif (null !== $connectionParameters) { throw new Exception\InvalidArgumentException( '$connection must be an array of parameters, a PDO object or null' ); } } /** * Set driver * * @param Pdo $driver * @return self */ public function setDriver(Pdo $driver) { $this->driver = $driver; return $this; } /** * {@inheritDoc} */ public function setConnectionParameters(array $connectionParameters) { $this->connectionParameters = $connectionParameters; if (isset($connectionParameters['dsn'])) { $this->driverName = substr( $connectionParameters['dsn'], 0, strpos($connectionParameters['dsn'], ':') ); } elseif (isset($connectionParameters['pdodriver'])) { $this->driverName = strtolower($connectionParameters['pdodriver']); } elseif (isset($connectionParameters['driver'])) { $this->driverName = strtolower(substr( str_replace(['-', '_', ' '], '', $connectionParameters['driver']), 3 )); } } /** * Get the dsn string for this connection * @throws \Zend\Db\Adapter\Exception\RunTimeException * @return string */ public function getDsn() { if (!$this->dsn) { throw new Exception\RunTimeException( 'The DSN has not been set or constructed from parameters in connect() for this Connection' ); } return $this->dsn; } /** * {@inheritDoc} */ public function getCurrentSchema() { if (!$this->isConnected()) { $this->connect(); } switch ($this->driverName) { case 'mysql': $sql = 'SELECT DATABASE()'; break; case 'sqlite': return 'main'; case 'sqlsrv': case 'dblib': $sql = 'SELECT SCHEMA_NAME()'; break; case 'pgsql': default: $sql = 'SELECT CURRENT_SCHEMA'; break; } /** @var $result \PDOStatement */ $result = $this->resource->query($sql); if ($result instanceof \PDOStatement) { return $result->fetchColumn(); } return false; } /** * Set resource * * @param \PDO $resource * @return self */ public function setResource(\PDO $resource) { $this->resource = $resource; $this->driverName = strtolower($this->resource->getAttribute(\PDO::ATTR_DRIVER_NAME)); return $this; } /** * {@inheritDoc} * * @throws Exception\InvalidConnectionParametersException * @throws Exception\RuntimeException */ public function connect() { if ($this->resource) { return $this; } $dsn = $username = $password = $hostname = $database = null; $options = []; foreach ($this->connectionParameters as $key => $value) { switch (strtolower($key)) { case 'dsn': $dsn = $value; break; case 'driver': $value = strtolower((string) $value); if (strpos($value, 'pdo') === 0) { $pdoDriver = str_replace(['-', '_', ' '], '', $value); $pdoDriver = substr($pdoDriver, 3) ?: ''; $pdoDriver = strtolower($pdoDriver); } break; case 'pdodriver': $pdoDriver = (string) $value; break; case 'user': case 'username': $username = (string) $value; break; case 'pass': case 'password': $password = (string) $value; break; case 'host': case 'hostname': $hostname = (string) $value; break; case 'port': $port = (int) $value; break; case 'database': case 'dbname': $database = (string) $value; break; case 'charset': $charset = (string) $value; break; case 'unix_socket': $unix_socket = (string) $value; break; case 'driver_options': case 'options': $value = (array) $value; $options = array_diff_key($options, $value) + $value; break; default: $options[$key] = $value; break; } } if (isset($hostname) && isset($unix_socket)) { throw new Exception\InvalidConnectionParametersException( 'Ambiguous connection parameters, both hostname and unix_socket parameters were set', $this->connectionParameters ); } if (!isset($dsn) && isset($pdoDriver)) { $dsn = []; switch ($pdoDriver) { case 'sqlite': $dsn[] = $database; break; case 'sqlsrv': if (isset($database)) { $dsn[] = "database={$database}"; } if (isset($hostname)) { $dsn[] = "server={$hostname}"; } break; default: if (isset($database)) { $dsn[] = "dbname={$database}"; } if (isset($hostname)) { $dsn[] = "host={$hostname}"; } if (isset($port)) { $dsn[] = "port={$port}"; } if (isset($charset) && $pdoDriver != 'pgsql') { $dsn[] = "charset={$charset}"; } if (isset($unix_socket)) { $dsn[] = "unix_socket={$unix_socket}"; } break; } $dsn = $pdoDriver . ':' . implode(';', $dsn); } elseif (!isset($dsn)) { throw new Exception\InvalidConnectionParametersException( 'A dsn was not provided or could not be constructed from your parameters', $this->connectionParameters ); } $this->dsn = $dsn; try { $this->resource = new \PDO($dsn, $username, $password, $options); $this->resource->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); if (isset($charset) && $pdoDriver == 'pgsql') { $this->resource->exec('SET NAMES ' . $this->resource->quote($charset)); } $this->driverName = strtolower($this->resource->getAttribute(\PDO::ATTR_DRIVER_NAME)); } catch (\PDOException $e) { $code = $e->getCode(); if (!is_long($code)) { $code = null; } throw new Exception\RuntimeException('Connect Error: ' . $e->getMessage(), $code, $e); } return $this; } /** * {@inheritDoc} */ public function isConnected() { return ($this->resource instanceof \PDO); } /** * {@inheritDoc} */ public function beginTransaction() { if (!$this->isConnected()) { $this->connect(); } if (0 === $this->nestedTransactionsCount) { $this->resource->beginTransaction(); $this->inTransaction = true; } $this->nestedTransactionsCount ++; return $this; } /** * {@inheritDoc} */ public function commit() { if (!$this->isConnected()) { $this->connect(); } if ($this->inTransaction) { $this->nestedTransactionsCount -= 1; } /* * This shouldn't check for being in a transaction since * after issuing a SET autocommit=0; we have to commit too. */ if (0 === $this->nestedTransactionsCount) { $this->resource->commit(); $this->inTransaction = false; } return $this; } /** * {@inheritDoc} * * @throws Exception\RuntimeException */ public function rollback() { if (!$this->isConnected()) { throw new Exception\RuntimeException('Must be connected before you can rollback'); } if (!$this->inTransaction()) { throw new Exception\RuntimeException('Must call beginTransaction() before you can rollback'); } $this->resource->rollBack(); $this->inTransaction = false; $this->nestedTransactionsCount = 0; return $this; } /** * {@inheritDoc} * * @throws Exception\InvalidQueryException */ public function execute($sql) { if (!$this->isConnected()) { $this->connect(); } if ($this->profiler) { $this->profiler->profilerStart($sql); } $resultResource = $this->resource->query($sql); if ($this->profiler) { $this->profiler->profilerFinish($sql); } if ($resultResource === false) { $errorInfo = $this->resource->errorInfo(); throw new Exception\InvalidQueryException($errorInfo[2]); } $result = $this->driver->createResult($resultResource, $sql); return $result; } /** * Prepare * * @param string $sql * @return Statement */ public function prepare($sql) { if (!$this->isConnected()) { $this->connect(); } $statement = $this->driver->createStatement($sql); return $statement; } /** * {@inheritDoc} * * @param string $name * @return string|null|false */ public function getLastGeneratedValue($name = null) { if ($name === null && $this->driverName == 'pgsql') { return; } try { return $this->resource->lastInsertId($name); } catch (\Exception $e) { // do nothing } return false; } } zend-db-release-2.8.1/src/Adapter/Driver/Pdo/Feature/000077500000000000000000000000001270372430400222045ustar00rootroot00000000000000zend-db-release-2.8.1/src/Adapter/Driver/Pdo/Feature/OracleRowCounter.php000066400000000000000000000040651270372430400261570ustar00rootroot00000000000000getSql(); if ($sql == '' || stripos($sql, 'select') === false) { return; } $countSql = 'SELECT COUNT(*) as "count" FROM (' . $sql . ')'; $countStmt->prepare($countSql); $result = $countStmt->execute(); $countRow = $result->getResource()->fetch(\PDO::FETCH_ASSOC); unset($statement, $result); return $countRow['count']; } /** * @param $sql * @return null|int */ public function getCountForSql($sql) { if (stripos($sql, 'select') === false) { return; } $countSql = 'SELECT COUNT(*) as count FROM (' . $sql . ')'; /** @var $pdo \PDO */ $pdo = $this->driver->getConnection()->getResource(); $result = $pdo->query($countSql); $countRow = $result->fetch(\PDO::FETCH_ASSOC); return $countRow['count']; } /** * @param $context * @return \Closure */ public function getRowCountClosure($context) { return function () use ($context) { return ($context instanceof Pdo\Statement) ? $this->getCountForStatement($context) : $this->getCountForSql($context); }; } } zend-db-release-2.8.1/src/Adapter/Driver/Pdo/Feature/SqliteRowCounter.php000066400000000000000000000040651270372430400262130ustar00rootroot00000000000000getSql(); if ($sql == '' || stripos($sql, 'select') === false) { return; } $countSql = 'SELECT COUNT(*) as "count" FROM (' . $sql . ')'; $countStmt->prepare($countSql); $result = $countStmt->execute(); $countRow = $result->getResource()->fetch(\PDO::FETCH_ASSOC); unset($statement, $result); return $countRow['count']; } /** * @param $sql * @return null|int */ public function getCountForSql($sql) { if (stripos($sql, 'select') === false) { return; } $countSql = 'SELECT COUNT(*) as count FROM (' . $sql . ')'; /** @var $pdo \PDO */ $pdo = $this->driver->getConnection()->getResource(); $result = $pdo->query($countSql); $countRow = $result->fetch(\PDO::FETCH_ASSOC); return $countRow['count']; } /** * @param $context * @return \Closure */ public function getRowCountClosure($context) { return function () use ($context) { return ($context instanceof Pdo\Statement) ? $this->getCountForStatement($context) : $this->getCountForSql($context); }; } } zend-db-release-2.8.1/src/Adapter/Driver/Pdo/Pdo.php000066400000000000000000000206601270372430400220500ustar00rootroot00000000000000registerConnection($connection); $this->registerStatementPrototype(($statementPrototype) ?: new Statement()); $this->registerResultPrototype(($resultPrototype) ?: new Result()); if (is_array($features)) { foreach ($features as $name => $feature) { $this->addFeature($name, $feature); } } elseif ($features instanceof AbstractFeature) { $this->addFeature($features->getName(), $features); } elseif ($features === self::FEATURES_DEFAULT) { $this->setupDefaultFeatures(); } } /** * @param Profiler\ProfilerInterface $profiler * @return Pdo */ public function setProfiler(Profiler\ProfilerInterface $profiler) { $this->profiler = $profiler; if ($this->connection instanceof Profiler\ProfilerAwareInterface) { $this->connection->setProfiler($profiler); } if ($this->statementPrototype instanceof Profiler\ProfilerAwareInterface) { $this->statementPrototype->setProfiler($profiler); } return $this; } /** * @return null|Profiler\ProfilerInterface */ public function getProfiler() { return $this->profiler; } /** * Register connection * * @param Connection $connection * @return Pdo */ public function registerConnection(Connection $connection) { $this->connection = $connection; $this->connection->setDriver($this); return $this; } /** * Register statement prototype * * @param Statement $statementPrototype */ public function registerStatementPrototype(Statement $statementPrototype) { $this->statementPrototype = $statementPrototype; $this->statementPrototype->setDriver($this); } /** * Register result prototype * * @param Result $resultPrototype */ public function registerResultPrototype(Result $resultPrototype) { $this->resultPrototype = $resultPrototype; } /** * Add feature * * @param string $name * @param AbstractFeature $feature * @return Pdo */ public function addFeature($name, $feature) { if ($feature instanceof AbstractFeature) { $name = $feature->getName(); // overwrite the name, just in case $feature->setDriver($this); } $this->features[$name] = $feature; return $this; } /** * Setup the default features for Pdo * * @return Pdo */ public function setupDefaultFeatures() { $driverName = $this->connection->getDriverName(); if ($driverName == 'sqlite') { $this->addFeature(null, new Feature\SqliteRowCounter); } elseif ($driverName == 'oci') { $this->addFeature(null, new Feature\OracleRowCounter); } return $this; } /** * Get feature * * @param $name * @return AbstractFeature|false */ public function getFeature($name) { if (isset($this->features[$name])) { return $this->features[$name]; } return false; } /** * Get database platform name * * @param string $nameFormat * @return string */ public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE) { $name = $this->getConnection()->getDriverName(); if ($nameFormat == self::NAME_FORMAT_CAMELCASE) { switch ($name) { case 'pgsql': return 'Postgresql'; case 'oci': return 'Oracle'; case 'dblib': case 'sqlsrv': return 'SqlServer'; default: return ucfirst($name); } } else { switch ($name) { case 'sqlite': return 'SQLite'; case 'mysql': return 'MySQL'; case 'pgsql': return 'PostgreSQL'; case 'oci': return 'Oracle'; case 'dblib': case 'sqlsrv': return 'SQLServer'; default: return ucfirst($name); } } } /** * Check environment */ public function checkEnvironment() { if (!extension_loaded('PDO')) { throw new Exception\RuntimeException('The PDO extension is required for this adapter but the extension is not loaded'); } } /** * @return Connection */ public function getConnection() { return $this->connection; } /** * @param string|PDOStatement $sqlOrResource * @return Statement */ public function createStatement($sqlOrResource = null) { $statement = clone $this->statementPrototype; if ($sqlOrResource instanceof PDOStatement) { $statement->setResource($sqlOrResource); } else { if (is_string($sqlOrResource)) { $statement->setSql($sqlOrResource); } if (!$this->connection->isConnected()) { $this->connection->connect(); } $statement->initialize($this->connection->getResource()); } return $statement; } /** * @param resource $resource * @param mixed $context * @return Result */ public function createResult($resource, $context = null) { $result = clone $this->resultPrototype; $rowCount = null; // special feature, sqlite PDO counter if ($this->connection->getDriverName() == 'sqlite' && ($sqliteRowCounter = $this->getFeature('SqliteRowCounter')) && $resource->columnCount() > 0) { $rowCount = $sqliteRowCounter->getRowCountClosure($context); } // special feature, oracle PDO counter if ($this->connection->getDriverName() == 'oci' && ($oracleRowCounter = $this->getFeature('OracleRowCounter')) && $resource->columnCount() > 0) { $rowCount = $oracleRowCounter->getRowCountClosure($context); } $result->initialize($resource, $this->connection->getLastGeneratedValue(), $rowCount); return $result; } /** * @return string */ public function getPrepareType() { return self::PARAMETERIZATION_NAMED; } /** * @param string $name * @param string|null $type * @return string */ public function formatParameterName($name, $type = null) { if ($type === null && !is_numeric($name) || $type == self::PARAMETERIZATION_NAMED) { return ':' . $name; } return '?'; } /** * @return mixed */ public function getLastGeneratedValue($name = null) { return $this->connection->getLastGeneratedValue($name); } } zend-db-release-2.8.1/src/Adapter/Driver/Pdo/Result.php000066400000000000000000000120511270372430400225770ustar00rootroot00000000000000resource = $resource; $this->generatedValue = $generatedValue; $this->rowCount = $rowCount; return $this; } /** * @return null */ public function buffer() { return; } /** * @return bool|null */ public function isBuffered() { return false; } /** * @param int $fetchMode * @throws Exception\InvalidArgumentException on invalid fetch mode */ public function setFetchMode($fetchMode) { if ($fetchMode < 1 || $fetchMode > 10) { throw new Exception\InvalidArgumentException( 'The fetch mode must be one of the PDO::FETCH_* constants.' ); } $this->fetchMode = (int) $fetchMode; } /** * @return int */ public function getFetchMode() { return $this->fetchMode; } /** * Get resource * * @return mixed */ public function getResource() { return $this->resource; } /** * Get the data * @return array */ public function current() { if ($this->currentComplete) { return $this->currentData; } $this->currentData = $this->resource->fetch($this->fetchMode); $this->currentComplete = true; return $this->currentData; } /** * Next * * @return mixed */ public function next() { $this->currentData = $this->resource->fetch($this->fetchMode); $this->currentComplete = true; $this->position++; return $this->currentData; } /** * Key * * @return mixed */ public function key() { return $this->position; } /** * @throws Exception\RuntimeException * @return void */ public function rewind() { if ($this->statementMode == self::STATEMENT_MODE_FORWARD && $this->position > 0) { throw new Exception\RuntimeException( 'This result is a forward only result set, calling rewind() after moving forward is not supported' ); } $this->currentData = $this->resource->fetch($this->fetchMode); $this->currentComplete = true; $this->position = 0; } /** * Valid * * @return bool */ public function valid() { return ($this->currentData !== false); } /** * Count * * @return int */ public function count() { if (is_int($this->rowCount)) { return $this->rowCount; } if ($this->rowCount instanceof \Closure) { $this->rowCount = (int) call_user_func($this->rowCount); } else { $this->rowCount = (int) $this->resource->rowCount(); } return $this->rowCount; } /** * @return int */ public function getFieldCount() { return $this->resource->columnCount(); } /** * Is query result * * @return bool */ public function isQueryResult() { return ($this->resource->columnCount() > 0); } /** * Get affected rows * * @return int */ public function getAffectedRows() { return $this->resource->rowCount(); } /** * @return mixed|null */ public function getGeneratedValue() { return $this->generatedValue; } } zend-db-release-2.8.1/src/Adapter/Driver/Pdo/Statement.php000066400000000000000000000161511270372430400232720ustar00rootroot00000000000000driver = $driver; return $this; } /** * @param Profiler\ProfilerInterface $profiler * @return Statement */ public function setProfiler(Profiler\ProfilerInterface $profiler) { $this->profiler = $profiler; return $this; } /** * @return null|Profiler\ProfilerInterface */ public function getProfiler() { return $this->profiler; } /** * Initialize * * @param \PDO $connectionResource * @return Statement */ public function initialize(\PDO $connectionResource) { $this->pdo = $connectionResource; return $this; } /** * Set resource * * @param \PDOStatement $pdoStatement * @return Statement */ public function setResource(\PDOStatement $pdoStatement) { $this->resource = $pdoStatement; return $this; } /** * Get resource * * @return mixed */ public function getResource() { return $this->resource; } /** * Set sql * * @param string $sql * @return Statement */ public function setSql($sql) { $this->sql = $sql; return $this; } /** * Get sql * * @return string */ public function getSql() { return $this->sql; } /** * @param ParameterContainer $parameterContainer * @return Statement */ public function setParameterContainer(ParameterContainer $parameterContainer) { $this->parameterContainer = $parameterContainer; return $this; } /** * @return ParameterContainer */ public function getParameterContainer() { return $this->parameterContainer; } /** * @param string $sql * @throws Exception\RuntimeException */ public function prepare($sql = null) { if ($this->isPrepared) { throw new Exception\RuntimeException('This statement has been prepared already'); } if ($sql === null) { $sql = $this->sql; } $this->resource = $this->pdo->prepare($sql); if ($this->resource === false) { $error = $this->pdo->errorInfo(); throw new Exception\RuntimeException($error[2]); } $this->isPrepared = true; } /** * @return bool */ public function isPrepared() { return $this->isPrepared; } /** * @param null|array|ParameterContainer $parameters * @throws Exception\InvalidQueryException * @return Result */ public function execute($parameters = null) { if (!$this->isPrepared) { $this->prepare(); } /** START Standard ParameterContainer Merging Block */ if (!$this->parameterContainer instanceof ParameterContainer) { if ($parameters instanceof ParameterContainer) { $this->parameterContainer = $parameters; $parameters = null; } else { $this->parameterContainer = new ParameterContainer(); } } if (is_array($parameters)) { $this->parameterContainer->setFromArray($parameters); } if ($this->parameterContainer->count() > 0) { $this->bindParametersFromContainer(); } /** END Standard ParameterContainer Merging Block */ if ($this->profiler) { $this->profiler->profilerStart($this); } try { $this->resource->execute(); } catch (\PDOException $e) { if ($this->profiler) { $this->profiler->profilerFinish(); } throw new Exception\InvalidQueryException( 'Statement could not be executed (' . implode(' - ', $this->resource->errorInfo()) . ')', null, $e ); } if ($this->profiler) { $this->profiler->profilerFinish(); } $result = $this->driver->createResult($this->resource, $this); return $result; } /** * Bind parameters from container */ protected function bindParametersFromContainer() { if ($this->parametersBound) { return; } $parameters = $this->parameterContainer->getNamedArray(); foreach ($parameters as $name => &$value) { if (is_bool($value)) { $type = \PDO::PARAM_BOOL; } elseif (is_int($value)) { $type = \PDO::PARAM_INT; } else { $type = \PDO::PARAM_STR; } if ($this->parameterContainer->offsetHasErrata($name)) { switch ($this->parameterContainer->offsetGetErrata($name)) { case ParameterContainer::TYPE_INTEGER: $type = \PDO::PARAM_INT; break; case ParameterContainer::TYPE_NULL: $type = \PDO::PARAM_NULL; break; case ParameterContainer::TYPE_LOB: $type = \PDO::PARAM_LOB; break; } } // parameter is named or positional, value is reference $parameter = is_int($name) ? ($name + 1) : $name; $this->resource->bindParam($parameter, $value, $type); } } /** * Perform a deep clone * @return Statement A cloned statement */ public function __clone() { $this->isPrepared = false; $this->parametersBound = false; $this->resource = null; if ($this->parameterContainer) { $this->parameterContainer = clone $this->parameterContainer; } } } zend-db-release-2.8.1/src/Adapter/Driver/Pgsql/000077500000000000000000000000001270372430400211555ustar00rootroot00000000000000zend-db-release-2.8.1/src/Adapter/Driver/Pgsql/Connection.php000066400000000000000000000170311270372430400237670ustar00rootroot00000000000000setConnectionParameters($connectionInfo); } elseif (is_resource($connectionInfo)) { $this->setResource($connectionInfo); } } /** * Set resource * * @param resource $resource * @return self */ public function setResource($resource) { $this->resource = $resource; return $this; } /** * Set driver * * @param Pgsql $driver * @return self */ public function setDriver(Pgsql $driver) { $this->driver = $driver; return $this; } /** * @param int|null $type * @return self */ public function setType($type) { $invalidConectionType = ($type !== PGSQL_CONNECT_FORCE_NEW); // Compatibility with PHP < 5.6 if ($invalidConectionType && defined('PGSQL_CONNECT_ASYNC')) { $invalidConectionType = ($type !== PGSQL_CONNECT_ASYNC); } if ($invalidConectionType) { throw new Exception\InvalidArgumentException('Connection type is not valid. (See: http://php.net/manual/en/function.pg-connect.php)'); } $this->type = $type; return $this; } /** * {@inheritDoc} * * @return null|string */ public function getCurrentSchema() { if (!$this->isConnected()) { $this->connect(); } $result = pg_query($this->resource, 'SELECT CURRENT_SCHEMA AS "currentschema"'); if ($result == false) { return; } return pg_fetch_result($result, 0, 'currentschema'); } /** * {@inheritDoc} * * @throws Exception\RuntimeException on failure */ public function connect() { if (is_resource($this->resource)) { return $this; } $connection = $this->getConnectionString(); set_error_handler(function ($number, $string) { throw new Exception\RuntimeException( __METHOD__ . ': Unable to connect to database', null, new Exception\ErrorException($string, $number) ); }); $this->resource = pg_connect($connection); restore_error_handler(); if ($this->resource === false) { throw new Exception\RuntimeException(sprintf( '%s: Unable to connect to database', __METHOD__ )); } $p = $this->connectionParameters; if (!empty($p['charset'])) { if (-1 === pg_set_client_encoding($this->resource, $p['charset'])) { throw new Exception\RuntimeException(sprintf( "%s: Unable to set client encoding '%s'", __METHOD__, $p['charset'] )); } } return $this; } /** * {@inheritDoc} */ public function isConnected() { return (is_resource($this->resource)); } /** * {@inheritDoc} */ public function disconnect() { pg_close($this->resource); return $this; } /** * {@inheritDoc} */ public function beginTransaction() { if ($this->inTransaction()) { throw new Exception\RuntimeException('Nested transactions are not supported'); } if (!$this->isConnected()) { $this->connect(); } pg_query($this->resource, 'BEGIN'); $this->inTransaction = true; return $this; } /** * {@inheritDoc} */ public function commit() { if (!$this->isConnected()) { $this->connect(); } if (!$this->inTransaction()) { return; // We ignore attempts to commit non-existing transaction } pg_query($this->resource, 'COMMIT'); $this->inTransaction = false; return $this; } /** * {@inheritDoc} */ public function rollback() { if (!$this->isConnected()) { throw new Exception\RuntimeException('Must be connected before you can rollback'); } if (!$this->inTransaction()) { throw new Exception\RuntimeException('Must call beginTransaction() before you can rollback'); } pg_query($this->resource, 'ROLLBACK'); $this->inTransaction = false; return $this; } /** * {@inheritDoc} * * @throws Exception\InvalidQueryException * @return resource|\Zend\Db\ResultSet\ResultSetInterface */ public function execute($sql) { if (!$this->isConnected()) { $this->connect(); } if ($this->profiler) { $this->profiler->profilerStart($sql); } $resultResource = pg_query($this->resource, $sql); if ($this->profiler) { $this->profiler->profilerFinish($sql); } // if the returnValue is something other than a pg result resource, bypass wrapping it if ($resultResource === false) { throw new Exception\InvalidQueryException(pg_errormessage()); } $resultPrototype = $this->driver->createResult(($resultResource === true) ? $this->resource : $resultResource); return $resultPrototype; } /** * {@inheritDoc} * * @return string */ public function getLastGeneratedValue($name = null) { if ($name === null) { return; } $result = pg_query($this->resource, 'SELECT CURRVAL(\'' . str_replace('\'', '\\\'', $name) . '\') as "currval"'); return pg_fetch_result($result, 0, 'currval'); } /** * Get Connection String * * @return string */ private function getConnectionString() { // localize $p = $this->connectionParameters; // given a list of key names, test for existence in $p $findParameterValue = function (array $names) use ($p) { foreach ($names as $name) { if (isset($p[$name])) { return $p[$name]; } } return; }; $connectionParameters = [ 'host' => $findParameterValue(['hostname', 'host']), 'user' => $findParameterValue(['username', 'user']), 'password' => $findParameterValue(['password', 'passwd', 'pw']), 'dbname' => $findParameterValue(['database', 'dbname', 'db', 'schema']), 'port' => isset($p['port']) ? (int) $p['port'] : null, 'socket' => isset($p['socket']) ? $p['socket'] : null, ]; return urldecode(http_build_query(array_filter($connectionParameters), null, ' ')); } } zend-db-release-2.8.1/src/Adapter/Driver/Pgsql/Pgsql.php000066400000000000000000000125211270372430400227550ustar00rootroot00000000000000 false ]; /** * Constructor * * @param array|Connection|resource $connection * @param null|Statement $statementPrototype * @param null|Result $resultPrototype * @param array $options */ public function __construct($connection, Statement $statementPrototype = null, Result $resultPrototype = null, $options = null) { if (!$connection instanceof Connection) { $connection = new Connection($connection); } $this->registerConnection($connection); $this->registerStatementPrototype(($statementPrototype) ?: new Statement()); $this->registerResultPrototype(($resultPrototype) ?: new Result()); } public function setProfiler(Profiler\ProfilerInterface $profiler) { $this->profiler = $profiler; if ($this->connection instanceof Profiler\ProfilerAwareInterface) { $this->connection->setProfiler($profiler); } if ($this->statementPrototype instanceof Profiler\ProfilerAwareInterface) { $this->statementPrototype->setProfiler($profiler); } return $this; } /** * @return null|Profiler\ProfilerInterface */ public function getProfiler() { return $this->profiler; } /** * Register connection * * @param Connection $connection * @return Pgsql */ public function registerConnection(Connection $connection) { $this->connection = $connection; $this->connection->setDriver($this); return $this; } /** * Register statement prototype * * @param Statement $statement * @return Pgsql */ public function registerStatementPrototype(Statement $statement) { $this->statementPrototype = $statement; $this->statementPrototype->setDriver($this); // needs access to driver to createResult() return $this; } /** * Register result prototype * * @param Result $result * @return Pgsql */ public function registerResultPrototype(Result $result) { $this->resultPrototype = $result; return $this; } /** * Get database platform name * * @param string $nameFormat * @return string */ public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE) { if ($nameFormat == self::NAME_FORMAT_CAMELCASE) { return 'Postgresql'; } return 'PostgreSQL'; } /** * Check environment * * @throws Exception\RuntimeException * @return bool */ public function checkEnvironment() { if (!extension_loaded('pgsql')) { throw new Exception\RuntimeException('The PostgreSQL (pgsql) extension is required for this adapter but the extension is not loaded'); } } /** * Get connection * * @return Connection */ public function getConnection() { return $this->connection; } /** * Create statement * * @param string|null $sqlOrResource * @return Statement */ public function createStatement($sqlOrResource = null) { $statement = clone $this->statementPrototype; if (is_string($sqlOrResource)) { $statement->setSql($sqlOrResource); } if (!$this->connection->isConnected()) { $this->connection->connect(); } $statement->initialize($this->connection->getResource()); return $statement; } /** * Create result * * @param resource $resource * @return Result */ public function createResult($resource) { $result = clone $this->resultPrototype; $result->initialize($resource, $this->connection->getLastGeneratedValue()); return $result; } /** * Get prepare Type * * @return string */ public function getPrepareType() { return self::PARAMETERIZATION_POSITIONAL; } /** * Format parameter name * * @param string $name * @param mixed $type * @return string */ public function formatParameterName($name, $type = null) { return '$#'; } /** * Get last generated value * * @param string $name * @return mixed */ public function getLastGeneratedValue($name = null) { return $this->connection->getLastGeneratedValue($name); } } zend-db-release-2.8.1/src/Adapter/Driver/Pgsql/Result.php000066400000000000000000000066261270372430400231560ustar00rootroot00000000000000resource = $resource; $this->count = pg_num_rows($this->resource); $this->generatedValue = $generatedValue; } /** * Current * * @return array|bool|mixed */ public function current() { if ($this->count === 0) { return false; } return pg_fetch_assoc($this->resource, $this->position); } /** * Next * * @return void */ public function next() { $this->position++; } /** * Key * * @return int|mixed */ public function key() { return $this->position; } /** * Valid * * @return bool */ public function valid() { return ($this->position < $this->count); } /** * Rewind * * @return void */ public function rewind() { $this->position = 0; } /** * Buffer * * @return null */ public function buffer() { return; } /** * Is buffered * * @return false */ public function isBuffered() { return false; } /** * Is query result * * @return bool */ public function isQueryResult() { return (pg_num_fields($this->resource) > 0); } /** * Get affected rows * * @return int */ public function getAffectedRows() { return pg_affected_rows($this->resource); } /** * Get generated value * * @return mixed|null */ public function getGeneratedValue() { return $this->generatedValue; } /** * Get resource */ public function getResource() { // TODO: Implement getResource() method. } /** * Count * * (PHP 5 >= 5.1.0)
* Count elements of an object * @link http://php.net/manual/en/countable.count.php * @return int The custom count as an integer. *

*

* The return value is cast to an integer. */ public function count() { return $this->count; } /** * Get field count * * @return int */ public function getFieldCount() { return pg_num_fields($this->resource); } } zend-db-release-2.8.1/src/Adapter/Driver/Pgsql/Statement.php000066400000000000000000000125111270372430400236320ustar00rootroot00000000000000driver = $driver; return $this; } /** * @param Profiler\ProfilerInterface $profiler * @return Statement */ public function setProfiler(Profiler\ProfilerInterface $profiler) { $this->profiler = $profiler; return $this; } /** * @return null|Profiler\ProfilerInterface */ public function getProfiler() { return $this->profiler; } /** * Initialize * * @param resource $pgsql * @return void * @throws Exception\RuntimeException for invalid or missing postgresql connection */ public function initialize($pgsql) { if (!is_resource($pgsql) || get_resource_type($pgsql) !== 'pgsql link') { throw new Exception\RuntimeException(sprintf( '%s: Invalid or missing postgresql connection; received "%s"', __METHOD__, get_resource_type($pgsql) )); } $this->pgsql = $pgsql; } /** * Get resource * * @return resource */ public function getResource() { // TODO: Implement getResource() method. } /** * Set sql * * @param string $sql * @return Statement */ public function setSql($sql) { $this->sql = $sql; return $this; } /** * Get sql * * @return string */ public function getSql() { return $this->sql; } /** * Set parameter container * * @param ParameterContainer $parameterContainer * @return Statement */ public function setParameterContainer(ParameterContainer $parameterContainer) { $this->parameterContainer = $parameterContainer; return $this; } /** * Get parameter container * * @return ParameterContainer */ public function getParameterContainer() { return $this->parameterContainer; } /** * Prepare * * @param string $sql */ public function prepare($sql = null) { $sql = ($sql) ?: $this->sql; $pCount = 1; $sql = preg_replace_callback( '#\$\##', function () use (&$pCount) { return '$' . $pCount++; }, $sql ); $this->sql = $sql; $this->statementName = 'statement' . ++static::$statementIndex; $this->resource = pg_prepare($this->pgsql, $this->statementName, $sql); } /** * Is prepared * * @return bool */ public function isPrepared() { return isset($this->resource); } /** * Execute * * @param null|array|ParameterContainer $parameters * @throws Exception\InvalidQueryException * @return Result */ public function execute($parameters = null) { if (!$this->isPrepared()) { $this->prepare(); } /** START Standard ParameterContainer Merging Block */ if (!$this->parameterContainer instanceof ParameterContainer) { if ($parameters instanceof ParameterContainer) { $this->parameterContainer = $parameters; $parameters = null; } else { $this->parameterContainer = new ParameterContainer(); } } if (is_array($parameters)) { $this->parameterContainer->setFromArray($parameters); } if ($this->parameterContainer->count() > 0) { $parameters = $this->parameterContainer->getPositionalArray(); } /** END Standard ParameterContainer Merging Block */ if ($this->profiler) { $this->profiler->profilerStart($this); } $resultResource = pg_execute($this->pgsql, $this->statementName, (array) $parameters); if ($this->profiler) { $this->profiler->profilerFinish(); } if ($resultResource === false) { throw new Exception\InvalidQueryException(pg_last_error()); } $result = $this->driver->createResult($resultResource); return $result; } } zend-db-release-2.8.1/src/Adapter/Driver/ResultInterface.php000066400000000000000000000022411270372430400236760ustar00rootroot00000000000000setConnectionParameters($connectionInfo); } elseif (is_resource($connectionInfo)) { $this->setResource($connectionInfo); } else { throw new Exception\InvalidArgumentException('$connection must be an array of parameters or a resource'); } } /** * Set driver * * @param Sqlsrv $driver * @return self */ public function setDriver(Sqlsrv $driver) { $this->driver = $driver; return $this; } /** * {@inheritDoc} */ public function getCurrentSchema() { if (!$this->isConnected()) { $this->connect(); } $result = sqlsrv_query($this->resource, 'SELECT SCHEMA_NAME()'); $r = sqlsrv_fetch_array($result); return $r[0]; } /** * Set resource * * @param resource $resource * @throws Exception\InvalidArgumentException * @return self */ public function setResource($resource) { if (get_resource_type($resource) !== 'SQL Server Connection') { throw new Exception\InvalidArgumentException('Resource provided was not of type SQL Server Connection'); } $this->resource = $resource; return $this; } /** * {@inheritDoc} * * @throws Exception\RuntimeException */ public function connect() { if ($this->resource) { return $this; } $serverName = '.'; $params = [ 'ReturnDatesAsStrings' => true ]; foreach ($this->connectionParameters as $key => $value) { switch (strtolower($key)) { case 'hostname': case 'servername': $serverName = (string) $value; break; case 'username': case 'uid': $params['UID'] = (string) $value; break; case 'password': case 'pwd': $params['PWD'] = (string) $value; break; case 'database': case 'dbname': $params['Database'] = (string) $value; break; case 'charset': $params['CharacterSet'] = (string) $value; break; case 'driver_options': case 'options': $params = array_merge($params, (array) $value); break; } } $this->resource = sqlsrv_connect($serverName, $params); if (!$this->resource) { throw new Exception\RuntimeException( 'Connect Error', null, new ErrorException(sqlsrv_errors()) ); } return $this; } /** * {@inheritDoc} */ public function isConnected() { return (is_resource($this->resource)); } /** * {@inheritDoc} */ public function disconnect() { sqlsrv_close($this->resource); $this->resource = null; } /** * {@inheritDoc} */ public function beginTransaction() { if (!$this->isConnected()) { $this->connect(); } if (sqlsrv_begin_transaction($this->resource) === false) { throw new Exception\RuntimeException( new ErrorException(sqlsrv_errors()) ); } $this->inTransaction = true; return $this; } /** * {@inheritDoc} */ public function commit() { // http://msdn.microsoft.com/en-us/library/cc296194.aspx if (!$this->isConnected()) { $this->connect(); } sqlsrv_commit($this->resource); $this->inTransaction = false; return $this; } /** * {@inheritDoc} */ public function rollback() { // http://msdn.microsoft.com/en-us/library/cc296176.aspx if (!$this->isConnected()) { throw new Exception\RuntimeException('Must be connected before you can rollback.'); } sqlsrv_rollback($this->resource); $this->inTransaction = false; return $this; } /** * {@inheritDoc} * * @throws Exception\RuntimeException */ public function execute($sql) { if (!$this->isConnected()) { $this->connect(); } if (!$this->driver instanceof Sqlsrv) { throw new Exception\RuntimeException('Connection is missing an instance of Sqlsrv'); } if ($this->profiler) { $this->profiler->profilerStart($sql); } $returnValue = sqlsrv_query($this->resource, $sql); if ($this->profiler) { $this->profiler->profilerFinish($sql); } // if the returnValue is something other than a Sqlsrv_result, bypass wrapping it if ($returnValue === false) { $errors = sqlsrv_errors(); // ignore general warnings if ($errors[0]['SQLSTATE'] != '01000') { throw new Exception\RuntimeException( 'An exception occurred while trying to execute the provided $sql', null, new ErrorException($errors) ); } } $result = $this->driver->createResult($returnValue); return $result; } /** * Prepare * * @param string $sql * @return string */ public function prepare($sql) { if (!$this->isConnected()) { $this->connect(); } $statement = $this->driver->createStatement($sql); return $statement; } /** * {@inheritDoc} * * @return mixed */ public function getLastGeneratedValue($name = null) { if (!$this->resource) { $this->connect(); } $sql = 'SELECT @@IDENTITY as Current_Identity'; $result = sqlsrv_query($this->resource, $sql); $row = sqlsrv_fetch_array($result); return $row['Current_Identity']; } } zend-db-release-2.8.1/src/Adapter/Driver/Sqlsrv/Exception/000077500000000000000000000000001270372430400233175ustar00rootroot00000000000000zend-db-release-2.8.1/src/Adapter/Driver/Sqlsrv/Exception/ErrorException.php000066400000000000000000000014001270372430400267730ustar00rootroot00000000000000errors = ($errors === false) ? sqlsrv_errors() : $errors; } } zend-db-release-2.8.1/src/Adapter/Driver/Sqlsrv/Exception/ExceptionInterface.php000066400000000000000000000007201270372430400276060ustar00rootroot00000000000000resource = $resource; $this->generatedValue = $generatedValue; return $this; } /** * @return null */ public function buffer() { return; } /** * @return bool */ public function isBuffered() { return false; } /** * Get resource * * @return resource */ public function getResource() { return $this->resource; } /** * Current * * @return mixed */ public function current() { if ($this->currentComplete) { return $this->currentData; } $this->load(); return $this->currentData; } /** * Next * * @return bool */ public function next() { $this->load(); return true; } /** * Load * * @param int $row * @return mixed */ protected function load($row = SQLSRV_SCROLL_NEXT) { $this->currentData = sqlsrv_fetch_array($this->resource, SQLSRV_FETCH_ASSOC, $row); $this->currentComplete = true; $this->position++; return $this->currentData; } /** * Key * * @return mixed */ public function key() { return $this->position; } /** * Rewind * * @return bool */ public function rewind() { $this->position = 0; $this->load(SQLSRV_SCROLL_FIRST); return true; } /** * Valid * * @return bool */ public function valid() { if ($this->currentComplete && $this->currentData) { return true; } return $this->load(); } /** * Count * * @return int */ public function count() { return sqlsrv_num_rows($this->resource); } /** * @return bool|int */ public function getFieldCount() { return sqlsrv_num_fields($this->resource); } /** * Is query result * * @return bool */ public function isQueryResult() { if (is_bool($this->resource)) { return false; } return (sqlsrv_num_fields($this->resource) > 0); } /** * Get affected rows * * @return int */ public function getAffectedRows() { return sqlsrv_rows_affected($this->resource); } /** * @return mixed|null */ public function getGeneratedValue() { return $this->generatedValue; } } zend-db-release-2.8.1/src/Adapter/Driver/Sqlsrv/Sqlsrv.php000066400000000000000000000125401270372430400233660ustar00rootroot00000000000000registerConnection($connection); $this->registerStatementPrototype(($statementPrototype) ?: new Statement()); $this->registerResultPrototype(($resultPrototype) ?: new Result()); } /** * @param Profiler\ProfilerInterface $profiler * @return Sqlsrv */ public function setProfiler(Profiler\ProfilerInterface $profiler) { $this->profiler = $profiler; if ($this->connection instanceof Profiler\ProfilerAwareInterface) { $this->connection->setProfiler($profiler); } if ($this->statementPrototype instanceof Profiler\ProfilerAwareInterface) { $this->statementPrototype->setProfiler($profiler); } return $this; } /** * @return null|Profiler\ProfilerInterface */ public function getProfiler() { return $this->profiler; } /** * Register connection * * @param Connection $connection * @return Sqlsrv */ public function registerConnection(Connection $connection) { $this->connection = $connection; $this->connection->setDriver($this); return $this; } /** * Register statement prototype * * @param Statement $statementPrototype * @return Sqlsrv */ public function registerStatementPrototype(Statement $statementPrototype) { $this->statementPrototype = $statementPrototype; $this->statementPrototype->setDriver($this); return $this; } /** * Register result prototype * * @param Result $resultPrototype * @return Sqlsrv */ public function registerResultPrototype(Result $resultPrototype) { $this->resultPrototype = $resultPrototype; return $this; } /** * Get database paltform name * * @param string $nameFormat * @return string */ public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE) { if ($nameFormat == self::NAME_FORMAT_CAMELCASE) { return 'SqlServer'; } return 'SQLServer'; } /** * Check environment * * @throws Exception\RuntimeException * @return void */ public function checkEnvironment() { if (!extension_loaded('sqlsrv')) { throw new Exception\RuntimeException('The Sqlsrv extension is required for this adapter but the extension is not loaded'); } } /** * @return Connection */ public function getConnection() { return $this->connection; } /** * @param string|resource $sqlOrResource * @return Statement */ public function createStatement($sqlOrResource = null) { $statement = clone $this->statementPrototype; if (is_resource($sqlOrResource)) { $statement->initialize($sqlOrResource); } else { if (!$this->connection->isConnected()) { $this->connection->connect(); } $statement->initialize($this->connection->getResource()); if (is_string($sqlOrResource)) { $statement->setSql($sqlOrResource); } elseif ($sqlOrResource !== null) { throw new Exception\InvalidArgumentException('createStatement() only accepts an SQL string or a Sqlsrv resource'); } } return $statement; } /** * @param resource $resource * @return Result */ public function createResult($resource) { $result = clone $this->resultPrototype; $result->initialize($resource, $this->connection->getLastGeneratedValue()); return $result; } /** * @return string */ public function getPrepareType() { return self::PARAMETERIZATION_POSITIONAL; } /** * @param string $name * @param mixed $type * @return string */ public function formatParameterName($name, $type = null) { return '?'; } /** * @return mixed */ public function getLastGeneratedValue() { return $this->getConnection()->getLastGeneratedValue(); } } zend-db-release-2.8.1/src/Adapter/Driver/Sqlsrv/Statement.php000066400000000000000000000162241270372430400240430ustar00rootroot00000000000000driver = $driver; return $this; } /** * @param Profiler\ProfilerInterface $profiler * @return Statement */ public function setProfiler(Profiler\ProfilerInterface $profiler) { $this->profiler = $profiler; return $this; } /** * @return null|Profiler\ProfilerInterface */ public function getProfiler() { return $this->profiler; } /** * * One of two resource types will be provided here: * a) "SQL Server Connection" when a prepared statement needs to still be produced * b) "SQL Server Statement" when a prepared statement has been already produced * (there will need to already be a bound param set if it applies to this query) * * @param resource $resource * @throws Exception\InvalidArgumentException * @return Statement */ public function initialize($resource) { $resourceType = get_resource_type($resource); if ($resourceType == 'SQL Server Connection') { $this->sqlsrv = $resource; } elseif ($resourceType == 'SQL Server Statement') { $this->resource = $resource; $this->isPrepared = true; } else { throw new Exception\InvalidArgumentException('Invalid resource provided to ' . __CLASS__); } return $this; } /** * Set parameter container * * @param ParameterContainer $parameterContainer * @return Statement */ public function setParameterContainer(ParameterContainer $parameterContainer) { $this->parameterContainer = $parameterContainer; return $this; } /** * @return ParameterContainer */ public function getParameterContainer() { return $this->parameterContainer; } /** * @param $resource * @return Statement */ public function setResource($resource) { $this->resource = $resource; return $this; } /** * Get resource * * @return resource */ public function getResource() { return $this->resource; } /** * @param string $sql * @return Statement */ public function setSql($sql) { $this->sql = $sql; return $this; } /** * Get sql * * @return string */ public function getSql() { return $this->sql; } /** * @param string $sql * @param array $options * @throws Exception\RuntimeException * @return Statement */ public function prepare($sql = null, array $options = []) { if ($this->isPrepared) { throw new Exception\RuntimeException('Already prepared'); } $sql = ($sql) ?: $this->sql; $options = ($options) ?: $this->prepareOptions; $pRef = &$this->parameterReferences; for ($position = 0, $count = substr_count($sql, '?'); $position < $count; $position++) { if (!isset($this->prepareParams[$position])) { $pRef[$position] = ['', SQLSRV_PARAM_IN, null, null]; } else { $pRef[$position] = &$this->prepareParams[$position]; } } $this->resource = sqlsrv_prepare($this->sqlsrv, $sql, $pRef, $options); $this->isPrepared = true; return $this; } /** * @return bool */ public function isPrepared() { return $this->isPrepared; } /** * Execute * * @param null|array|ParameterContainer $parameters * @throws Exception\RuntimeException * @return Result */ public function execute($parameters = null) { /** END Standard ParameterContainer Merging Block */ if (!$this->isPrepared) { $this->prepare(); } /** START Standard ParameterContainer Merging Block */ if (!$this->parameterContainer instanceof ParameterContainer) { if ($parameters instanceof ParameterContainer) { $this->parameterContainer = $parameters; $parameters = null; } else { $this->parameterContainer = new ParameterContainer(); } } if (is_array($parameters)) { $this->parameterContainer->setFromArray($parameters); } if ($this->parameterContainer->count() > 0) { $this->bindParametersFromContainer(); } if ($this->profiler) { $this->profiler->profilerStart($this); } $resultValue = sqlsrv_execute($this->resource); if ($this->profiler) { $this->profiler->profilerFinish(); } if ($resultValue === false) { $errors = sqlsrv_errors(); // ignore general warnings if ($errors[0]['SQLSTATE'] != '01000') { throw new Exception\RuntimeException($errors[0]['message']); } } $result = $this->driver->createResult($this->resource); return $result; } /** * Bind parameters from container * */ protected function bindParametersFromContainer() { $values = $this->parameterContainer->getPositionalArray(); $position = 0; foreach ($values as $value) { $this->parameterReferences[$position++][0] = $value; } } /** * @param array $prepareParams */ public function setPrepareParams(array $prepareParams) { $this->prepareParams = $prepareParams; } /** * @param array $prepareOptions */ public function setPrepareOptions(array $prepareOptions) { $this->prepareOptions = $prepareOptions; } } zend-db-release-2.8.1/src/Adapter/Driver/StatementInterface.php000066400000000000000000000017461270372430400243750ustar00rootroot00000000000000parameters = $parameters; } } zend-db-release-2.8.1/src/Adapter/Exception/InvalidQueryException.php000066400000000000000000000006731270372430400256040ustar00rootroot00000000000000setFromArray($data); } } /** * Offset exists * * @param string $name * @return bool */ public function offsetExists($name) { return (isset($this->data[$name])); } /** * Offset get * * @param string $name * @return mixed */ public function offsetGet($name) { return (isset($this->data[$name])) ? $this->data[$name] : null; } /** * @param $name * @param $from */ public function offsetSetReference($name, $from) { $this->data[$name] =& $this->data[$from]; } /** * Offset set * * @param string|int $name * @param mixed $value * @param mixed $errata * @param mixed $maxLength * @throws Exception\InvalidArgumentException */ public function offsetSet($name, $value, $errata = null, $maxLength = null) { $position = false; // if integer, get name for this position if (is_int($name)) { if (isset($this->positions[$name])) { $position = $name; $name = $this->positions[$name]; } else { $name = (string) $name; } } elseif (is_string($name)) { // is a string: $position = array_key_exists($name, $this->data); } elseif ($name === null) { $name = (string) count($this->data); } else { throw new Exception\InvalidArgumentException('Keys must be string, integer or null'); } if ($position === false) { $this->positions[] = $name; } $this->data[$name] = $value; if ($errata) { $this->offsetSetErrata($name, $errata); } if ($maxLength) { $this->offsetSetMaxLength($name, $maxLength); } } /** * Offset unset * * @param string $name * @return ParameterContainer */ public function offsetUnset($name) { if (is_int($name) && isset($this->positions[$name])) { $name = $this->positions[$name]; } unset($this->data[$name]); return $this; } /** * Set from array * * @param array $data * @return ParameterContainer */ public function setFromArray(array $data) { foreach ($data as $n => $v) { $this->offsetSet($n, $v); } return $this; } /** * Offset set max length * * @param string|int $name * @param mixed $maxLength */ public function offsetSetMaxLength($name, $maxLength) { if (is_int($name)) { $name = $this->positions[$name]; } $this->maxLength[$name] = $maxLength; } /** * Offset get max length * * @param string|int $name * @throws Exception\InvalidArgumentException * @return mixed */ public function offsetGetMaxLength($name) { if (is_int($name)) { $name = $this->positions[$name]; } if (!array_key_exists($name, $this->data)) { throw new Exception\InvalidArgumentException('Data does not exist for this name/position'); } return $this->maxLength[$name]; } /** * Offset has max length * * @param string|int $name * @return bool */ public function offsetHasMaxLength($name) { if (is_int($name)) { $name = $this->positions[$name]; } return (isset($this->maxLength[$name])); } /** * Offset unset max length * * @param string|int $name * @throws Exception\InvalidArgumentException */ public function offsetUnsetMaxLength($name) { if (is_int($name)) { $name = $this->positions[$name]; } if (!array_key_exists($name, $this->maxLength)) { throw new Exception\InvalidArgumentException('Data does not exist for this name/position'); } $this->maxLength[$name] = null; } /** * Get max length iterator * * @return \ArrayIterator */ public function getMaxLengthIterator() { return new \ArrayIterator($this->maxLength); } /** * Offset set errata * * @param string|int $name * @param mixed $errata */ public function offsetSetErrata($name, $errata) { if (is_int($name)) { $name = $this->positions[$name]; } $this->errata[$name] = $errata; } /** * Offset get errata * * @param string|int $name * @throws Exception\InvalidArgumentException * @return mixed */ public function offsetGetErrata($name) { if (is_int($name)) { $name = $this->positions[$name]; } if (!array_key_exists($name, $this->data)) { throw new Exception\InvalidArgumentException('Data does not exist for this name/position'); } return $this->errata[$name]; } /** * Offset has errata * * @param string|int $name * @return bool */ public function offsetHasErrata($name) { if (is_int($name)) { $name = $this->positions[$name]; } return (isset($this->errata[$name])); } /** * Offset unset errata * * @param string|int $name * @throws Exception\InvalidArgumentException */ public function offsetUnsetErrata($name) { if (is_int($name)) { $name = $this->positions[$name]; } if (!array_key_exists($name, $this->errata)) { throw new Exception\InvalidArgumentException('Data does not exist for this name/position'); } $this->errata[$name] = null; } /** * Get errata iterator * * @return \ArrayIterator */ public function getErrataIterator() { return new \ArrayIterator($this->errata); } /** * getNamedArray * * @return array */ public function getNamedArray() { return $this->data; } /** * getNamedArray * * @return array */ public function getPositionalArray() { return array_values($this->data); } /** * count * * @return int */ public function count() { return count($this->data); } /** * Current * * @return mixed */ public function current() { return current($this->data); } /** * Next * * @return mixed */ public function next() { return next($this->data); } /** * Key * * @return mixed */ public function key() { return key($this->data); } /** * Valid * * @return bool */ public function valid() { return (current($this->data) !== false); } /** * Rewind */ public function rewind() { reset($this->data); } /** * @param array|ParameterContainer $parameters * @throws Exception\InvalidArgumentException * @return ParameterContainer */ public function merge($parameters) { if (!is_array($parameters) && !$parameters instanceof ParameterContainer) { throw new Exception\InvalidArgumentException('$parameters must be an array or an instance of ParameterContainer'); } if (count($parameters) == 0) { return $this; } if ($parameters instanceof ParameterContainer) { $parameters = $parameters->getNamedArray(); } foreach ($parameters as $key => $value) { if (is_int($key)) { $key = null; } $this->offsetSet($key, $value); } return $this; } } zend-db-release-2.8.1/src/Adapter/Platform/000077500000000000000000000000001270372430400204205ustar00rootroot00000000000000zend-db-release-2.8.1/src/Adapter/Platform/AbstractPlatform.php000066400000000000000000000063031270372430400244030ustar00rootroot00000000000000quoteIdentifiers) { return $identifier; } $safeWordsInt = ['*' => true, ' ' => true, '.' => true, 'as' => true]; foreach ($safeWords as $sWord) { $safeWordsInt[strtolower($sWord)] = true; } $parts = preg_split( '/([^0-9,a-z,A-Z$_:])/i', $identifier, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY ); $identifier = ''; foreach ($parts as $part) { $identifier .= isset($safeWordsInt[strtolower($part)]) ? $part : $this->quoteIdentifier[0] . str_replace($this->quoteIdentifier[0], $this->quoteIdentifierTo, $part) . $this->quoteIdentifier[1]; } return $identifier; } /** * {@inheritDoc} */ public function quoteIdentifier($identifier) { if (! $this->quoteIdentifiers) { return $identifier; } return $this->quoteIdentifier[0] . str_replace($this->quoteIdentifier[0], $this->quoteIdentifierTo, $identifier) . $this->quoteIdentifier[1]; } /** * {@inheritDoc} */ public function quoteIdentifierChain($identifierChain) { return '"' . implode('"."', (array) str_replace('"', '\\"', $identifierChain)) . '"'; } /** * {@inheritDoc} */ public function getQuoteIdentifierSymbol() { return $this->quoteIdentifier[0]; } /** * {@inheritDoc} */ public function getQuoteValueSymbol() { return '\''; } /** * {@inheritDoc} */ public function quoteValue($value) { trigger_error( 'Attempting to quote a value in ' . get_class($this) . ' without extension/driver support can introduce security vulnerabilities in a production environment' ); return '\'' . addcslashes((string) $value, "\x00\n\r\\'\"\x1a") . '\''; } /** * {@inheritDoc} */ public function quoteTrustedValue($value) { return '\'' . addcslashes((string) $value, "\x00\n\r\\'\"\x1a") . '\''; } /** * {@inheritDoc} */ public function quoteValueList($valueList) { return implode(', ', array_map([$this, 'quoteValue'], (array) $valueList)); } /** * {@inheritDoc} */ public function getIdentifierSeparator() { return '.'; } } zend-db-release-2.8.1/src/Adapter/Platform/IbmDb2.php000066400000000000000000000066101270372430400221730ustar00rootroot00000000000000quoteIdentifiers = false; } if (isset($options['identifier_separator'])) { $this->identifierSeparator = $options['identifier_separator']; } } /** * {@inheritDoc} */ public function getName() { return 'IBM DB2'; } /** * {@inheritDoc} */ public function quoteIdentifierInFragment($identifier, array $safeWords = []) { if (! $this->quoteIdentifiers) { return $identifier; } $safeWordsInt = ['*' => true, ' ' => true, '.' => true, 'as' => true]; foreach ($safeWords as $sWord) { $safeWordsInt[strtolower($sWord)] = true; } $parts = preg_split( '/([^0-9,a-z,A-Z$#_:])/i', $identifier, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY ); $identifier = ''; foreach ($parts as $part) { $identifier .= isset($safeWordsInt[strtolower($part)]) ? $part : $this->quoteIdentifier[0] . str_replace($this->quoteIdentifier[0], $this->quoteIdentifierTo, $part) . $this->quoteIdentifier[1]; } return $identifier; } /** * {@inheritDoc} */ public function quoteIdentifierChain($identifierChain) { if ($this->quoteIdentifiers === false) { return (is_array($identifierChain)) ? implode($this->identifierSeparator, $identifierChain) : $identifierChain; } $identifierChain = str_replace('"', '\\"', $identifierChain); if (is_array($identifierChain)) { $identifierChain = implode('"' . $this->identifierSeparator . '"', $identifierChain); } return '"' . $identifierChain . '"'; } /** * {@inheritDoc} */ public function quoteValue($value) { if (function_exists('db2_escape_string')) { return '\'' . db2_escape_string($value) . '\''; } trigger_error( 'Attempting to quote a value in ' . __CLASS__ . ' without extension/driver support ' . 'can introduce security vulnerabilities in a production environment.' ); return '\'' . str_replace("'", "''", $value) . '\''; } /** * {@inheritDoc} */ public function quoteTrustedValue($value) { if (function_exists('db2_escape_string')) { return '\'' . db2_escape_string($value) . '\''; } return '\'' . str_replace("'", "''", $value) . '\''; } /** * {@inheritDoc} */ public function getIdentifierSeparator() { return $this->identifierSeparator; } } zend-db-release-2.8.1/src/Adapter/Platform/Mysql.php000066400000000000000000000062301270372430400222370ustar00rootroot00000000000000setDriver($driver); } } /** * @param \Zend\Db\Adapter\Driver\Mysqli\Mysqli|\Zend\Db\Adapter\Driver\Pdo\Pdo|\mysqli|\PDO $driver * @throws \Zend\Db\Adapter\Exception\InvalidArgumentException * * @return self */ public function setDriver($driver) { // handle Zend\Db drivers if ($driver instanceof Mysqli\Mysqli || ($driver instanceof Pdo\Pdo && $driver->getDatabasePlatformName() == 'Mysql') || ($driver instanceof \mysqli) || ($driver instanceof \PDO && $driver->getAttribute(\PDO::ATTR_DRIVER_NAME) == 'mysql') ) { $this->resource = $driver; return $this; } throw new Exception\InvalidArgumentException('$driver must be a Mysqli or Mysql PDO Zend\Db\Adapter\Driver, Mysqli instance or MySQL PDO instance'); } /** * {@inheritDoc} */ public function getName() { return 'MySQL'; } /** * {@inheritDoc} */ public function quoteIdentifierChain($identifierChain) { return '`' . implode('`.`', (array) str_replace('`', '``', $identifierChain)) . '`'; } /** * {@inheritDoc} */ public function quoteValue($value) { if ($this->resource instanceof DriverInterface) { $this->resource = $this->resource->getConnection()->getResource(); } if ($this->resource instanceof \mysqli) { return '\'' . $this->resource->real_escape_string($value) . '\''; } if ($this->resource instanceof \PDO) { return $this->resource->quote($value); } return parent::quoteValue($value); } /** * {@inheritDoc} */ public function quoteTrustedValue($value) { if ($this->resource instanceof DriverInterface) { $this->resource = $this->resource->getConnection()->getResource(); } if ($this->resource instanceof \mysqli) { return '\'' . $this->resource->real_escape_string($value) . '\''; } if ($this->resource instanceof \PDO) { return $this->resource->quote($value); } return parent::quoteTrustedValue($value); } } zend-db-release-2.8.1/src/Adapter/Platform/Oracle.php000066400000000000000000000070341270372430400223420ustar00rootroot00000000000000quoteIdentifiers = false; } if ($driver) { $this->setDriver($driver); } } /** * @param Pdo|Oci8 $driver * @throws InvalidArgumentException * @return $this */ public function setDriver($driver) { if ($driver instanceof Oci8 || ($driver instanceof Pdo && $driver->getDatabasePlatformName() == 'Oracle') || ($driver instanceof Pdo && $driver->getDatabasePlatformName() == 'Sqlite') || ($driver instanceof \oci8) || ($driver instanceof PDO && $driver->getAttribute(PDO::ATTR_DRIVER_NAME) == 'oci') ) { $this->resource = $driver; return $this; } throw new InvalidArgumentException( '$driver must be a Oci8 or Oracle PDO Zend\Db\Adapter\Driver, ' . 'Oci8 instance, or Oci PDO instance' ); } /** * @return null|Pdo|Oci8 */ public function getDriver() { return $this->resource; } /** * {@inheritDoc} */ public function getName() { return 'Oracle'; } /** * {@inheritDoc} */ public function quoteIdentifierChain($identifierChain) { if ($this->quoteIdentifiers === false) { return implode('.', (array) $identifierChain); } return '"' . implode('"."', (array) str_replace('"', '\\"', $identifierChain)) . '"'; } /** * {@inheritDoc} */ public function quoteValue($value) { if ($this->resource instanceof DriverInterface) { $this->resource = $this->resource->getConnection()->getResource(); } if ($this->resource) { if ($this->resource instanceof PDO) { return $this->resource->quote($value); } if (get_resource_type($this->resource) == 'oci8 connection' || get_resource_type($this->resource) == 'oci8 persistent connection' ) { return "'" . addcslashes(str_replace("'", "''", $value), "\x00\n\r\"\x1a") . "'"; } } trigger_error( 'Attempting to quote a value in ' . __CLASS__ . ' without extension/driver support ' . 'can introduce security vulnerabilities in a production environment.' ); return "'" . addcslashes(str_replace("'", "''", $value), "\x00\n\r\"\x1a") . "'"; } /** * {@inheritDoc} */ public function quoteTrustedValue($value) { return "'" . addcslashes(str_replace('\'', '\'\'', $value), "\x00\n\r\"\x1a") . "'"; } } zend-db-release-2.8.1/src/Adapter/Platform/PlatformInterface.php000066400000000000000000000037341270372430400245450ustar00rootroot00000000000000setDriver($driver); } } /** * @param \Zend\Db\Adapter\Driver\Pgsql\Pgsql|\Zend\Db\Adapter\Driver\Pdo\Pdo|resource|\PDO $driver * @throws \Zend\Db\Adapter\Exception\InvalidArgumentException * @return $this */ public function setDriver($driver) { if ($driver instanceof Pgsql\Pgsql || ($driver instanceof Pdo\Pdo && $driver->getDatabasePlatformName() == 'Postgresql') || (is_resource($driver) && (in_array(get_resource_type($driver), ['pgsql link', 'pgsql link persistent']))) || ($driver instanceof \PDO && $driver->getAttribute(\PDO::ATTR_DRIVER_NAME) == 'pgsql') ) { $this->resource = $driver; return $this; } throw new Exception\InvalidArgumentException('$driver must be a Pgsql or Postgresql PDO Zend\Db\Adapter\Driver, pgsql link resource or Postgresql PDO instance'); } /** * {@inheritDoc} */ public function getName() { return 'PostgreSQL'; } /** * {@inheritDoc} */ public function quoteIdentifierChain($identifierChain) { return '"' . implode('"."', (array) str_replace('"', '""', $identifierChain)) . '"'; } /** * {@inheritDoc} */ public function quoteValue($value) { if ($this->resource instanceof DriverInterface) { $this->resource = $this->resource->getConnection()->getResource(); } if (is_resource($this->resource)) { return '\'' . pg_escape_string($this->resource, $value) . '\''; } if ($this->resource instanceof \PDO) { return $this->resource->quote($value); } return 'E' . parent::quoteValue($value); } /** * {@inheritDoc} */ public function quoteTrustedValue($value) { if ($this->resource instanceof DriverInterface) { $this->resource = $this->resource->getConnection()->getResource(); } if (is_resource($this->resource)) { return '\'' . pg_escape_string($this->resource, $value) . '\''; } if ($this->resource instanceof \PDO) { return $this->resource->quote($value); } return 'E' . parent::quoteTrustedValue($value); } } zend-db-release-2.8.1/src/Adapter/Platform/Sql92.php000066400000000000000000000015221270372430400220430ustar00rootroot00000000000000setDriver($driver); } } /** * @param \Zend\Db\Adapter\Driver\Sqlsrv\Sqlsrv|\Zend\Db\Adapter\Driver\Pdo\Pdo|resource|\PDO $driver * @throws \Zend\Db\Adapter\Exception\InvalidArgumentException * * @return self */ public function setDriver($driver) { // handle Zend\Db drivers if (($driver instanceof Pdo\Pdo && in_array($driver->getDatabasePlatformName(), ['SqlServer', 'Dblib'])) || (($driver instanceof \PDO && in_array($driver->getAttribute(\PDO::ATTR_DRIVER_NAME), ['sqlsrv', 'dblib']))) ) { $this->resource = $driver; return $this; } throw new Exception\InvalidArgumentException('$driver must be a Sqlsrv PDO Zend\Db\Adapter\Driver or Sqlsrv PDO instance'); } /** * {@inheritDoc} */ public function getName() { return 'SQLServer'; } /** * {@inheritDoc} */ public function getQuoteIdentifierSymbol() { return $this->quoteIdentifier; } /** * {@inheritDoc} */ public function quoteIdentifierChain($identifierChain) { return '[' . implode('].[', (array) $identifierChain) . ']'; } /** * {@inheritDoc} */ public function quoteValue($value) { if ($this->resource instanceof DriverInterface) { $this->resource = $this->resource->getConnection()->getResource(); } if ($this->resource instanceof \PDO) { return $this->resource->quote($value); } trigger_error( 'Attempting to quote a value in ' . __CLASS__ . ' without extension/driver support ' . 'can introduce security vulnerabilities in a production environment.' ); return '\'' . str_replace('\'', '\'\'', addcslashes($value, "\000\032")) . '\''; } /** * {@inheritDoc} */ public function quoteTrustedValue($value) { if ($this->resource instanceof DriverInterface) { $this->resource = $this->resource->getConnection()->getResource(); } if ($this->resource instanceof \PDO) { return $this->resource->quote($value); } return '\'' . str_replace('\'', '\'\'', $value) . '\''; } } zend-db-release-2.8.1/src/Adapter/Platform/Sqlite.php000066400000000000000000000046621270372430400224020ustar00rootroot00000000000000setDriver($driver); } } /** * @param \Zend\Db\Adapter\Driver\Pdo\Pdo|\PDO $driver * @throws \Zend\Db\Adapter\Exception\InvalidArgumentException * * @return self */ public function setDriver($driver) { if (($driver instanceof \PDO && $driver->getAttribute(\PDO::ATTR_DRIVER_NAME) == 'sqlite') || ($driver instanceof Pdo\Pdo && $driver->getDatabasePlatformName() == 'Sqlite') ) { $this->resource = $driver; return $this; } throw new Exception\InvalidArgumentException('$driver must be a Sqlite PDO Zend\Db\Adapter\Driver, Sqlite PDO instance'); } /** * {@inheritDoc} */ public function getName() { return 'SQLite'; } /** * {@inheritDoc} */ public function quoteValue($value) { $resource = $this->resource; if ($resource instanceof DriverInterface) { $resource = $resource->getConnection()->getResource(); } if ($resource instanceof \PDO) { return $resource->quote($value); } return parent::quoteValue($value); } /** * {@inheritDoc} */ public function quoteTrustedValue($value) { $resource = $this->resource; if ($resource instanceof DriverInterface) { $resource = $resource->getConnection()->getResource(); } if ($resource instanceof \PDO) { return $resource->quote($value); } return parent::quoteTrustedValue($value); } } zend-db-release-2.8.1/src/Adapter/Profiler/000077500000000000000000000000001270372430400204165ustar00rootroot00000000000000zend-db-release-2.8.1/src/Adapter/Profiler/Profiler.php000066400000000000000000000044121270372430400227120ustar00rootroot00000000000000 '', 'parameters' => null, 'start' => microtime(true), 'end' => null, 'elapse' => null ]; if ($target instanceof StatementContainerInterface) { $profileInformation['sql'] = $target->getSql(); $profileInformation['parameters'] = clone $target->getParameterContainer(); } elseif (is_string($target)) { $profileInformation['sql'] = $target; } else { throw new Exception\InvalidArgumentException(__FUNCTION__ . ' takes either a StatementContainer or a string'); } $this->profiles[$this->currentIndex] = $profileInformation; return $this; } /** * @return Profiler */ public function profilerFinish() { if (!isset($this->profiles[$this->currentIndex])) { throw new Exception\RuntimeException('A profile must be started before ' . __FUNCTION__ . ' can be called.'); } $current = &$this->profiles[$this->currentIndex]; $current['end'] = microtime(true); $current['elapse'] = $current['end'] - $current['start']; $this->currentIndex++; return $this; } /** * @return array|null */ public function getLastProfile() { return end($this->profiles); } /** * @return array */ public function getProfiles() { return $this->profiles; } } zend-db-release-2.8.1/src/Adapter/Profiler/ProfilerAwareInterface.php000066400000000000000000000007711270372430400255170ustar00rootroot00000000000000setSql($sql); } $this->parameterContainer = ($parameterContainer) ?: new ParameterContainer; } /** * @param $sql * @return StatementContainer */ public function setSql($sql) { $this->sql = $sql; return $this; } /** * @return string */ public function getSql() { return $this->sql; } /** * @param ParameterContainer $parameterContainer * @return StatementContainer */ public function setParameterContainer(ParameterContainer $parameterContainer) { $this->parameterContainer = $parameterContainer; return $this; } /** * @return null|ParameterContainer */ public function getParameterContainer() { return $this->parameterContainer; } } zend-db-release-2.8.1/src/Adapter/StatementContainerInterface.php000066400000000000000000000016231270372430400247770ustar00rootroot00000000000000 $this->getDependencyConfig(), ]; } /** * Retrieve zend-db default dependency configuration. * * @return array */ public function getDependencyConfig() { return [ 'abstract_factories' => [ Adapter\AdapterAbstractServiceFactory::class, ], 'factories' => [ Adapter\AdapterInterface::class => Adapter\AdapterServiceFactory::class, ], ]; } } zend-db-release-2.8.1/src/Exception/000077500000000000000000000000001270372430400172125ustar00rootroot00000000000000zend-db-release-2.8.1/src/Exception/ErrorException.php000066400000000000000000000006361270372430400227000ustar00rootroot00000000000000source = Source\Factory::createSourceFromAdapter($adapter); } /** * {@inheritdoc} */ public function getTables($schema = null, $includeViews = false) { return $this->source->getTables($schema, $includeViews); } /** * {@inheritdoc} */ public function getViews($schema = null) { return $this->source->getViews($schema); } /** * {@inheritdoc} */ public function getTriggers($schema = null) { return $this->source->getTriggers($schema); } /** * {@inheritdoc} */ public function getConstraints($table, $schema = null) { return $this->source->getConstraints($table, $schema); } /** * {@inheritdoc} */ public function getColumns($table, $schema = null) { return $this->source->getColumns($table, $schema); } /** * {@inheritdoc} */ public function getConstraintKeys($constraint, $table, $schema = null) { return $this->source->getConstraintKeys($constraint, $table, $schema); } /** * {@inheritdoc} */ public function getConstraint($constraintName, $table, $schema = null) { return $this->source->getConstraint($constraintName, $table, $schema); } /** * {@inheritdoc} */ public function getSchemas() { return $this->source->getSchemas(); } /** * {@inheritdoc} */ public function getTableNames($schema = null, $includeViews = false) { return $this->source->getTableNames($schema, $includeViews); } /** * {@inheritdoc} */ public function getTable($tableName, $schema = null) { return $this->source->getTable($tableName, $schema); } /** * {@inheritdoc} */ public function getViewNames($schema = null) { return $this->source->getViewNames($schema); } /** * {@inheritdoc} */ public function getView($viewName, $schema = null) { return $this->source->getView($viewName, $schema); } /** * {@inheritdoc} */ public function getTriggerNames($schema = null) { return $this->source->getTriggerNames($schema); } /** * {@inheritdoc} */ public function getTrigger($triggerName, $schema = null) { return $this->source->getTrigger($triggerName, $schema); } /** * {@inheritdoc} */ public function getColumnNames($table, $schema = null) { return $this->source->getColumnNames($table, $schema); } /** * {@inheritdoc} */ public function getColumn($columnName, $table, $schema = null) { return $this->source->getColumn($columnName, $table, $schema); } } zend-db-release-2.8.1/src/Metadata/MetadataInterface.php000066400000000000000000000066621270372430400230600ustar00rootroot00000000000000setName($name); } } /** * Set columns * * @param array $columns */ public function setColumns(array $columns) { $this->columns = $columns; } /** * Get columns * * @return array */ public function getColumns() { return $this->columns; } /** * Set constraints * * @param array $constraints */ public function setConstraints($constraints) { $this->constraints = $constraints; } /** * Get constraints * * @return array */ public function getConstraints() { return $this->constraints; } /** * Set name * * @param string $name */ public function setName($name) { $this->name = $name; } /** * Get name * * @return string */ public function getName() { return $this->name; } } zend-db-release-2.8.1/src/Metadata/Object/ColumnObject.php000066400000000000000000000162211270372430400233010ustar00rootroot00000000000000setName($name); $this->setTableName($tableName); $this->setSchemaName($schemaName); } /** * Set name * * @param string $name */ public function setName($name) { $this->name = $name; } /** * Get name * * @return string */ public function getName() { return $this->name; } /** * Get table name * * @return string */ public function getTableName() { return $this->tableName; } /** * Set table name * * @param string $tableName * @return ColumnObject */ public function setTableName($tableName) { $this->tableName = $tableName; return $this; } /** * Set schema name * * @param string $schemaName */ public function setSchemaName($schemaName) { $this->schemaName = $schemaName; } /** * Get schema name * * @return string */ public function getSchemaName() { return $this->schemaName; } /** * @return int $ordinalPosition */ public function getOrdinalPosition() { return $this->ordinalPosition; } /** * @param int $ordinalPosition to set * @return ColumnObject */ public function setOrdinalPosition($ordinalPosition) { $this->ordinalPosition = $ordinalPosition; return $this; } /** * @return null|string the $columnDefault */ public function getColumnDefault() { return $this->columnDefault; } /** * @param mixed $columnDefault to set * @return ColumnObject */ public function setColumnDefault($columnDefault) { $this->columnDefault = $columnDefault; return $this; } /** * @return bool $isNullable */ public function getIsNullable() { return $this->isNullable; } /** * @param bool $isNullable to set * @return ColumnObject */ public function setIsNullable($isNullable) { $this->isNullable = $isNullable; return $this; } /** * @return bool $isNullable */ public function isNullable() { return $this->isNullable; } /** * @return null|string the $dataType */ public function getDataType() { return $this->dataType; } /** * @param string $dataType the $dataType to set * @return ColumnObject */ public function setDataType($dataType) { $this->dataType = $dataType; return $this; } /** * @return int|null the $characterMaximumLength */ public function getCharacterMaximumLength() { return $this->characterMaximumLength; } /** * @param int $characterMaximumLength the $characterMaximumLength to set * @return ColumnObject */ public function setCharacterMaximumLength($characterMaximumLength) { $this->characterMaximumLength = $characterMaximumLength; return $this; } /** * @return int|null the $characterOctetLength */ public function getCharacterOctetLength() { return $this->characterOctetLength; } /** * @param int $characterOctetLength the $characterOctetLength to set * @return ColumnObject */ public function setCharacterOctetLength($characterOctetLength) { $this->characterOctetLength = $characterOctetLength; return $this; } /** * @return int the $numericPrecision */ public function getNumericPrecision() { return $this->numericPrecision; } /** * @param int $numericPrecision the $numericPrevision to set * @return ColumnObject */ public function setNumericPrecision($numericPrecision) { $this->numericPrecision = $numericPrecision; return $this; } /** * @return int the $numericScale */ public function getNumericScale() { return $this->numericScale; } /** * @param int $numericScale the $numericScale to set * @return ColumnObject */ public function setNumericScale($numericScale) { $this->numericScale = $numericScale; return $this; } /** * @return bool */ public function getNumericUnsigned() { return $this->numericUnsigned; } /** * @param bool $numericUnsigned * @return ColumnObject */ public function setNumericUnsigned($numericUnsigned) { $this->numericUnsigned = $numericUnsigned; return $this; } /** * @return bool */ public function isNumericUnsigned() { return $this->numericUnsigned; } /** * @return array the $errata */ public function getErratas() { return $this->errata; } /** * @param array $erratas * @return ColumnObject */ public function setErratas(array $erratas) { foreach ($erratas as $name => $value) { $this->setErrata($name, $value); } return $this; } /** * @param string $errataName * @return mixed */ public function getErrata($errataName) { if (array_key_exists($errataName, $this->errata)) { return $this->errata[$errataName]; } return; } /** * @param string $errataName * @param mixed $errataValue * @return ColumnObject */ public function setErrata($errataName, $errataValue) { $this->errata[$errataName] = $errataValue; return $this; } } zend-db-release-2.8.1/src/Metadata/Object/ConstraintKeyObject.php000066400000000000000000000116731270372430400246470ustar00rootroot00000000000000setColumnName($column); } /** * Get column name * * @return string */ public function getColumnName() { return $this->columnName; } /** * Set column name * * @param string $columnName * @return ConstraintKeyObject */ public function setColumnName($columnName) { $this->columnName = $columnName; return $this; } /** * Get ordinal position * * @return int */ public function getOrdinalPosition() { return $this->ordinalPosition; } /** * Set ordinal position * * @param int $ordinalPosition * @return ConstraintKeyObject */ public function setOrdinalPosition($ordinalPosition) { $this->ordinalPosition = $ordinalPosition; return $this; } /** * Get position in unique constraint * * @return bool */ public function getPositionInUniqueConstraint() { return $this->positionInUniqueConstraint; } /** * Set position in unique constraint * * @param bool $positionInUniqueConstraint * @return ConstraintKeyObject */ public function setPositionInUniqueConstraint($positionInUniqueConstraint) { $this->positionInUniqueConstraint = $positionInUniqueConstraint; return $this; } /** * Get referencred table schema * * @return string */ public function getReferencedTableSchema() { return $this->referencedTableSchema; } /** * Set referenced table schema * * @param string $referencedTableSchema * @return ConstraintKeyObject */ public function setReferencedTableSchema($referencedTableSchema) { $this->referencedTableSchema = $referencedTableSchema; return $this; } /** * Get referenced table name * * @return string */ public function getReferencedTableName() { return $this->referencedTableName; } /** * Set Referenced table name * * @param string $referencedTableName * @return ConstraintKeyObject */ public function setReferencedTableName($referencedTableName) { $this->referencedTableName = $referencedTableName; return $this; } /** * Get referenced column name * * @return string */ public function getReferencedColumnName() { return $this->referencedColumnName; } /** * Set referenced column name * * @param string $referencedColumnName * @return ConstraintKeyObject */ public function setReferencedColumnName($referencedColumnName) { $this->referencedColumnName = $referencedColumnName; return $this; } /** * set foreign key update rule * * @param string $foreignKeyUpdateRule */ public function setForeignKeyUpdateRule($foreignKeyUpdateRule) { $this->foreignKeyUpdateRule = $foreignKeyUpdateRule; } /** * Get foreign key update rule * * @return string */ public function getForeignKeyUpdateRule() { return $this->foreignKeyUpdateRule; } /** * Set foreign key delete rule * * @param string $foreignKeyDeleteRule */ public function setForeignKeyDeleteRule($foreignKeyDeleteRule) { $this->foreignKeyDeleteRule = $foreignKeyDeleteRule; } /** * get foreign key delete rule * * @return string */ public function getForeignKeyDeleteRule() { return $this->foreignKeyDeleteRule; } } zend-db-release-2.8.1/src/Metadata/Object/ConstraintObject.php000066400000000000000000000155701270372430400241760ustar00rootroot00000000000000setName($name); $this->setTableName($tableName); $this->setSchemaName($schemaName); } /** * Set name * * @param string $name */ public function setName($name) { $this->name = $name; } /** * Get name * * @return string */ public function getName() { return $this->name; } /** * Set schema name * * @param string $schemaName */ public function setSchemaName($schemaName) { $this->schemaName = $schemaName; } /** * Get schema name * * @return string */ public function getSchemaName() { return $this->schemaName; } /** * Get table name * * @return string */ public function getTableName() { return $this->tableName; } /** * Set table name * * @param string $tableName * @return ConstraintObject */ public function setTableName($tableName) { $this->tableName = $tableName; return $this; } /** * Set type * * @param string $type */ public function setType($type) { $this->type = $type; } /** * Get type * * @return string */ public function getType() { return $this->type; } public function hasColumns() { return (!empty($this->columns)); } /** * Get Columns. * * @return string[] */ public function getColumns() { return $this->columns; } /** * Set Columns. * * @param string[] $columns * @return ConstraintObject */ public function setColumns(array $columns) { $this->columns = $columns; return $this; } /** * Get Referenced Table Schema. * * @return string */ public function getReferencedTableSchema() { return $this->referencedTableSchema; } /** * Set Referenced Table Schema. * * @param string $referencedTableSchema * @return ConstraintObject */ public function setReferencedTableSchema($referencedTableSchema) { $this->referencedTableSchema = $referencedTableSchema; return $this; } /** * Get Referenced Table Name. * * @return string */ public function getReferencedTableName() { return $this->referencedTableName; } /** * Set Referenced Table Name. * * @param string $referencedTableName * @return ConstraintObject */ public function setReferencedTableName($referencedTableName) { $this->referencedTableName = $referencedTableName; return $this; } /** * Get Referenced Columns. * * @return string[] */ public function getReferencedColumns() { return $this->referencedColumns; } /** * Set Referenced Columns. * * @param string[] $referencedColumns * @return ConstraintObject */ public function setReferencedColumns(array $referencedColumns) { $this->referencedColumns = $referencedColumns; return $this; } /** * Get Match Option. * * @return string */ public function getMatchOption() { return $this->matchOption; } /** * Set Match Option. * * @param string $matchOption * @return ConstraintObject */ public function setMatchOption($matchOption) { $this->matchOption = $matchOption; return $this; } /** * Get Update Rule. * * @return string */ public function getUpdateRule() { return $this->updateRule; } /** * Set Update Rule. * * @param string $updateRule * @return ConstraintObject */ public function setUpdateRule($updateRule) { $this->updateRule = $updateRule; return $this; } /** * Get Delete Rule. * * @return string */ public function getDeleteRule() { return $this->deleteRule; } /** * Set Delete Rule. * * @param string $deleteRule * @return ConstraintObject */ public function setDeleteRule($deleteRule) { $this->deleteRule = $deleteRule; return $this; } /** * Get Check Clause. * * @return string */ public function getCheckClause() { return $this->checkClause; } /** * Set Check Clause. * * @param string $checkClause * @return ConstraintObject */ public function setCheckClause($checkClause) { $this->checkClause = $checkClause; return $this; } /** * Is primary key * * @return bool */ public function isPrimaryKey() { return ('PRIMARY KEY' == $this->type); } /** * Is unique key * * @return bool */ public function isUnique() { return ('UNIQUE' == $this->type); } /** * Is foreign key * * @return bool */ public function isForeignKey() { return ('FOREIGN KEY' == $this->type); } /** * Is foreign key * * @return bool */ public function isCheck() { return ('CHECK' == $this->type); } } zend-db-release-2.8.1/src/Metadata/Object/TableObject.php000066400000000000000000000006141270372430400230720ustar00rootroot00000000000000name; } /** * Set Name. * * @param string $name * @return TriggerObject */ public function setName($name) { $this->name = $name; return $this; } /** * Get Event Manipulation. * * @return string */ public function getEventManipulation() { return $this->eventManipulation; } /** * Set Event Manipulation. * * @param string $eventManipulation * @return TriggerObject */ public function setEventManipulation($eventManipulation) { $this->eventManipulation = $eventManipulation; return $this; } /** * Get Event Object Catalog. * * @return string */ public function getEventObjectCatalog() { return $this->eventObjectCatalog; } /** * Set Event Object Catalog. * * @param string $eventObjectCatalog * @return TriggerObject */ public function setEventObjectCatalog($eventObjectCatalog) { $this->eventObjectCatalog = $eventObjectCatalog; return $this; } /** * Get Event Object Schema. * * @return string */ public function getEventObjectSchema() { return $this->eventObjectSchema; } /** * Set Event Object Schema. * * @param string $eventObjectSchema * @return TriggerObject */ public function setEventObjectSchema($eventObjectSchema) { $this->eventObjectSchema = $eventObjectSchema; return $this; } /** * Get Event Object Table. * * @return string */ public function getEventObjectTable() { return $this->eventObjectTable; } /** * Set Event Object Table. * * @param string $eventObjectTable * @return TriggerObject */ public function setEventObjectTable($eventObjectTable) { $this->eventObjectTable = $eventObjectTable; return $this; } /** * Get Action Order. * * @return string */ public function getActionOrder() { return $this->actionOrder; } /** * Set Action Order. * * @param string $actionOrder * @return TriggerObject */ public function setActionOrder($actionOrder) { $this->actionOrder = $actionOrder; return $this; } /** * Get Action Condition. * * @return string */ public function getActionCondition() { return $this->actionCondition; } /** * Set Action Condition. * * @param string $actionCondition * @return TriggerObject */ public function setActionCondition($actionCondition) { $this->actionCondition = $actionCondition; return $this; } /** * Get Action Statement. * * @return string */ public function getActionStatement() { return $this->actionStatement; } /** * Set Action Statement. * * @param string $actionStatement * @return TriggerObject */ public function setActionStatement($actionStatement) { $this->actionStatement = $actionStatement; return $this; } /** * Get Action Orientation. * * @return string */ public function getActionOrientation() { return $this->actionOrientation; } /** * Set Action Orientation. * * @param string $actionOrientation * @return TriggerObject */ public function setActionOrientation($actionOrientation) { $this->actionOrientation = $actionOrientation; return $this; } /** * Get Action Timing. * * @return string */ public function getActionTiming() { return $this->actionTiming; } /** * Set Action Timing. * * @param string $actionTiming * @return TriggerObject */ public function setActionTiming($actionTiming) { $this->actionTiming = $actionTiming; return $this; } /** * Get Action Reference Old Table. * * @return string */ public function getActionReferenceOldTable() { return $this->actionReferenceOldTable; } /** * Set Action Reference Old Table. * * @param string $actionReferenceOldTable * @return TriggerObject */ public function setActionReferenceOldTable($actionReferenceOldTable) { $this->actionReferenceOldTable = $actionReferenceOldTable; return $this; } /** * Get Action Reference New Table. * * @return string */ public function getActionReferenceNewTable() { return $this->actionReferenceNewTable; } /** * Set Action Reference New Table. * * @param string $actionReferenceNewTable * @return TriggerObject */ public function setActionReferenceNewTable($actionReferenceNewTable) { $this->actionReferenceNewTable = $actionReferenceNewTable; return $this; } /** * Get Action Reference Old Row. * * @return string */ public function getActionReferenceOldRow() { return $this->actionReferenceOldRow; } /** * Set Action Reference Old Row. * * @param string $actionReferenceOldRow * @return TriggerObject */ public function setActionReferenceOldRow($actionReferenceOldRow) { $this->actionReferenceOldRow = $actionReferenceOldRow; return $this; } /** * Get Action Reference New Row. * * @return string */ public function getActionReferenceNewRow() { return $this->actionReferenceNewRow; } /** * Set Action Reference New Row. * * @param string $actionReferenceNewRow * @return TriggerObject */ public function setActionReferenceNewRow($actionReferenceNewRow) { $this->actionReferenceNewRow = $actionReferenceNewRow; return $this; } /** * Get Created. * * @return \DateTime */ public function getCreated() { return $this->created; } /** * Set Created. * * @param \DateTime $created * @return TriggerObject */ public function setCreated($created) { $this->created = $created; return $this; } } zend-db-release-2.8.1/src/Metadata/Object/ViewObject.php000066400000000000000000000031261270372430400227560ustar00rootroot00000000000000viewDefinition; } /** * @param string $viewDefinition to set * @return ViewObject */ public function setViewDefinition($viewDefinition) { $this->viewDefinition = $viewDefinition; return $this; } /** * @return string $checkOption */ public function getCheckOption() { return $this->checkOption; } /** * @param string $checkOption to set * @return ViewObject */ public function setCheckOption($checkOption) { $this->checkOption = $checkOption; return $this; } /** * @return bool $isUpdatable */ public function getIsUpdatable() { return $this->isUpdatable; } /** * @param bool $isUpdatable to set * @return ViewObject */ public function setIsUpdatable($isUpdatable) { $this->isUpdatable = $isUpdatable; return $this; } public function isUpdatable() { return $this->isUpdatable; } } zend-db-release-2.8.1/src/Metadata/Source/000077500000000000000000000000001270372430400202345ustar00rootroot00000000000000zend-db-release-2.8.1/src/Metadata/Source/AbstractSource.php000066400000000000000000000363321270372430400237000ustar00rootroot00000000000000adapter = $adapter; $this->defaultSchema = ($adapter->getCurrentSchema()) ?: self::DEFAULT_SCHEMA; } /** * Get schemas * */ public function getSchemas() { $this->loadSchemaData(); return $this->data['schemas']; } /** * {@inheritdoc} */ public function getTableNames($schema = null, $includeViews = false) { if ($schema === null) { $schema = $this->defaultSchema; } $this->loadTableNameData($schema); if ($includeViews) { return array_keys($this->data['table_names'][$schema]); } $tableNames = []; foreach ($this->data['table_names'][$schema] as $tableName => $data) { if ('BASE TABLE' == $data['table_type']) { $tableNames[] = $tableName; } } return $tableNames; } /** * {@inheritdoc} */ public function getTables($schema = null, $includeViews = false) { if ($schema === null) { $schema = $this->defaultSchema; } $tables = []; foreach ($this->getTableNames($schema, $includeViews) as $tableName) { $tables[] = $this->getTable($tableName, $schema); } return $tables; } /** * {@inheritdoc} */ public function getTable($tableName, $schema = null) { if ($schema === null) { $schema = $this->defaultSchema; } $this->loadTableNameData($schema); if (!isset($this->data['table_names'][$schema][$tableName])) { throw new \Exception('Table "' . $tableName . '" does not exist'); } $data = $this->data['table_names'][$schema][$tableName]; switch ($data['table_type']) { case 'BASE TABLE': $table = new Object\TableObject($tableName); break; case 'VIEW': $table = new Object\ViewObject($tableName); $table->setViewDefinition($data['view_definition']); $table->setCheckOption($data['check_option']); $table->setIsUpdatable($data['is_updatable']); break; default: throw new \Exception('Table "' . $tableName . '" is of an unsupported type "' . $data['table_type'] . '"'); } $table->setColumns($this->getColumns($tableName, $schema)); $table->setConstraints($this->getConstraints($tableName, $schema)); return $table; } /** * {@inheritdoc} */ public function getViewNames($schema = null) { if ($schema === null) { $schema = $this->defaultSchema; } $this->loadTableNameData($schema); $viewNames = []; foreach ($this->data['table_names'][$schema] as $tableName => $data) { if ('VIEW' == $data['table_type']) { $viewNames[] = $tableName; } } return $viewNames; } /** * {@inheritdoc} */ public function getViews($schema = null) { if ($schema === null) { $schema = $this->defaultSchema; } $views = []; foreach ($this->getViewNames($schema) as $tableName) { $views[] = $this->getTable($tableName, $schema); } return $views; } /** * {@inheritdoc} */ public function getView($viewName, $schema = null) { if ($schema === null) { $schema = $this->defaultSchema; } $this->loadTableNameData($schema); $tableNames = $this->data['table_names'][$schema]; if (isset($tableNames[$viewName]) && 'VIEW' == $tableNames[$viewName]['table_type']) { return $this->getTable($viewName, $schema); } throw new \Exception('View "' . $viewName . '" does not exist'); } /** * {@inheritdoc} */ public function getColumnNames($table, $schema = null) { if ($schema === null) { $schema = $this->defaultSchema; } $this->loadColumnData($table, $schema); if (!isset($this->data['columns'][$schema][$table])) { throw new \Exception('"' . $table . '" does not exist'); } return array_keys($this->data['columns'][$schema][$table]); } /** * {@inheritdoc} */ public function getColumns($table, $schema = null) { if ($schema === null) { $schema = $this->defaultSchema; } $this->loadColumnData($table, $schema); $columns = []; foreach ($this->getColumnNames($table, $schema) as $columnName) { $columns[] = $this->getColumn($columnName, $table, $schema); } return $columns; } /** * {@inheritdoc} */ public function getColumn($columnName, $table, $schema = null) { if ($schema === null) { $schema = $this->defaultSchema; } $this->loadColumnData($table, $schema); if (!isset($this->data['columns'][$schema][$table][$columnName])) { throw new \Exception('A column by that name was not found.'); } $info = $this->data['columns'][$schema][$table][$columnName]; $column = new Object\ColumnObject($columnName, $table, $schema); $props = [ 'ordinal_position', 'column_default', 'is_nullable', 'data_type', 'character_maximum_length', 'character_octet_length', 'numeric_precision', 'numeric_scale', 'numeric_unsigned', 'erratas' ]; foreach ($props as $prop) { if (isset($info[$prop])) { $column->{'set' . str_replace('_', '', $prop)}($info[$prop]); } } $column->setOrdinalPosition($info['ordinal_position']); $column->setColumnDefault($info['column_default']); $column->setIsNullable($info['is_nullable']); $column->setDataType($info['data_type']); $column->setCharacterMaximumLength($info['character_maximum_length']); $column->setCharacterOctetLength($info['character_octet_length']); $column->setNumericPrecision($info['numeric_precision']); $column->setNumericScale($info['numeric_scale']); $column->setNumericUnsigned($info['numeric_unsigned']); $column->setErratas($info['erratas']); return $column; } /** * {@inheritdoc} */ public function getConstraints($table, $schema = null) { if ($schema === null) { $schema = $this->defaultSchema; } $this->loadConstraintData($table, $schema); $constraints = []; foreach (array_keys($this->data['constraints'][$schema][$table]) as $constraintName) { $constraints[] = $this->getConstraint($constraintName, $table, $schema); } return $constraints; } /** * {@inheritdoc} */ public function getConstraint($constraintName, $table, $schema = null) { if ($schema === null) { $schema = $this->defaultSchema; } $this->loadConstraintData($table, $schema); if (!isset($this->data['constraints'][$schema][$table][$constraintName])) { throw new \Exception('Cannot find a constraint by that name in this table'); } $info = $this->data['constraints'][$schema][$table][$constraintName]; $constraint = new Object\ConstraintObject($constraintName, $table, $schema); foreach ([ 'constraint_type' => 'setType', 'match_option' => 'setMatchOption', 'update_rule' => 'setUpdateRule', 'delete_rule' => 'setDeleteRule', 'columns' => 'setColumns', 'referenced_table_schema' => 'setReferencedTableSchema', 'referenced_table_name' => 'setReferencedTableName', 'referenced_columns' => 'setReferencedColumns', 'check_clause' => 'setCheckClause', ] as $key => $setMethod) { if (isset($info[$key])) { $constraint->{$setMethod}($info[$key]); } } return $constraint; } /** * {@inheritdoc} */ public function getConstraintKeys($constraint, $table, $schema = null) { if ($schema === null) { $schema = $this->defaultSchema; } $this->loadConstraintReferences($table, $schema); // organize references first $references = []; foreach ($this->data['constraint_references'][$schema] as $refKeyInfo) { if ($refKeyInfo['constraint_name'] == $constraint) { $references[$refKeyInfo['constraint_name']] = $refKeyInfo; } } $this->loadConstraintDataKeys($schema); $keys = []; foreach ($this->data['constraint_keys'][$schema] as $constraintKeyInfo) { if ($constraintKeyInfo['table_name'] == $table && $constraintKeyInfo['constraint_name'] === $constraint) { $keys[] = $key = new Object\ConstraintKeyObject($constraintKeyInfo['column_name']); $key->setOrdinalPosition($constraintKeyInfo['ordinal_position']); if (isset($references[$constraint])) { //$key->setReferencedTableSchema($constraintKeyInfo['referenced_table_schema']); $key->setForeignKeyUpdateRule($references[$constraint]['update_rule']); $key->setForeignKeyDeleteRule($references[$constraint]['delete_rule']); //$key->setReferencedTableSchema($references[$constraint]['referenced_table_schema']); $key->setReferencedTableName($references[$constraint]['referenced_table_name']); $key->setReferencedColumnName($references[$constraint]['referenced_column_name']); } } } return $keys; } /** * {@inheritdoc} */ public function getTriggerNames($schema = null) { if ($schema === null) { $schema = $this->defaultSchema; } $this->loadTriggerData($schema); return array_keys($this->data['triggers'][$schema]); } /** * {@inheritdoc} */ public function getTriggers($schema = null) { if ($schema === null) { $schema = $this->defaultSchema; } $triggers = []; foreach ($this->getTriggerNames($schema) as $triggerName) { $triggers[] = $this->getTrigger($triggerName, $schema); } return $triggers; } /** * {@inheritdoc} */ public function getTrigger($triggerName, $schema = null) { if ($schema === null) { $schema = $this->defaultSchema; } $this->loadTriggerData($schema); if (!isset($this->data['triggers'][$schema][$triggerName])) { throw new \Exception('Trigger "' . $triggerName . '" does not exist'); } $info = $this->data['triggers'][$schema][$triggerName]; $trigger = new Object\TriggerObject(); $trigger->setName($triggerName); $trigger->setEventManipulation($info['event_manipulation']); $trigger->setEventObjectCatalog($info['event_object_catalog']); $trigger->setEventObjectSchema($info['event_object_schema']); $trigger->setEventObjectTable($info['event_object_table']); $trigger->setActionOrder($info['action_order']); $trigger->setActionCondition($info['action_condition']); $trigger->setActionStatement($info['action_statement']); $trigger->setActionOrientation($info['action_orientation']); $trigger->setActionTiming($info['action_timing']); $trigger->setActionReferenceOldTable($info['action_reference_old_table']); $trigger->setActionReferenceNewTable($info['action_reference_new_table']); $trigger->setActionReferenceOldRow($info['action_reference_old_row']); $trigger->setActionReferenceNewRow($info['action_reference_new_row']); $trigger->setCreated($info['created']); return $trigger; } /** * Prepare data hierarchy * * @param string $type * @param string $key ... */ protected function prepareDataHierarchy($type) { $data = &$this->data; foreach (func_get_args() as $key) { if (!isset($data[$key])) { $data[$key] = []; } $data = &$data[$key]; } } /** * Load schema data */ protected function loadSchemaData() { } /** * Load table name data * * @param string $schema */ protected function loadTableNameData($schema) { if (isset($this->data['table_names'][$schema])) { return; } $this->prepareDataHierarchy('table_names', $schema); } /** * Load column data * * @param string $table * @param string $schema */ protected function loadColumnData($table, $schema) { if (isset($this->data['columns'][$schema][$table])) { return; } $this->prepareDataHierarchy('columns', $schema, $table); } /** * Load constraint data * * @param string $table * @param string $schema */ protected function loadConstraintData($table, $schema) { if (isset($this->data['constraints'][$schema])) { return; } $this->prepareDataHierarchy('constraints', $schema); } /** * Load constraint data keys * * @param string $schema */ protected function loadConstraintDataKeys($schema) { if (isset($this->data['constraint_keys'][$schema])) { return; } $this->prepareDataHierarchy('constraint_keys', $schema); } /** * Load constraint references * * @param string $table * @param string $schema */ protected function loadConstraintReferences($table, $schema) { if (isset($this->data['constraint_references'][$schema])) { return; } $this->prepareDataHierarchy('constraint_references', $schema); } /** * Load trigger data * * @param string $schema */ protected function loadTriggerData($schema) { if (isset($this->data['triggers'][$schema])) { return; } $this->prepareDataHierarchy('triggers', $schema); } } zend-db-release-2.8.1/src/Metadata/Source/Factory.php000066400000000000000000000026351270372430400223620ustar00rootroot00000000000000getPlatform()->getName(); switch ($platformName) { case 'MySQL': return new MysqlMetadata($adapter); case 'SQLServer': return new SqlServerMetadata($adapter); case 'SQLite': return new SqliteMetadata($adapter); case 'PostgreSQL': return new PostgresqlMetadata($adapter); case 'Oracle': return new OracleMetadata($adapter); default: throw new InvalidArgumentException("Unknown adapter platform '{$platformName}'"); } } } zend-db-release-2.8.1/src/Metadata/Source/MysqlMetadata.php000066400000000000000000000461571270372430400235300ustar00rootroot00000000000000data['schemas'])) { return; } $this->prepareDataHierarchy('schemas'); $p = $this->adapter->getPlatform(); $sql = 'SELECT ' . $p->quoteIdentifier('SCHEMA_NAME') . ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'SCHEMATA']) . ' WHERE ' . $p->quoteIdentifier('SCHEMA_NAME') . ' != \'INFORMATION_SCHEMA\''; $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); $schemas = []; foreach ($results->toArray() as $row) { $schemas[] = $row['SCHEMA_NAME']; } $this->data['schemas'] = $schemas; } protected function loadTableNameData($schema) { if (isset($this->data['table_names'][$schema])) { return; } $this->prepareDataHierarchy('table_names', $schema); $p = $this->adapter->getPlatform(); $isColumns = [ ['T', 'TABLE_NAME'], ['T', 'TABLE_TYPE'], ['V', 'VIEW_DEFINITION'], ['V', 'CHECK_OPTION'], ['V', 'IS_UPDATABLE'], ]; array_walk($isColumns, function (&$c) use ($p) { $c = $p->quoteIdentifierChain($c); }); $sql = 'SELECT ' . implode(', ', $isColumns) . ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . 'T' . ' LEFT JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'VIEWS']) . ' V' . ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' = ' . $p->quoteIdentifierChain(['V', 'TABLE_SCHEMA']) . ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME']) . ' = ' . $p->quoteIdentifierChain(['V', 'TABLE_NAME']) . ' WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE']) . ' IN (\'BASE TABLE\', \'VIEW\')'; if ($schema != self::DEFAULT_SCHEMA) { $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' = ' . $p->quoteTrustedValue($schema); } else { $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' != \'INFORMATION_SCHEMA\''; } $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); $tables = []; foreach ($results->toArray() as $row) { $tables[$row['TABLE_NAME']] = [ 'table_type' => $row['TABLE_TYPE'], 'view_definition' => $row['VIEW_DEFINITION'], 'check_option' => $row['CHECK_OPTION'], 'is_updatable' => ('YES' == $row['IS_UPDATABLE']), ]; } $this->data['table_names'][$schema] = $tables; } protected function loadColumnData($table, $schema) { if (isset($this->data['columns'][$schema][$table])) { return; } $this->prepareDataHierarchy('columns', $schema, $table); $p = $this->adapter->getPlatform(); $isColumns = [ ['C', 'ORDINAL_POSITION'], ['C', 'COLUMN_DEFAULT'], ['C', 'IS_NULLABLE'], ['C', 'DATA_TYPE'], ['C', 'CHARACTER_MAXIMUM_LENGTH'], ['C', 'CHARACTER_OCTET_LENGTH'], ['C', 'NUMERIC_PRECISION'], ['C', 'NUMERIC_SCALE'], ['C', 'COLUMN_NAME'], ['C', 'COLUMN_TYPE'], ]; array_walk($isColumns, function (&$c) use ($p) { $c = $p->quoteIdentifierChain($c); }); $sql = 'SELECT ' . implode(', ', $isColumns) . ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . 'T' . ' INNER JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'COLUMNS']) . 'C' . ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' = ' . $p->quoteIdentifierChain(['C', 'TABLE_SCHEMA']) . ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME']) . ' = ' . $p->quoteIdentifierChain(['C', 'TABLE_NAME']) . ' WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE']) . ' IN (\'BASE TABLE\', \'VIEW\')' . ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME']) . ' = ' . $p->quoteTrustedValue($table); if ($schema != self::DEFAULT_SCHEMA) { $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' = ' . $p->quoteTrustedValue($schema); } else { $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' != \'INFORMATION_SCHEMA\''; } $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); $columns = []; foreach ($results->toArray() as $row) { $erratas = []; $matches = []; if (preg_match('/^(?:enum|set)\((.+)\)$/i', $row['COLUMN_TYPE'], $matches)) { $permittedValues = $matches[1]; if (preg_match_all("/\\s*'((?:[^']++|'')*+)'\\s*(?:,|\$)/", $permittedValues, $matches, PREG_PATTERN_ORDER)) { $permittedValues = str_replace("''", "'", $matches[1]); } else { $permittedValues = [$permittedValues]; } $erratas['permitted_values'] = $permittedValues; } $columns[$row['COLUMN_NAME']] = [ 'ordinal_position' => $row['ORDINAL_POSITION'], 'column_default' => $row['COLUMN_DEFAULT'], 'is_nullable' => ('YES' == $row['IS_NULLABLE']), 'data_type' => $row['DATA_TYPE'], 'character_maximum_length' => $row['CHARACTER_MAXIMUM_LENGTH'], 'character_octet_length' => $row['CHARACTER_OCTET_LENGTH'], 'numeric_precision' => $row['NUMERIC_PRECISION'], 'numeric_scale' => $row['NUMERIC_SCALE'], 'numeric_unsigned' => (false !== strpos($row['COLUMN_TYPE'], 'unsigned')), 'erratas' => $erratas, ]; } $this->data['columns'][$schema][$table] = $columns; } protected function loadConstraintData($table, $schema) { if (isset($this->data['constraints'][$schema][$table])) { return; } $this->prepareDataHierarchy('constraints', $schema, $table); $isColumns = [ ['T', 'TABLE_NAME'], ['TC', 'CONSTRAINT_NAME'], ['TC', 'CONSTRAINT_TYPE'], ['KCU', 'COLUMN_NAME'], ['RC', 'MATCH_OPTION'], ['RC', 'UPDATE_RULE'], ['RC', 'DELETE_RULE'], ['KCU', 'REFERENCED_TABLE_SCHEMA'], ['KCU', 'REFERENCED_TABLE_NAME'], ['KCU', 'REFERENCED_COLUMN_NAME'], ]; $p = $this->adapter->getPlatform(); array_walk($isColumns, function (&$c) use ($p) { $c = $p->quoteIdentifierChain($c); }); $sql = 'SELECT ' . implode(', ', $isColumns) . ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . ' T' . ' INNER JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLE_CONSTRAINTS']) . ' TC' . ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' = ' . $p->quoteIdentifierChain(['TC', 'TABLE_SCHEMA']) . ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME']) . ' = ' . $p->quoteIdentifierChain(['TC', 'TABLE_NAME']) . ' LEFT JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'KEY_COLUMN_USAGE']) . ' KCU' . ' ON ' . $p->quoteIdentifierChain(['TC', 'TABLE_SCHEMA']) . ' = ' . $p->quoteIdentifierChain(['KCU', 'TABLE_SCHEMA']) . ' AND ' . $p->quoteIdentifierChain(['TC', 'TABLE_NAME']) . ' = ' . $p->quoteIdentifierChain(['KCU', 'TABLE_NAME']) . ' AND ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_NAME']) . ' = ' . $p->quoteIdentifierChain(['KCU', 'CONSTRAINT_NAME']) . ' LEFT JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'REFERENTIAL_CONSTRAINTS']) . ' RC' . ' ON ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_SCHEMA']) . ' = ' . $p->quoteIdentifierChain(['RC', 'CONSTRAINT_SCHEMA']) . ' AND ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_NAME']) . ' = ' . $p->quoteIdentifierChain(['RC', 'CONSTRAINT_NAME']) . ' WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME']) . ' = ' . $p->quoteTrustedValue($table) . ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE']) . ' IN (\'BASE TABLE\', \'VIEW\')'; if ($schema != self::DEFAULT_SCHEMA) { $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' = ' . $p->quoteTrustedValue($schema); } else { $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' != \'INFORMATION_SCHEMA\''; } $sql .= ' ORDER BY CASE ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_TYPE']) . " WHEN 'PRIMARY KEY' THEN 1" . " WHEN 'UNIQUE' THEN 2" . " WHEN 'FOREIGN KEY' THEN 3" . " ELSE 4 END" . ', ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_NAME']) . ', ' . $p->quoteIdentifierChain(['KCU', 'ORDINAL_POSITION']); $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); $realName = null; $constraints = []; foreach ($results->toArray() as $row) { if ($row['CONSTRAINT_NAME'] !== $realName) { $realName = $row['CONSTRAINT_NAME']; $isFK = ('FOREIGN KEY' == $row['CONSTRAINT_TYPE']); if ($isFK) { $name = $realName; } else { $name = '_zf_' . $row['TABLE_NAME'] . '_' . $realName; } $constraints[$name] = [ 'constraint_name' => $name, 'constraint_type' => $row['CONSTRAINT_TYPE'], 'table_name' => $row['TABLE_NAME'], 'columns' => [], ]; if ($isFK) { $constraints[$name]['referenced_table_schema'] = $row['REFERENCED_TABLE_SCHEMA']; $constraints[$name]['referenced_table_name'] = $row['REFERENCED_TABLE_NAME']; $constraints[$name]['referenced_columns'] = []; $constraints[$name]['match_option'] = $row['MATCH_OPTION']; $constraints[$name]['update_rule'] = $row['UPDATE_RULE']; $constraints[$name]['delete_rule'] = $row['DELETE_RULE']; } } $constraints[$name]['columns'][] = $row['COLUMN_NAME']; if ($isFK) { $constraints[$name]['referenced_columns'][] = $row['REFERENCED_COLUMN_NAME']; } } $this->data['constraints'][$schema][$table] = $constraints; } protected function loadConstraintDataNames($schema) { if (isset($this->data['constraint_names'][$schema])) { return; } $this->prepareDataHierarchy('constraint_names', $schema); $p = $this->adapter->getPlatform(); $isColumns = [ ['TC', 'TABLE_NAME'], ['TC', 'CONSTRAINT_NAME'], ['TC', 'CONSTRAINT_TYPE'], ]; array_walk($isColumns, function (&$c) use ($p) { $c = $p->quoteIdentifierChain($c); }); $sql = 'SELECT ' . implode(', ', $isColumns) . ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . 'T' . ' INNER JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLE_CONSTRAINTS']) . 'TC' . ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' = ' . $p->quoteIdentifierChain(['TC', 'TABLE_SCHEMA']) . ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME']) . ' = ' . $p->quoteIdentifierChain(['TC', 'TABLE_NAME']) . ' WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE']) . ' IN (\'BASE TABLE\', \'VIEW\')'; if ($schema != self::DEFAULT_SCHEMA) { $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' = ' . $p->quoteTrustedValue($schema); } else { $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' != \'INFORMATION_SCHEMA\''; } $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); $data = []; foreach ($results->toArray() as $row) { $data[] = array_change_key_case($row, CASE_LOWER); } $this->data['constraint_names'][$schema] = $data; } protected function loadConstraintDataKeys($schema) { if (isset($this->data['constraint_keys'][$schema])) { return; } $this->prepareDataHierarchy('constraint_keys', $schema); $p = $this->adapter->getPlatform(); $isColumns = [ ['T', 'TABLE_NAME'], ['KCU', 'CONSTRAINT_NAME'], ['KCU', 'COLUMN_NAME'], ['KCU', 'ORDINAL_POSITION'], ]; array_walk($isColumns, function (&$c) use ($p) { $c = $p->quoteIdentifierChain($c); }); $sql = 'SELECT ' . implode(', ', $isColumns) . ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . 'T' . ' INNER JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'KEY_COLUMN_USAGE']) . 'KCU' . ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' = ' . $p->quoteIdentifierChain(['KCU', 'TABLE_SCHEMA']) . ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME']) . ' = ' . $p->quoteIdentifierChain(['KCU', 'TABLE_NAME']) . ' WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE']) . ' IN (\'BASE TABLE\', \'VIEW\')'; if ($schema != self::DEFAULT_SCHEMA) { $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' = ' . $p->quoteTrustedValue($schema); } else { $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' != \'INFORMATION_SCHEMA\''; } $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); $data = []; foreach ($results->toArray() as $row) { $data[] = array_change_key_case($row, CASE_LOWER); } $this->data['constraint_keys'][$schema] = $data; } protected function loadConstraintReferences($table, $schema) { parent::loadConstraintReferences($table, $schema); $p = $this->adapter->getPlatform(); $isColumns = [ ['RC', 'TABLE_NAME'], ['RC', 'CONSTRAINT_NAME'], ['RC', 'UPDATE_RULE'], ['RC', 'DELETE_RULE'], ['KCU', 'REFERENCED_TABLE_SCHEMA'], ['KCU', 'REFERENCED_TABLE_NAME'], ['KCU', 'REFERENCED_COLUMN_NAME'], ]; array_walk($isColumns, function (&$c) use ($p) { $c = $p->quoteIdentifierChain($c); }); $sql = 'SELECT ' . implode(', ', $isColumns) . 'FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . 'T' . ' INNER JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'REFERENTIAL_CONSTRAINTS']) . 'RC' . ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' = ' . $p->quoteIdentifierChain(['RC', 'CONSTRAINT_SCHEMA']) . ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME']) . ' = ' . $p->quoteIdentifierChain(['RC', 'TABLE_NAME']) . ' INNER JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'KEY_COLUMN_USAGE']) . 'KCU' . ' ON ' . $p->quoteIdentifierChain(['RC', 'CONSTRAINT_SCHEMA']) . ' = ' . $p->quoteIdentifierChain(['KCU', 'TABLE_SCHEMA']) . ' AND ' . $p->quoteIdentifierChain(['RC', 'TABLE_NAME']) . ' = ' . $p->quoteIdentifierChain(['KCU', 'TABLE_NAME']) . ' AND ' . $p->quoteIdentifierChain(['RC', 'CONSTRAINT_NAME']) . ' = ' . $p->quoteIdentifierChain(['KCU', 'CONSTRAINT_NAME']) . 'WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE']) . ' IN (\'BASE TABLE\', \'VIEW\')'; if ($schema != self::DEFAULT_SCHEMA) { $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' = ' . $p->quoteTrustedValue($schema); } else { $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' != \'INFORMATION_SCHEMA\''; } $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); $data = []; foreach ($results->toArray() as $row) { $data[] = array_change_key_case($row, CASE_LOWER); } $this->data['constraint_references'][$schema] = $data; } protected function loadTriggerData($schema) { if (isset($this->data['triggers'][$schema])) { return; } $this->prepareDataHierarchy('triggers', $schema); $p = $this->adapter->getPlatform(); $isColumns = [ // 'TRIGGER_CATALOG', // 'TRIGGER_SCHEMA', 'TRIGGER_NAME', 'EVENT_MANIPULATION', 'EVENT_OBJECT_CATALOG', 'EVENT_OBJECT_SCHEMA', 'EVENT_OBJECT_TABLE', 'ACTION_ORDER', 'ACTION_CONDITION', 'ACTION_STATEMENT', 'ACTION_ORIENTATION', 'ACTION_TIMING', 'ACTION_REFERENCE_OLD_TABLE', 'ACTION_REFERENCE_NEW_TABLE', 'ACTION_REFERENCE_OLD_ROW', 'ACTION_REFERENCE_NEW_ROW', 'CREATED', ]; array_walk($isColumns, function (&$c) use ($p) { $c = $p->quoteIdentifier($c); }); $sql = 'SELECT ' . implode(', ', $isColumns) . ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TRIGGERS']) . ' WHERE '; if ($schema != self::DEFAULT_SCHEMA) { $sql .= $p->quoteIdentifier('TRIGGER_SCHEMA') . ' = ' . $p->quoteTrustedValue($schema); } else { $sql .= $p->quoteIdentifier('TRIGGER_SCHEMA') . ' != \'INFORMATION_SCHEMA\''; } $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); $data = []; foreach ($results->toArray() as $row) { $row = array_change_key_case($row, CASE_LOWER); if (null !== $row['created']) { $row['created'] = new \DateTime($row['created']); } $data[$row['trigger_name']] = $row; } $this->data['triggers'][$schema] = $data; } } zend-db-release-2.8.1/src/Metadata/Source/OracleMetadata.php000066400000000000000000000172251270372430400236220ustar00rootroot00000000000000 'CHECK', 'P' => 'PRIMARY KEY', 'R' => 'FOREIGN_KEY' ]; /** * {@inheritdoc} * @see \Zend\Db\Metadata\Source\AbstractSource::loadColumnData() */ protected function loadColumnData($table, $schema) { if (isset($this->data['columns'][$schema][$table])) { return; } $isColumns = [ 'COLUMN_ID', 'COLUMN_NAME', 'DATA_DEFAULT', 'NULLABLE', 'DATA_TYPE', 'DATA_LENGTH', 'DATA_PRECISION', 'DATA_SCALE' ]; $this->prepareDataHierarchy('columns', $schema, $table); $parameters = [ ':ownername' => $schema, ':tablename' => $table ]; $sql = 'SELECT ' . implode(', ', $isColumns) . ' FROM all_tab_columns' . ' WHERE owner = :ownername AND table_name = :tablename'; $result = $this->adapter->query($sql)->execute($parameters); $columns = []; foreach ($result as $row) { $columns[$row['COLUMN_NAME']] = [ 'ordinal_position' => $row['COLUMN_ID'], 'column_default' => $row['DATA_DEFAULT'], 'is_nullable' => ('Y' == $row['NULLABLE']), 'data_type' => $row['DATA_TYPE'], 'character_maximum_length' => $row['DATA_LENGTH'], 'character_octet_length' => null, 'numeric_precision' => $row['DATA_PRECISION'], 'numeric_scale' => $row['DATA_SCALE'], 'numeric_unsigned' => false, 'erratas' => [], ]; } $this->data['columns'][$schema][$table] = $columns; return $this; } /** * Constraint type * * @param string $type * @return string */ protected function getConstraintType($type) { if (isset($this->constraintTypeMap[$type])) { return $this->constraintTypeMap[$type]; } return $type; } /** * {@inheritdoc} * @see \Zend\Db\Metadata\Source\AbstractSource::loadConstraintData() */ protected function loadConstraintData($table, $schema) { if (isset($this->data['constraints'][$schema][$table])) { return; } $this->prepareDataHierarchy('constraints', $schema, $table); $sql = ' SELECT ac.owner, ac.constraint_name, ac.constraint_type, ac.search_condition check_clause, ac.table_name, ac.delete_rule, cc1.column_name, cc2.table_name as ref_table, cc2.column_name as ref_column, cc2.owner as ref_owner FROM all_constraints ac INNER JOIN all_cons_columns cc1 ON cc1.constraint_name = ac.constraint_name LEFT JOIN all_cons_columns cc2 ON cc2.constraint_name = ac.r_constraint_name AND cc2.position = cc1.position WHERE ac.owner = :ownername AND ac.table_name = :tablename ORDER BY ac.constraint_name '; $parameters = [ ':ownername' => $schema, ':tablename' => $table ]; $results = $this->adapter->query($sql)->execute($parameters); $isFK = false; $name = null; $constraints = []; foreach ($results as $row) { if ($row['CONSTRAINT_NAME'] !== $name) { $name = $row['CONSTRAINT_NAME']; $constraints[$name] = [ 'constraint_name' => $name, 'constraint_type' => $this->getConstraintType($row['CONSTRAINT_TYPE']), 'table_name' => $row['TABLE_NAME'], ]; if ('C' == $row['CONSTRAINT_TYPE']) { $constraints[$name]['CHECK_CLAUSE'] = $row['CHECK_CLAUSE']; continue; } $constraints[$name]['columns'] = []; $isFK = ('R' == $row['CONSTRAINT_TYPE']); if ($isFK) { $constraints[$name]['referenced_table_schema'] = $row['REF_OWNER']; $constraints[$name]['referenced_table_name'] = $row['REF_TABLE']; $constraints[$name]['referenced_columns'] = []; $constraints[$name]['match_option'] = 'NONE'; $constraints[$name]['update_rule'] = null; $constraints[$name]['delete_rule'] = $row['DELETE_RULE']; } } $constraints[$name]['columns'][] = $row['COLUMN_NAME']; if ($isFK) { $constraints[$name]['referenced_columns'][] = $row['REF_COLUMN']; } } return $this; } /** * {@inheritdoc} * @see \Zend\Db\Metadata\Source\AbstractSource::loadSchemaData() */ protected function loadSchemaData() { if (isset($this->data['schemas'])) { return; } $this->prepareDataHierarchy('schemas'); $sql = 'SELECT USERNAME FROM ALL_USERS'; $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); $schemas = []; foreach ($results->toArray() as $row) { $schemas[] = $row['USERNAME']; } $this->data['schemas'] = $schemas; } /** * {@inheritdoc} * @see \Zend\Db\Metadata\Source\AbstractSource::loadTableNameData() */ protected function loadTableNameData($schema) { if (isset($this->data['table_names'][$schema])) { return $this; } $this->prepareDataHierarchy('table_names', $schema); $tables = []; // Tables $bind = [':OWNER' => strtoupper($schema)]; $result = $this->adapter->query('SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER=:OWNER')->execute($bind); foreach ($result as $row) { $tables[$row['TABLE_NAME']] = [ 'table_type' => 'BASE TABLE', 'view_definition' => null, 'check_option' => null, 'is_updatable' => false, ]; } // Views $result = $this->adapter->query('SELECT VIEW_NAME, TEXT FROM ALL_VIEWS WHERE OWNER=:OWNER', $bind); foreach ($result as $row) { $tables[$row['VIEW_NAME']] = [ 'table_type' => 'VIEW', 'view_definition' => null, 'check_option' => 'NONE', 'is_updatable' => false, ]; } $this->data['table_names'][$schema] = $tables; return $this; } /** * FIXME: load trigger data * * {@inheritdoc} * * @see \Zend\Db\Metadata\Source\AbstractSource::loadTriggerData() */ protected function loadTriggerData($schema) { if (isset($this->data['triggers'][$schema])) { return; } $this->prepareDataHierarchy('triggers', $schema); } } zend-db-release-2.8.1/src/Metadata/Source/PostgresqlMetadata.php000066400000000000000000000335211270372430400245550ustar00rootroot00000000000000data['schemas'])) { return; } $this->prepareDataHierarchy('schemas'); $p = $this->adapter->getPlatform(); $sql = 'SELECT ' . $p->quoteIdentifier('schema_name') . ' FROM ' . $p->quoteIdentifierChain(['information_schema', 'schemata']) . ' WHERE ' . $p->quoteIdentifier('schema_name') . ' != \'information_schema\'' . ' AND ' . $p->quoteIdentifier('schema_name') . " NOT LIKE 'pg_%'"; $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); $schemas = []; foreach ($results->toArray() as $row) { $schemas[] = $row['schema_name']; } $this->data['schemas'] = $schemas; } protected function loadTableNameData($schema) { if (isset($this->data['table_names'][$schema])) { return; } $this->prepareDataHierarchy('table_names', $schema); $p = $this->adapter->getPlatform(); $isColumns = [ ['t', 'table_name'], ['t', 'table_type'], ['v', 'view_definition'], ['v', 'check_option'], ['v', 'is_updatable'], ]; array_walk($isColumns, function (&$c) use ($p) { $c = $p->quoteIdentifierChain($c); }); $sql = 'SELECT ' . implode(', ', $isColumns) . ' FROM ' . $p->quoteIdentifierChain(['information_schema', 'tables']) . ' t' . ' LEFT JOIN ' . $p->quoteIdentifierChain(['information_schema', 'views']) . ' v' . ' ON ' . $p->quoteIdentifierChain(['t', 'table_schema']) . ' = ' . $p->quoteIdentifierChain(['v', 'table_schema']) . ' AND ' . $p->quoteIdentifierChain(['t', 'table_name']) . ' = ' . $p->quoteIdentifierChain(['v', 'table_name']) . ' WHERE ' . $p->quoteIdentifierChain(['t', 'table_type']) . ' IN (\'BASE TABLE\', \'VIEW\')'; if ($schema != self::DEFAULT_SCHEMA) { $sql .= ' AND ' . $p->quoteIdentifierChain(['t', 'table_schema']) . ' = ' . $p->quoteTrustedValue($schema); } else { $sql .= ' AND ' . $p->quoteIdentifierChain(['t', 'table_schema']) . ' != \'information_schema\''; } $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); $tables = []; foreach ($results->toArray() as $row) { $tables[$row['table_name']] = [ 'table_type' => $row['table_type'], 'view_definition' => $row['view_definition'], 'check_option' => $row['check_option'], 'is_updatable' => ('YES' == $row['is_updatable']), ]; } $this->data['table_names'][$schema] = $tables; } protected function loadColumnData($table, $schema) { if (isset($this->data['columns'][$schema][$table])) { return; } $this->prepareDataHierarchy('columns', $schema, $table); $platform = $this->adapter->getPlatform(); $isColumns = [ 'table_name', 'column_name', 'ordinal_position', 'column_default', 'is_nullable', 'data_type', 'character_maximum_length', 'character_octet_length', 'numeric_precision', 'numeric_scale', ]; array_walk($isColumns, function (&$c) use ($platform) { $c = $platform->quoteIdentifier($c); }); $sql = 'SELECT ' . implode(', ', $isColumns) . ' FROM ' . $platform->quoteIdentifier('information_schema') . $platform->getIdentifierSeparator() . $platform->quoteIdentifier('columns') . ' WHERE ' . $platform->quoteIdentifier('table_schema') . ' != \'information\'' . ' AND ' . $platform->quoteIdentifier('table_name') . ' = ' . $platform->quoteTrustedValue($table); if ($schema != '__DEFAULT_SCHEMA__') { $sql .= ' AND ' . $platform->quoteIdentifier('table_schema') . ' = ' . $platform->quoteTrustedValue($schema); } $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); $columns = []; foreach ($results->toArray() as $row) { $columns[$row['column_name']] = [ 'ordinal_position' => $row['ordinal_position'], 'column_default' => $row['column_default'], 'is_nullable' => ('YES' == $row['is_nullable']), 'data_type' => $row['data_type'], 'character_maximum_length' => $row['character_maximum_length'], 'character_octet_length' => $row['character_octet_length'], 'numeric_precision' => $row['numeric_precision'], 'numeric_scale' => $row['numeric_scale'], 'numeric_unsigned' => null, 'erratas' => [], ]; } $this->data['columns'][$schema][$table] = $columns; } protected function loadConstraintData($table, $schema) { if (isset($this->data['constraints'][$schema][$table])) { return; } $this->prepareDataHierarchy('constraints', $schema, $table); $isColumns = [ ['t', 'table_name'], ['tc', 'constraint_name'], ['tc', 'constraint_type'], ['kcu', 'column_name'], ['cc', 'check_clause'], ['rc', 'match_option'], ['rc', 'update_rule'], ['rc', 'delete_rule'], ['referenced_table_schema' => 'kcu2', 'table_schema'], ['referenced_table_name' => 'kcu2', 'table_name'], ['referenced_column_name' => 'kcu2', 'column_name'], ]; $p = $this->adapter->getPlatform(); array_walk($isColumns, function (&$c) use ($p) { $alias = key($c); $c = $p->quoteIdentifierChain($c); if (is_string($alias)) { $c .= ' ' . $p->quoteIdentifier($alias); } }); $sql = 'SELECT ' . implode(', ', $isColumns) . ' FROM ' . $p->quoteIdentifierChain(['information_schema', 'tables']) . ' t' . ' INNER JOIN ' . $p->quoteIdentifierChain(['information_schema', 'table_constraints']) . ' tc' . ' ON ' . $p->quoteIdentifierChain(['t', 'table_schema']) . ' = ' . $p->quoteIdentifierChain(['tc', 'table_schema']) . ' AND ' . $p->quoteIdentifierChain(['t', 'table_name']) . ' = ' . $p->quoteIdentifierChain(['tc', 'table_name']) . ' LEFT JOIN ' . $p->quoteIdentifierChain(['information_schema', 'key_column_usage']) . ' kcu' . ' ON ' . $p->quoteIdentifierChain(['tc', 'table_schema']) . ' = ' . $p->quoteIdentifierChain(['kcu', 'table_schema']) . ' AND ' . $p->quoteIdentifierChain(['tc', 'table_name']) . ' = ' . $p->quoteIdentifierChain(['kcu', 'table_name']) . ' AND ' . $p->quoteIdentifierChain(['tc', 'constraint_name']) . ' = ' . $p->quoteIdentifierChain(['kcu', 'constraint_name']) . ' LEFT JOIN ' . $p->quoteIdentifierChain(['information_schema', 'check_constraints']) . ' cc' . ' ON ' . $p->quoteIdentifierChain(['tc', 'constraint_schema']) . ' = ' . $p->quoteIdentifierChain(['cc', 'constraint_schema']) . ' AND ' . $p->quoteIdentifierChain(['tc', 'constraint_name']) . ' = ' . $p->quoteIdentifierChain(['cc', 'constraint_name']) . ' LEFT JOIN ' . $p->quoteIdentifierChain(['information_schema', 'referential_constraints']) . ' rc' . ' ON ' . $p->quoteIdentifierChain(['tc', 'constraint_schema']) . ' = ' . $p->quoteIdentifierChain(['rc', 'constraint_schema']) . ' AND ' . $p->quoteIdentifierChain(['tc', 'constraint_name']) . ' = ' . $p->quoteIdentifierChain(['rc', 'constraint_name']) . ' LEFT JOIN ' . $p->quoteIdentifierChain(['information_schema', 'key_column_usage']) . ' kcu2' . ' ON ' . $p->quoteIdentifierChain(['rc', 'unique_constraint_schema']) . ' = ' . $p->quoteIdentifierChain(['kcu2', 'constraint_schema']) . ' AND ' . $p->quoteIdentifierChain(['rc', 'unique_constraint_name']) . ' = ' . $p->quoteIdentifierChain(['kcu2', 'constraint_name']) . ' AND ' . $p->quoteIdentifierChain(['kcu', 'position_in_unique_constraint']) . ' = ' . $p->quoteIdentifierChain(['kcu2', 'ordinal_position']) . ' WHERE ' . $p->quoteIdentifierChain(['t', 'table_name']) . ' = ' . $p->quoteTrustedValue($table) . ' AND ' . $p->quoteIdentifierChain(['t', 'table_type']) . ' IN (\'BASE TABLE\', \'VIEW\')'; if ($schema != self::DEFAULT_SCHEMA) { $sql .= ' AND ' . $p->quoteIdentifierChain(['t', 'table_schema']) . ' = ' . $p->quoteTrustedValue($schema); } else { $sql .= ' AND ' . $p->quoteIdentifierChain(['t', 'table_schema']) . ' != \'information_schema\''; } $sql .= ' ORDER BY CASE ' . $p->quoteIdentifierChain(['tc', 'constraint_type']) . " WHEN 'PRIMARY KEY' THEN 1" . " WHEN 'UNIQUE' THEN 2" . " WHEN 'FOREIGN KEY' THEN 3" . " WHEN 'CHECK' THEN 4" . " ELSE 5 END" . ', ' . $p->quoteIdentifierChain(['tc', 'constraint_name']) . ', ' . $p->quoteIdentifierChain(['kcu', 'ordinal_position']); $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); $name = null; $constraints = []; foreach ($results->toArray() as $row) { if ($row['constraint_name'] !== $name) { $name = $row['constraint_name']; $constraints[$name] = [ 'constraint_name' => $name, 'constraint_type' => $row['constraint_type'], 'table_name' => $row['table_name'], ]; if ('CHECK' == $row['constraint_type']) { $constraints[$name]['check_clause'] = $row['check_clause']; continue; } $constraints[$name]['columns'] = []; $isFK = ('FOREIGN KEY' == $row['constraint_type']); if ($isFK) { $constraints[$name]['referenced_table_schema'] = $row['referenced_table_schema']; $constraints[$name]['referenced_table_name'] = $row['referenced_table_name']; $constraints[$name]['referenced_columns'] = []; $constraints[$name]['match_option'] = $row['match_option']; $constraints[$name]['update_rule'] = $row['update_rule']; $constraints[$name]['delete_rule'] = $row['delete_rule']; } } $constraints[$name]['columns'][] = $row['column_name']; if ($isFK) { $constraints[$name]['referenced_columns'][] = $row['referenced_column_name']; } } $this->data['constraints'][$schema][$table] = $constraints; } protected function loadTriggerData($schema) { if (isset($this->data['triggers'][$schema])) { return; } $this->prepareDataHierarchy('triggers', $schema); $p = $this->adapter->getPlatform(); $isColumns = [ 'trigger_name', 'event_manipulation', 'event_object_catalog', 'event_object_schema', 'event_object_table', 'action_order', 'action_condition', 'action_statement', 'action_orientation', ['action_timing' => 'condition_timing'], ['action_reference_old_table' => 'condition_reference_old_table'], ['action_reference_new_table' => 'condition_reference_new_table'], 'created', ]; array_walk($isColumns, function (&$c) use ($p) { if (is_array($c)) { $alias = key($c); $c = $p->quoteIdentifierChain($c); if (is_string($alias)) { $c .= ' ' . $p->quoteIdentifier($alias); } } else { $c = $p->quoteIdentifier($c); } }); $sql = 'SELECT ' . implode(', ', $isColumns) . ' FROM ' . $p->quoteIdentifierChain(['information_schema', 'triggers']) . ' WHERE '; if ($schema != self::DEFAULT_SCHEMA) { $sql .= $p->quoteIdentifier('trigger_schema') . ' = ' . $p->quoteTrustedValue($schema); } else { $sql .= $p->quoteIdentifier('trigger_schema') . ' != \'information_schema\''; } $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); $data = []; foreach ($results->toArray() as $row) { $row = array_change_key_case($row, CASE_LOWER); $row['action_reference_old_row'] = 'OLD'; $row['action_reference_new_row'] = 'NEW'; if (null !== $row['created']) { $row['created'] = new \DateTime($row['created']); } $data[$row['trigger_name']] = $row; } $this->data['triggers'][$schema] = $data; } } zend-db-release-2.8.1/src/Metadata/Source/SqlServerMetadata.php000066400000000000000000000335251270372430400243440ustar00rootroot00000000000000data['schemas'])) { return; } $this->prepareDataHierarchy('schemas'); $p = $this->adapter->getPlatform(); $sql = 'SELECT ' . $p->quoteIdentifier('SCHEMA_NAME') . ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'SCHEMATA']) . ' WHERE ' . $p->quoteIdentifier('SCHEMA_NAME') . ' != \'INFORMATION_SCHEMA\''; $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); $schemas = []; foreach ($results->toArray() as $row) { $schemas[] = $row['SCHEMA_NAME']; } $this->data['schemas'] = $schemas; } protected function loadTableNameData($schema) { if (isset($this->data['table_names'][$schema])) { return; } $this->prepareDataHierarchy('table_names', $schema); $p = $this->adapter->getPlatform(); $isColumns = [ ['T', 'TABLE_NAME'], ['T', 'TABLE_TYPE'], ['V', 'VIEW_DEFINITION'], ['V', 'CHECK_OPTION'], ['V', 'IS_UPDATABLE'], ]; array_walk($isColumns, function (&$c) use ($p) { $c = $p->quoteIdentifierChain($c); }); $sql = 'SELECT ' . implode(', ', $isColumns) . ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . ' t' . ' LEFT JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'VIEWS']) . ' v' . ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' = ' . $p->quoteIdentifierChain(['V', 'TABLE_SCHEMA']) . ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME']) . ' = ' . $p->quoteIdentifierChain(['V', 'TABLE_NAME']) . ' WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE']) . ' IN (\'BASE TABLE\', \'VIEW\')'; if ($schema != self::DEFAULT_SCHEMA) { $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' = ' . $p->quoteTrustedValue($schema); } else { $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' != \'INFORMATION_SCHEMA\''; } $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); $tables = []; foreach ($results->toArray() as $row) { $tables[$row['TABLE_NAME']] = [ 'table_type' => $row['TABLE_TYPE'], 'view_definition' => $row['VIEW_DEFINITION'], 'check_option' => $row['CHECK_OPTION'], 'is_updatable' => ('YES' == $row['IS_UPDATABLE']), ]; } $this->data['table_names'][$schema] = $tables; } protected function loadColumnData($table, $schema) { if (isset($this->data['columns'][$schema][$table])) { return; } $this->prepareDataHierarchy('columns', $schema, $table); $p = $this->adapter->getPlatform(); $isColumns = [ ['C', 'ORDINAL_POSITION'], ['C', 'COLUMN_DEFAULT'], ['C', 'IS_NULLABLE'], ['C', 'DATA_TYPE'], ['C', 'CHARACTER_MAXIMUM_LENGTH'], ['C', 'CHARACTER_OCTET_LENGTH'], ['C', 'NUMERIC_PRECISION'], ['C', 'NUMERIC_SCALE'], ['C', 'COLUMN_NAME'], ]; array_walk($isColumns, function (&$c) use ($p) { $c = $p->quoteIdentifierChain($c); }); $sql = 'SELECT ' . implode(', ', $isColumns) . ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . 'T' . ' INNER JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'COLUMNS']) . 'C' . ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' = ' . $p->quoteIdentifierChain(['C', 'TABLE_SCHEMA']) . ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME']) . ' = ' . $p->quoteIdentifierChain(['C', 'TABLE_NAME']) . ' WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE']) . ' IN (\'BASE TABLE\', \'VIEW\')' . ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME']) . ' = ' . $p->quoteTrustedValue($table); if ($schema != self::DEFAULT_SCHEMA) { $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' = ' . $p->quoteTrustedValue($schema); } else { $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' != \'INFORMATION_SCHEMA\''; } $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); $columns = []; foreach ($results->toArray() as $row) { $columns[$row['COLUMN_NAME']] = [ 'ordinal_position' => $row['ORDINAL_POSITION'], 'column_default' => $row['COLUMN_DEFAULT'], 'is_nullable' => ('YES' == $row['IS_NULLABLE']), 'data_type' => $row['DATA_TYPE'], 'character_maximum_length' => $row['CHARACTER_MAXIMUM_LENGTH'], 'character_octet_length' => $row['CHARACTER_OCTET_LENGTH'], 'numeric_precision' => $row['NUMERIC_PRECISION'], 'numeric_scale' => $row['NUMERIC_SCALE'], 'numeric_unsigned' => null, 'erratas' => [], ]; } $this->data['columns'][$schema][$table] = $columns; } protected function loadConstraintData($table, $schema) { if (isset($this->data['constraints'][$schema][$table])) { return; } $this->prepareDataHierarchy('constraints', $schema, $table); $isColumns = [ ['T', 'TABLE_NAME'], ['TC', 'CONSTRAINT_NAME'], ['TC', 'CONSTRAINT_TYPE'], ['KCU', 'COLUMN_NAME'], ['CC', 'CHECK_CLAUSE'], ['RC', 'MATCH_OPTION'], ['RC', 'UPDATE_RULE'], ['RC', 'DELETE_RULE'], ['REFERENCED_TABLE_SCHEMA' => 'KCU2', 'TABLE_SCHEMA'], ['REFERENCED_TABLE_NAME' => 'KCU2', 'TABLE_NAME'], ['REFERENCED_COLUMN_NAME' => 'KCU2', 'COLUMN_NAME'], ]; $p = $this->adapter->getPlatform(); array_walk($isColumns, function (&$c) use ($p) { $alias = key($c); $c = $p->quoteIdentifierChain($c); if (is_string($alias)) { $c .= ' ' . $p->quoteIdentifier($alias); } }); $sql = 'SELECT ' . implode(', ', $isColumns) . ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . ' T' . ' INNER JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLE_CONSTRAINTS']) . ' TC' . ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' = ' . $p->quoteIdentifierChain(['TC', 'TABLE_SCHEMA']) . ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME']) . ' = ' . $p->quoteIdentifierChain(['TC', 'TABLE_NAME']) . ' LEFT JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'KEY_COLUMN_USAGE']) . ' KCU' . ' ON ' . $p->quoteIdentifierChain(['TC', 'TABLE_SCHEMA']) . ' = ' . $p->quoteIdentifierChain(['KCU', 'TABLE_SCHEMA']) . ' AND ' . $p->quoteIdentifierChain(['TC', 'TABLE_NAME']) . ' = ' . $p->quoteIdentifierChain(['KCU', 'TABLE_NAME']) . ' AND ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_NAME']) . ' = ' . $p->quoteIdentifierChain(['KCU', 'CONSTRAINT_NAME']) . ' LEFT JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'CHECK_CONSTRAINTS']) . ' CC' . ' ON ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_SCHEMA']) . ' = ' . $p->quoteIdentifierChain(['CC', 'CONSTRAINT_SCHEMA']) . ' AND ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_NAME']) . ' = ' . $p->quoteIdentifierChain(['CC', 'CONSTRAINT_NAME']) . ' LEFT JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'REFERENTIAL_CONSTRAINTS']) . ' RC' . ' ON ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_SCHEMA']) . ' = ' . $p->quoteIdentifierChain(['RC', 'CONSTRAINT_SCHEMA']) . ' AND ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_NAME']) . ' = ' . $p->quoteIdentifierChain(['RC', 'CONSTRAINT_NAME']) . ' LEFT JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'KEY_COLUMN_USAGE']) . ' KCU2' . ' ON ' . $p->quoteIdentifierChain(['RC', 'UNIQUE_CONSTRAINT_SCHEMA']) . ' = ' . $p->quoteIdentifierChain(['KCU2', 'CONSTRAINT_SCHEMA']) . ' AND ' . $p->quoteIdentifierChain(['RC', 'UNIQUE_CONSTRAINT_NAME']) . ' = ' . $p->quoteIdentifierChain(['KCU2', 'CONSTRAINT_NAME']) . ' AND ' . $p->quoteIdentifierChain(['KCU', 'ORDINAL_POSITION']) . ' = ' . $p->quoteIdentifierChain(['KCU2', 'ORDINAL_POSITION']) . ' WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME']) . ' = ' . $p->quoteTrustedValue($table) . ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE']) . ' IN (\'BASE TABLE\', \'VIEW\')'; if ($schema != self::DEFAULT_SCHEMA) { $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' = ' . $p->quoteTrustedValue($schema); } else { $sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA']) . ' != \'INFORMATION_SCHEMA\''; } $sql .= ' ORDER BY CASE ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_TYPE']) . " WHEN 'PRIMARY KEY' THEN 1" . " WHEN 'UNIQUE' THEN 2" . " WHEN 'FOREIGN KEY' THEN 3" . " WHEN 'CHECK' THEN 4" . " ELSE 5 END" . ', ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_NAME']) . ', ' . $p->quoteIdentifierChain(['KCU', 'ORDINAL_POSITION']); $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); $name = null; $constraints = []; $isFK = false; foreach ($results->toArray() as $row) { if ($row['CONSTRAINT_NAME'] !== $name) { $name = $row['CONSTRAINT_NAME']; $constraints[$name] = [ 'constraint_name' => $name, 'constraint_type' => $row['CONSTRAINT_TYPE'], 'table_name' => $row['TABLE_NAME'], ]; if ('CHECK' == $row['CONSTRAINT_TYPE']) { $constraints[$name]['check_clause'] = $row['CHECK_CLAUSE']; continue; } $constraints[$name]['columns'] = []; $isFK = ('FOREIGN KEY' == $row['CONSTRAINT_TYPE']); if ($isFK) { $constraints[$name]['referenced_table_schema'] = $row['REFERENCED_TABLE_SCHEMA']; $constraints[$name]['referenced_table_name'] = $row['REFERENCED_TABLE_NAME']; $constraints[$name]['referenced_columns'] = []; $constraints[$name]['match_option'] = $row['MATCH_OPTION']; $constraints[$name]['update_rule'] = $row['UPDATE_RULE']; $constraints[$name]['delete_rule'] = $row['DELETE_RULE']; } } $constraints[$name]['columns'][] = $row['COLUMN_NAME']; if ($isFK) { $constraints[$name]['referenced_columns'][] = $row['REFERENCED_COLUMN_NAME']; } } $this->data['constraints'][$schema][$table] = $constraints; } protected function loadTriggerData($schema) { if (isset($this->data['triggers'][$schema])) { return; } $this->prepareDataHierarchy('triggers', $schema); $p = $this->adapter->getPlatform(); $isColumns = [ 'TRIGGER_NAME', 'EVENT_MANIPULATION', 'EVENT_OBJECT_CATALOG', 'EVENT_OBJECT_SCHEMA', 'EVENT_OBJECT_TABLE', 'ACTION_ORDER', 'ACTION_CONDITION', 'ACTION_STATEMENT', 'ACTION_ORIENTATION', 'ACTION_TIMING', 'ACTION_REFERENCE_OLD_TABLE', 'ACTION_REFERENCE_NEW_TABLE', 'ACTION_REFERENCE_OLD_ROW', 'ACTION_REFERENCE_NEW_ROW', 'CREATED', ]; array_walk($isColumns, function (&$c) use ($p) { $c = $p->quoteIdentifier($c); }); $sql = 'SELECT ' . implode(', ', $isColumns) . ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TRIGGERS']) . ' WHERE '; if ($schema != self::DEFAULT_SCHEMA) { $sql .= $p->quoteIdentifier('TRIGGER_SCHEMA') . ' = ' . $p->quoteTrustedValue($schema); } else { $sql .= $p->quoteIdentifier('TRIGGER_SCHEMA') . ' != \'INFORMATION_SCHEMA\''; } $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); $data = []; foreach ($results->toArray() as $row) { $row = array_change_key_case($row, CASE_LOWER); if (null !== $row['created']) { $row['created'] = new \DateTime($row['created']); } $data[$row['trigger_name']] = $row; } $this->data['triggers'][$schema] = $data; } } zend-db-release-2.8.1/src/Metadata/Source/SqliteMetadata.php000066400000000000000000000316441270372430400236570ustar00rootroot00000000000000data['schemas'])) { return; } $this->prepareDataHierarchy('schemas'); $results = $this->fetchPragma('database_list'); foreach ($results as $row) { $schemas[] = $row['name']; } $this->data['schemas'] = $schemas; } protected function loadTableNameData($schema) { if (isset($this->data['table_names'][$schema])) { return; } $this->prepareDataHierarchy('table_names', $schema); // FEATURE: Filename? $p = $this->adapter->getPlatform(); $sql = 'SELECT "name", "type", "sql" FROM ' . $p->quoteIdentifierChain([$schema, 'sqlite_master']) . ' WHERE "type" IN (\'table\',\'view\') AND "name" NOT LIKE \'sqlite_%\''; $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); $tables = []; foreach ($results->toArray() as $row) { if ('table' == $row['type']) { $table = [ 'table_type' => 'BASE TABLE', 'view_definition' => null, // VIEW only 'check_option' => null, // VIEW only 'is_updatable' => null, // VIEW only ]; } else { $table = [ 'table_type' => 'VIEW', 'view_definition' => null, 'check_option' => 'NONE', 'is_updatable' => false, ]; // Parse out extra data if (null !== ($data = $this->parseView($row['sql']))) { $table = array_merge($table, $data); } } $tables[$row['name']] = $table; } $this->data['table_names'][$schema] = $tables; } protected function loadColumnData($table, $schema) { if (isset($this->data['columns'][$schema][$table])) { return; } $this->prepareDataHierarchy('columns', $schema, $table); $this->prepareDataHierarchy('sqlite_columns', $schema, $table); $results = $this->fetchPragma('table_info', $table, $schema); $columns = []; foreach ($results as $row) { $columns[$row['name']] = [ // cid appears to be zero-based, ordinal position needs to be one-based 'ordinal_position' => $row['cid'] + 1, 'column_default' => $row['dflt_value'], 'is_nullable' => !((bool) $row['notnull']), 'data_type' => $row['type'], 'character_maximum_length' => null, 'character_octet_length' => null, 'numeric_precision' => null, 'numeric_scale' => null, 'numeric_unsigned' => null, 'erratas' => [], ]; // TODO: populate character_ and numeric_values with correct info } $this->data['columns'][$schema][$table] = $columns; $this->data['sqlite_columns'][$schema][$table] = $results; } protected function loadConstraintData($table, $schema) { if (isset($this->data['constraints'][$schema][$table])) { return; } $this->prepareDataHierarchy('constraints', $schema, $table); $this->loadColumnData($table, $schema); $primaryKey = []; foreach ($this->data['sqlite_columns'][$schema][$table] as $col) { if ((bool) $col['pk']) { $primaryKey[] = $col['name']; } } if (empty($primaryKey)) { $primaryKey = null; } $constraints = []; $indexes = $this->fetchPragma('index_list', $table, $schema); foreach ($indexes as $index) { if (!((bool) $index['unique'])) { continue; } $constraint = [ 'constraint_name' => $index['name'], 'constraint_type' => 'UNIQUE', 'table_name' => $table, 'columns' => [], ]; $info = $this->fetchPragma('index_info', $index['name'], $schema); foreach ($info as $column) { $constraint['columns'][] = $column['name']; } if ($primaryKey === $constraint['columns']) { $constraint['constraint_type'] = 'PRIMARY KEY'; $primaryKey = null; } $constraints[$constraint['constraint_name']] = $constraint; } if (null !== $primaryKey) { $constraintName = '_zf_' . $table . '_PRIMARY'; $constraints[$constraintName] = [ 'constraint_name' => $constraintName, 'constraint_type' => 'PRIMARY KEY', 'table_name' => $table, 'columns' => $primaryKey, ]; } $foreignKeys = $this->fetchPragma('foreign_key_list', $table, $schema); $id = $name = null; foreach ($foreignKeys as $fk) { if ($id !== $fk['id']) { $id = $fk['id']; $name = '_zf_' . $table . '_FOREIGN_KEY_' . ($id + 1); $constraints[$name] = [ 'constraint_name' => $name, 'constraint_type' => 'FOREIGN KEY', 'table_name' => $table, 'columns' => [], 'referenced_table_schema' => $schema, 'referenced_table_name' => $fk['table'], 'referenced_columns' => [], // TODO: Verify match, on_update, and on_delete values conform to SQL Standard 'match_option' => strtoupper($fk['match']), 'update_rule' => strtoupper($fk['on_update']), 'delete_rule' => strtoupper($fk['on_delete']), ]; } $constraints[$name]['columns'][] = $fk['from']; $constraints[$name]['referenced_columns'][] = $fk['to']; } $this->data['constraints'][$schema][$table] = $constraints; } protected function loadTriggerData($schema) { if (isset($this->data['triggers'][$schema])) { return; } $this->prepareDataHierarchy('triggers', $schema); $p = $this->adapter->getPlatform(); $sql = 'SELECT "name", "tbl_name", "sql" FROM ' . $p->quoteIdentifierChain([$schema, 'sqlite_master']) . ' WHERE "type" = \'trigger\''; $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); $triggers = []; foreach ($results->toArray() as $row) { $trigger = [ 'trigger_name' => $row['name'], 'event_manipulation' => null, // in $row['sql'] 'event_object_catalog' => null, 'event_object_schema' => $schema, 'event_object_table' => $row['tbl_name'], 'action_order' => 0, 'action_condition' => null, // in $row['sql'] 'action_statement' => null, // in $row['sql'] 'action_orientation' => 'ROW', 'action_timing' => null, // in $row['sql'] 'action_reference_old_table' => null, 'action_reference_new_table' => null, 'action_reference_old_row' => 'OLD', 'action_reference_new_row' => 'NEW', 'created' => null, ]; // Parse out extra data if (null !== ($data = $this->parseTrigger($row['sql']))) { $trigger = array_merge($trigger, $data); } $triggers[$trigger['trigger_name']] = $trigger; } $this->data['triggers'][$schema] = $triggers; } protected function fetchPragma($name, $value = null, $schema = null) { $p = $this->adapter->getPlatform(); $sql = 'PRAGMA '; if (null !== $schema) { $sql .= $p->quoteIdentifier($schema) . '.'; } $sql .= $name; if (null !== $value) { $sql .= '(' . $p->quoteTrustedValue($value) . ')'; } $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE); if ($results instanceof ResultSetInterface) { return $results->toArray(); } return []; } protected function parseView($sql) { static $re = null; if (null === $re) { $identifierChain = $this->getIdentifierChainRegularExpression(); $re = $this->buildRegularExpression([ 'CREATE', ['TEMP|TEMPORARY'], 'VIEW', ['IF', 'NOT', 'EXISTS'], $identifierChain, 'AS', '(?.+)', [';'], ]); } if (!preg_match($re, $sql, $matches)) { return; } return [ 'view_definition' => $matches['view_definition'], ]; } protected function parseTrigger($sql) { static $re = null; if (null === $re) { $identifier = $this->getIdentifierRegularExpression(); $identifierList = $this->getIdentifierListRegularExpression(); $identifierChain = $this->getIdentifierChainRegularExpression(); $re = $this->buildRegularExpression([ 'CREATE', ['TEMP|TEMPORARY'], 'TRIGGER', ['IF', 'NOT', 'EXISTS'], $identifierChain, ['(?BEFORE|AFTER|INSTEAD\\s+OF)', ], '(?DELETE|INSERT|UPDATE)', ['OF', '(?' . $identifierList . ')'], 'ON', '(?' . $identifier . ')', ['FOR', 'EACH', 'ROW'], ['WHEN', '(?.+)'], '(?BEGIN', '.+', 'END)', [';'], ]); } if (!preg_match($re, $sql, $matches)) { return; } $data = []; foreach ($matches as $key => $value) { if (is_string($key)) { $data[$key] = $value; } } // Normalize data and populate defaults, if necessary $data['event_manipulation'] = strtoupper($data['event_manipulation']); if (empty($data['action_condition'])) { $data['action_condition'] = null; } if (!empty($data['action_timing'])) { $data['action_timing'] = strtoupper($data['action_timing']); if ('I' == $data['action_timing'][0]) { // normalize the white-space between the two words $data['action_timing'] = 'INSTEAD OF'; } } else { $data['action_timing'] = 'AFTER'; } unset($data['column_usage']); return $data; } protected function buildRegularExpression(array $re) { foreach ($re as &$value) { if (is_array($value)) { $value = '(?:' . implode('\\s*+', $value) . '\\s*+)?'; } else { $value .= '\\s*+'; } } unset($value); $re = '/^' . implode('\\s*+', $re) . '$/'; return $re; } protected function getIdentifierRegularExpression() { static $re = null; if (null === $re) { $re = '(?:' . implode('|', [ '"(?:[^"\\\\]++|\\\\.)*+"', '`(?:[^`]++|``)*+`', '\\[[^\\]]+\\]', '[^\\s\\.]+', ]) . ')'; } return $re; } protected function getIdentifierChainRegularExpression() { static $re = null; if (null === $re) { $identifier = $this->getIdentifierRegularExpression(); $re = $identifier . '(?:\\s*\\.\\s*' . $identifier . ')*+'; } return $re; } protected function getIdentifierListRegularExpression() { static $re = null; if (null === $re) { $identifier = $this->getIdentifierRegularExpression(); $re = $identifier . '(?:\\s*,\\s*' . $identifier . ')*+'; } return $re; } } zend-db-release-2.8.1/src/Module.php000066400000000000000000000011221270372430400172060ustar00rootroot00000000000000 $provider->getDependencyConfig(), ]; } } zend-db-release-2.8.1/src/ResultSet/000077500000000000000000000000001270372430400172065ustar00rootroot00000000000000zend-db-release-2.8.1/src/ResultSet/AbstractResultSet.php000066400000000000000000000163221270372430400233410ustar00rootroot00000000000000buffer)) { $this->buffer = []; } if ($dataSource instanceof ResultInterface) { $this->fieldCount = $dataSource->getFieldCount(); $this->dataSource = $dataSource; if ($dataSource->isBuffered()) { $this->buffer = -1; } if (is_array($this->buffer)) { $this->dataSource->rewind(); } return $this; } if (is_array($dataSource)) { // its safe to get numbers from an array $first = current($dataSource); reset($dataSource); $this->fieldCount = count($first); $this->dataSource = new ArrayIterator($dataSource); $this->buffer = -1; // array's are a natural buffer } elseif ($dataSource instanceof IteratorAggregate) { $this->dataSource = $dataSource->getIterator(); } elseif ($dataSource instanceof Iterator) { $this->dataSource = $dataSource; } else { throw new Exception\InvalidArgumentException('DataSource provided is not an array, nor does it implement Iterator or IteratorAggregate'); } return $this; } public function buffer() { if ($this->buffer === -2) { throw new Exception\RuntimeException('Buffering must be enabled before iteration is started'); } elseif ($this->buffer === null) { $this->buffer = []; if ($this->dataSource instanceof ResultInterface) { $this->dataSource->rewind(); } } return $this; } public function isBuffered() { if ($this->buffer === -1 || is_array($this->buffer)) { return true; } return false; } /** * Get the data source used to create the result set * * @return null|Iterator */ public function getDataSource() { return $this->dataSource; } /** * Retrieve count of fields in individual rows of the result set * * @return int */ public function getFieldCount() { if (null !== $this->fieldCount) { return $this->fieldCount; } $dataSource = $this->getDataSource(); if (null === $dataSource) { return 0; } $dataSource->rewind(); if (!$dataSource->valid()) { $this->fieldCount = 0; return 0; } $row = $dataSource->current(); if (is_object($row) && $row instanceof Countable) { $this->fieldCount = $row->count(); return $this->fieldCount; } $row = (array) $row; $this->fieldCount = count($row); return $this->fieldCount; } /** * Iterator: move pointer to next item * * @return void */ public function next() { if ($this->buffer === null) { $this->buffer = -2; // implicitly disable buffering from here on } if (!is_array($this->buffer) || $this->position == $this->dataSource->key()) { $this->dataSource->next(); } $this->position++; } /** * Iterator: retrieve current key * * @return mixed */ public function key() { return $this->position; } /** * Iterator: get current item * * @return array|null */ public function current() { if ($this->buffer === null) { $this->buffer = -2; // implicitly disable buffering from here on } elseif (is_array($this->buffer) && isset($this->buffer[$this->position])) { return $this->buffer[$this->position]; } $data = $this->dataSource->current(); if (is_array($this->buffer)) { $this->buffer[$this->position] = $data; } return is_array($data) ? $data : null; } /** * Iterator: is pointer valid? * * @return bool */ public function valid() { if (is_array($this->buffer) && isset($this->buffer[$this->position])) { return true; } if ($this->dataSource instanceof Iterator) { return $this->dataSource->valid(); } else { $key = key($this->dataSource); return ($key !== null); } } /** * Iterator: rewind * * @return void */ public function rewind() { if (!is_array($this->buffer)) { if ($this->dataSource instanceof Iterator) { $this->dataSource->rewind(); } else { reset($this->dataSource); } } $this->position = 0; } /** * Countable: return count of rows * * @return int */ public function count() { if ($this->count !== null) { return $this->count; } if ($this->dataSource instanceof Countable) { $this->count = count($this->dataSource); } return $this->count; } /** * Cast result set to array of arrays * * @return array * @throws Exception\RuntimeException if any row is not castable to an array */ public function toArray() { $return = []; foreach ($this as $row) { if (is_array($row)) { $return[] = $row; } elseif (method_exists($row, 'toArray')) { $return[] = $row->toArray(); } elseif (method_exists($row, 'getArrayCopy')) { $return[] = $row->getArrayCopy(); } else { throw new Exception\RuntimeException( 'Rows as part of this DataSource, with type ' . gettype($row) . ' cannot be cast to an array' ); } } return $return; } } zend-db-release-2.8.1/src/ResultSet/Exception/000077500000000000000000000000001270372430400211445ustar00rootroot00000000000000zend-db-release-2.8.1/src/ResultSet/Exception/ExceptionInterface.php000066400000000000000000000006741270372430400254430ustar00rootroot00000000000000setHydrator(($hydrator) ?: new ArraySerializable); $this->setObjectPrototype(($objectPrototype) ?: new ArrayObject); } /** * Set the row object prototype * * @param object $objectPrototype * @throws Exception\InvalidArgumentException * @return ResultSet */ public function setObjectPrototype($objectPrototype) { if (!is_object($objectPrototype)) { throw new Exception\InvalidArgumentException( 'An object must be set as the object prototype, a ' . gettype($objectPrototype) . ' was provided.' ); } $this->objectPrototype = $objectPrototype; return $this; } /** * Get the row object prototype * * @return object */ public function getObjectPrototype() { return $this->objectPrototype; } /** * Set the hydrator to use for each row object * * @param HydratorInterface $hydrator * @return HydratingResultSet */ public function setHydrator(HydratorInterface $hydrator) { $this->hydrator = $hydrator; return $this; } /** * Get the hydrator to use for each row object * * @return HydratorInterface */ public function getHydrator() { return $this->hydrator; } /** * Iterator: get current item * * @return object */ public function current() { if ($this->buffer === null) { $this->buffer = -2; // implicitly disable buffering from here on } elseif (is_array($this->buffer) && isset($this->buffer[$this->position])) { return $this->buffer[$this->position]; } $data = $this->dataSource->current(); $object = is_array($data) ? $this->hydrator->hydrate($data, clone $this->objectPrototype) : false; if (is_array($this->buffer)) { $this->buffer[$this->position] = $object; } return $object; } /** * Cast result set to array of arrays * * @return array * @throws Exception\RuntimeException if any row is not castable to an array */ public function toArray() { $return = []; foreach ($this as $row) { $return[] = $this->getHydrator()->extract($row); } return $return; } } zend-db-release-2.8.1/src/ResultSet/ResultSet.php000066400000000000000000000060101270372430400216460ustar00rootroot00000000000000returnType = (in_array($returnType, [self::TYPE_ARRAY, self::TYPE_ARRAYOBJECT])) ? $returnType : self::TYPE_ARRAYOBJECT; if ($this->returnType === self::TYPE_ARRAYOBJECT) { $this->setArrayObjectPrototype(($arrayObjectPrototype) ?: new ArrayObject([], ArrayObject::ARRAY_AS_PROPS)); } } /** * Set the row object prototype * * @param ArrayObject $arrayObjectPrototype * @throws Exception\InvalidArgumentException * @return ResultSet */ public function setArrayObjectPrototype($arrayObjectPrototype) { if (!is_object($arrayObjectPrototype) || (!$arrayObjectPrototype instanceof ArrayObject && !method_exists($arrayObjectPrototype, 'exchangeArray')) ) { throw new Exception\InvalidArgumentException('Object must be of type ArrayObject, or at least implement exchangeArray'); } $this->arrayObjectPrototype = $arrayObjectPrototype; return $this; } /** * Get the row object prototype * * @return ArrayObject */ public function getArrayObjectPrototype() { return $this->arrayObjectPrototype; } /** * Get the return type to use when returning objects from the set * * @return string */ public function getReturnType() { return $this->returnType; } /** * @return array|\ArrayObject|null */ public function current() { $data = parent::current(); if ($this->returnType === self::TYPE_ARRAYOBJECT && is_array($data)) { /** @var $ao ArrayObject */ $ao = clone $this->arrayObjectPrototype; if ($ao instanceof ArrayObject || method_exists($ao, 'exchangeArray')) { $ao->exchangeArray($data); } return $ao; } return $data; } } zend-db-release-2.8.1/src/ResultSet/ResultSetInterface.php000066400000000000000000000015551270372430400235000ustar00rootroot00000000000000isInitialized) { return; } if (!$this->featureSet instanceof Feature\FeatureSet) { $this->featureSet = new Feature\FeatureSet; } $this->featureSet->setRowGateway($this); $this->featureSet->apply('preInitialize', []); if (!is_string($this->table) && !$this->table instanceof TableIdentifier) { throw new Exception\RuntimeException('This row object does not have a valid table set.'); } if ($this->primaryKeyColumn === null) { throw new Exception\RuntimeException('This row object does not have a primary key column set.'); } elseif (is_string($this->primaryKeyColumn)) { $this->primaryKeyColumn = (array) $this->primaryKeyColumn; } if (!$this->sql instanceof Sql) { throw new Exception\RuntimeException('This row object does not have a Sql object set.'); } $this->featureSet->apply('postInitialize', []); $this->isInitialized = true; } /** * Populate Data * * @param array $rowData * @param bool $rowExistsInDatabase * @return AbstractRowGateway */ public function populate(array $rowData, $rowExistsInDatabase = false) { $this->initialize(); $this->data = $rowData; if ($rowExistsInDatabase == true) { $this->processPrimaryKeyData(); } else { $this->primaryKeyData = null; } return $this; } /** * @param mixed $array * @return array|void */ public function exchangeArray($array) { return $this->populate($array, true); } /** * Save * * @return int */ public function save() { $this->initialize(); if ($this->rowExistsInDatabase()) { // UPDATE $data = $this->data; $where = []; $isPkModified = false; // primary key is always an array even if its a single column foreach ($this->primaryKeyColumn as $pkColumn) { $where[$pkColumn] = $this->primaryKeyData[$pkColumn]; if ($data[$pkColumn] == $this->primaryKeyData[$pkColumn]) { unset($data[$pkColumn]); } else { $isPkModified = true; } } $statement = $this->sql->prepareStatementForSqlObject($this->sql->update()->set($data)->where($where)); $result = $statement->execute(); $rowsAffected = $result->getAffectedRows(); unset($statement, $result); // cleanup // If one or more primary keys are modified, we update the where clause if ($isPkModified) { foreach ($this->primaryKeyColumn as $pkColumn) { if ($data[$pkColumn] != $this->primaryKeyData[$pkColumn]) { $where[$pkColumn] = $data[$pkColumn]; } } } } else { // INSERT $insert = $this->sql->insert(); $insert->values($this->data); $statement = $this->sql->prepareStatementForSqlObject($insert); $result = $statement->execute(); if (($primaryKeyValue = $result->getGeneratedValue()) && count($this->primaryKeyColumn) == 1) { $this->primaryKeyData = [$this->primaryKeyColumn[0] => $primaryKeyValue]; } else { // make primary key data available so that $where can be complete $this->processPrimaryKeyData(); } $rowsAffected = $result->getAffectedRows(); unset($statement, $result); // cleanup $where = []; // primary key is always an array even if its a single column foreach ($this->primaryKeyColumn as $pkColumn) { $where[$pkColumn] = $this->primaryKeyData[$pkColumn]; } } // refresh data $statement = $this->sql->prepareStatementForSqlObject($this->sql->select()->where($where)); $result = $statement->execute(); $rowData = $result->current(); unset($statement, $result); // cleanup // make sure data and original data are in sync after save $this->populate($rowData, true); // return rows affected return $rowsAffected; } /** * Delete * * @return int */ public function delete() { $this->initialize(); $where = []; // primary key is always an array even if its a single column foreach ($this->primaryKeyColumn as $pkColumn) { $where[$pkColumn] = $this->primaryKeyData[$pkColumn]; } // @todo determine if we need to do a select to ensure 1 row will be affected $statement = $this->sql->prepareStatementForSqlObject($this->sql->delete()->where($where)); $result = $statement->execute(); $affectedRows = $result->getAffectedRows(); if ($affectedRows == 1) { // detach from database $this->primaryKeyData = null; } return $affectedRows; } /** * Offset Exists * * @param string $offset * @return bool */ public function offsetExists($offset) { return array_key_exists($offset, $this->data); } /** * Offset get * * @param string $offset * @return mixed */ public function offsetGet($offset) { return $this->data[$offset]; } /** * Offset set * * @param string $offset * @param mixed $value * @return RowGateway */ public function offsetSet($offset, $value) { $this->data[$offset] = $value; return $this; } /** * Offset unset * * @param string $offset * @return AbstractRowGateway */ public function offsetUnset($offset) { $this->data[$offset] = null; return $this; } /** * @return int */ public function count() { return count($this->data); } /** * To array * * @return array */ public function toArray() { return $this->data; } /** * __get * * @param string $name * @throws Exception\InvalidArgumentException * @return mixed */ public function __get($name) { if (array_key_exists($name, $this->data)) { return $this->data[$name]; } else { throw new Exception\InvalidArgumentException('Not a valid column in this row: ' . $name); } } /** * __set * * @param string $name * @param mixed $value * @return void */ public function __set($name, $value) { $this->offsetSet($name, $value); } /** * __isset * * @param string $name * @return bool */ public function __isset($name) { return $this->offsetExists($name); } /** * __unset * * @param string $name * @return void */ public function __unset($name) { $this->offsetUnset($name); } /** * @return bool */ public function rowExistsInDatabase() { return ($this->primaryKeyData !== null); } /** * @throws Exception\RuntimeException */ protected function processPrimaryKeyData() { $this->primaryKeyData = []; foreach ($this->primaryKeyColumn as $column) { if (!isset($this->data[$column])) { throw new Exception\RuntimeException('While processing primary key data, a known key ' . $column . ' was not found in the data array'); } $this->primaryKeyData[$column] = $this->data[$column]; } } } zend-db-release-2.8.1/src/RowGateway/Exception/000077500000000000000000000000001270372430400213035ustar00rootroot00000000000000zend-db-release-2.8.1/src/RowGateway/Exception/ExceptionInterface.php000066400000000000000000000006751270372430400256030ustar00rootroot00000000000000rowGateway = $rowGateway; } /** * @throws \Zend\Db\RowGateway\Exception\RuntimeException */ public function initialize() { throw new Exception\RuntimeException('This method is not intended to be called on this object.'); } /** * @return array */ public function getMagicMethodSpecifications() { return []; } } zend-db-release-2.8.1/src/RowGateway/Feature/FeatureSet.php000066400000000000000000000061731270372430400235270ustar00rootroot00000000000000addFeatures($features); } } public function setRowGateway(AbstractRowGateway $rowGateway) { $this->rowGateway = $rowGateway; foreach ($this->features as $feature) { $feature->setRowGateway($this->rowGateway); } return $this; } public function getFeatureByClassName($featureClassName) { $feature = false; foreach ($this->features as $potentialFeature) { if ($potentialFeature instanceof $featureClassName) { $feature = $potentialFeature; break; } } return $feature; } public function addFeatures(array $features) { foreach ($features as $feature) { $this->addFeature($feature); } return $this; } public function addFeature(AbstractFeature $feature) { $this->features[] = $feature; $feature->setRowGateway($feature); return $this; } public function apply($method, $args) { foreach ($this->features as $feature) { if (method_exists($feature, $method)) { $return = call_user_func_array([$feature, $method], $args); if ($return === self::APPLY_HALT) { break; } } } } /** * @param string $property * @return bool */ public function canCallMagicGet($property) { return false; } /** * @param string $property * @return mixed */ public function callMagicGet($property) { $return = null; return $return; } /** * @param string $property * @return bool */ public function canCallMagicSet($property) { return false; } /** * @param $property * @param $value * @return mixed */ public function callMagicSet($property, $value) { $return = null; return $return; } /** * @param string $method * @return bool */ public function canCallMagicCall($method) { return false; } /** * @param string $method * @param array $arguments * @return mixed */ public function callMagicCall($method, $arguments) { $return = null; return $return; } } zend-db-release-2.8.1/src/RowGateway/RowGateway.php000066400000000000000000000027631270372430400221570ustar00rootroot00000000000000primaryKeyColumn = empty($primaryKeyColumn) ? null : (array) $primaryKeyColumn; // set table $this->table = $table; // set Sql object if ($adapterOrSql instanceof Sql) { $this->sql = $adapterOrSql; } elseif ($adapterOrSql instanceof Adapter) { $this->sql = new Sql($adapterOrSql, $this->table); } else { throw new Exception\InvalidArgumentException('A valid Sql object was not provided.'); } if ($this->sql->getTable() !== $this->table) { throw new Exception\InvalidArgumentException('The Sql object provided does not have a table that matches this row object'); } $this->initialize(); } } zend-db-release-2.8.1/src/RowGateway/RowGatewayInterface.php000066400000000000000000000006611270372430400237730ustar00rootroot00000000000000buildNormalizedArgument($argument, self::TYPE_VALUE); } if (is_scalar($argument) || $argument === null) { return $this->buildNormalizedArgument($argument, $defaultType); } if (is_array($argument)) { $value = current($argument); if ($value instanceof ExpressionInterface || $value instanceof SqlInterface) { return $this->buildNormalizedArgument($value, self::TYPE_VALUE); } $key = key($argument); if (is_integer($key) && ! in_array($value, $this->allowedTypes)) { return $this->buildNormalizedArgument($value, $defaultType); } return $this->buildNormalizedArgument($key, $value); } throw new Exception\InvalidArgumentException(sprintf( '$argument should be %s or %s or %s or %s or %s, "%s" given', 'null', 'scalar', 'array', 'Zend\Db\Sql\ExpressionInterface', 'Zend\Db\Sql\SqlInterface', is_object($argument) ? get_class($argument) : gettype($argument) )); } /** * @param mixed $argument * @param string $argumentType * * @return array * * @throws Exception\InvalidArgumentException */ private function buildNormalizedArgument($argument, $argumentType) { if (! in_array($argumentType, $this->allowedTypes)) { throw new Exception\InvalidArgumentException(sprintf( 'Argument type should be in array(%s)', implode(',', $this->allowedTypes) )); } return [ $argument, $argumentType, ]; } } zend-db-release-2.8.1/src/Sql/AbstractPreparableSql.php000066400000000000000000000023421270372430400227460ustar00rootroot00000000000000getParameterContainer(); if (! $parameterContainer instanceof ParameterContainer) { $parameterContainer = new ParameterContainer(); $statementContainer->setParameterContainer($parameterContainer); } $statementContainer->setSql( $this->buildSqlString($adapter->getPlatform(), $adapter->getDriver(), $parameterContainer) ); return $statementContainer; } } zend-db-release-2.8.1/src/Sql/AbstractSql.php000066400000000000000000000413441270372430400207550ustar00rootroot00000000000000 '', 'subselectCount' => 0]; /** * @var array */ protected $instanceParameterIndex = []; /** * {@inheritDoc} */ public function getSqlString(PlatformInterface $adapterPlatform = null) { $adapterPlatform = ($adapterPlatform) ?: new DefaultAdapterPlatform; return $this->buildSqlString($adapterPlatform); } /** * @param PlatformInterface $platform * @param null|DriverInterface $driver * @param null|ParameterContainer $parameterContainer * @return string */ protected function buildSqlString( PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null ) { $this->localizeVariables(); $sqls = []; $parameters = []; foreach ($this->specifications as $name => $specification) { $parameters[$name] = $this->{'process' . $name}( $platform, $driver, $parameterContainer, $sqls, $parameters ); if ($specification && is_array($parameters[$name])) { $sqls[$name] = $this->createSqlFromSpecificationAndParameters($specification, $parameters[$name]); continue; } if (is_string($parameters[$name])) { $sqls[$name] = $parameters[$name]; } } return rtrim(implode(' ', $sqls), "\n ,"); } /** * Render table with alias in from/join parts * * @todo move TableIdentifier concatination here * @param string $table * @param string $alias * @return string */ protected function renderTable($table, $alias = null) { return $table . ($alias ? ' AS ' . $alias : ''); } /** * @staticvar int $runtimeExpressionPrefix * @param ExpressionInterface $expression * @param PlatformInterface $platform * @param null|DriverInterface $driver * @param null|ParameterContainer $parameterContainer * @param null|string $namedParameterPrefix * @return string * @throws Exception\RuntimeException */ protected function processExpression( ExpressionInterface $expression, PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null, $namedParameterPrefix = null ) { $namedParameterPrefix = ! $namedParameterPrefix ? $namedParameterPrefix : $this->processInfo['paramPrefix'] . $namedParameterPrefix; // static counter for the number of times this method was invoked across the PHP runtime static $runtimeExpressionPrefix = 0; if ($parameterContainer && ((!is_string($namedParameterPrefix) || $namedParameterPrefix == ''))) { $namedParameterPrefix = sprintf('expr%04dParam', ++$runtimeExpressionPrefix); } else { $namedParameterPrefix = preg_replace('/\s/', '__', $namedParameterPrefix); } $sql = ''; // initialize variables $parts = $expression->getExpressionData(); if (! isset($this->instanceParameterIndex[$namedParameterPrefix])) { $this->instanceParameterIndex[$namedParameterPrefix] = 1; } $expressionParamIndex = &$this->instanceParameterIndex[$namedParameterPrefix]; foreach ($parts as $part) { // #7407: use $expression->getExpression() to get the unescaped // version of the expression if (is_string($part) && $expression instanceof Expression) { $sql .= $expression->getExpression(); continue; } // If it is a string, simply tack it onto the return sql // "specification" string if (is_string($part)) { $sql .= $part; continue; } if (! is_array($part)) { throw new Exception\RuntimeException( 'Elements returned from getExpressionData() array must be a string or array.' ); } // Process values and types (the middle and last position of the // expression data) $values = $part[1]; $types = isset($part[2]) ? $part[2] : []; foreach ($values as $vIndex => $value) { if (!isset($types[$vIndex])) { continue; } $type = $types[$vIndex]; if ($value instanceof Select) { // process sub-select $values[$vIndex] = '(' . $this->processSubSelect($value, $platform, $driver, $parameterContainer) . ')'; } elseif ($value instanceof ExpressionInterface) { // recursive call to satisfy nested expressions $values[$vIndex] = $this->processExpression( $value, $platform, $driver, $parameterContainer, $namedParameterPrefix . $vIndex . 'subpart' ); } elseif ($type == ExpressionInterface::TYPE_IDENTIFIER) { $values[$vIndex] = $platform->quoteIdentifierInFragment($value); } elseif ($type == ExpressionInterface::TYPE_VALUE) { // if prepareType is set, it means that this particular value must be // passed back to the statement in a way it can be used as a placeholder value if ($parameterContainer) { $name = $namedParameterPrefix . $expressionParamIndex++; $parameterContainer->offsetSet($name, $value); $values[$vIndex] = $driver->formatParameterName($name); continue; } // if not a preparable statement, simply quote the value and move on $values[$vIndex] = $platform->quoteValue($value); } elseif ($type == ExpressionInterface::TYPE_LITERAL) { $values[$vIndex] = $value; } } // After looping the values, interpolate them into the sql string // (they might be placeholder names, or values) $sql .= vsprintf($part[0], $values); } return $sql; } /** * @param string|array $specifications * @param array $parameters * * @return string * * @throws Exception\RuntimeException */ protected function createSqlFromSpecificationAndParameters($specifications, $parameters) { if (is_string($specifications)) { return vsprintf($specifications, $parameters); } $parametersCount = count($parameters); foreach ($specifications as $specificationString => $paramSpecs) { if ($parametersCount == count($paramSpecs)) { break; } unset($specificationString, $paramSpecs); } if (!isset($specificationString)) { throw new Exception\RuntimeException( 'A number of parameters was found that is not supported by this specification' ); } $topParameters = []; foreach ($parameters as $position => $paramsForPosition) { if (isset($paramSpecs[$position]['combinedby'])) { $multiParamValues = []; foreach ($paramsForPosition as $multiParamsForPosition) { $ppCount = count($multiParamsForPosition); if (!isset($paramSpecs[$position][$ppCount])) { throw new Exception\RuntimeException(sprintf( 'A number of parameters (%d) was found that is not supported by this specification', $ppCount )); } $multiParamValues[] = vsprintf($paramSpecs[$position][$ppCount], $multiParamsForPosition); } $topParameters[] = implode($paramSpecs[$position]['combinedby'], $multiParamValues); } elseif ($paramSpecs[$position] !== null) { $ppCount = count($paramsForPosition); if (!isset($paramSpecs[$position][$ppCount])) { throw new Exception\RuntimeException(sprintf( 'A number of parameters (%d) was found that is not supported by this specification', $ppCount )); } $topParameters[] = vsprintf($paramSpecs[$position][$ppCount], $paramsForPosition); } else { $topParameters[] = $paramsForPosition; } } return vsprintf($specificationString, $topParameters); } /** * @param Select $subselect * @param PlatformInterface $platform * @param null|DriverInterface $driver * @param null|ParameterContainer $parameterContainer * @return string */ protected function processSubSelect( Select $subselect, PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null ) { if ($this instanceof PlatformDecoratorInterface) { $decorator = clone $this; $decorator->setSubject($subselect); } else { $decorator = $subselect; } if ($parameterContainer) { // Track subselect prefix and count for parameters $processInfoContext = ($decorator instanceof PlatformDecoratorInterface) ? $subselect : $decorator; $this->processInfo['subselectCount']++; $processInfoContext->processInfo['subselectCount'] = $this->processInfo['subselectCount']; $processInfoContext->processInfo['paramPrefix'] = 'subselect' . $processInfoContext->processInfo['subselectCount']; $sql = $decorator->buildSqlString($platform, $driver, $parameterContainer); // copy count $this->processInfo['subselectCount'] = $decorator->processInfo['subselectCount']; return $sql; } return $decorator->buildSqlString($platform, $driver, $parameterContainer); } /** * @param Join[] $joins * @param PlatformInterface $platform * @param null|DriverInterface $driver * @param null|ParameterContainer $parameterContainer * @return null|string[] Null if no joins present, array of JOIN statements * otherwise * @throws Exception\InvalidArgumentException for invalid JOIN table names. */ protected function processJoin( Join $joins, PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null ) { if (! $joins->count()) { return; } // process joins $joinSpecArgArray = []; foreach ($joins->getJoins() as $j => $join) { $joinName = null; $joinAs = null; // table name if (is_array($join['name'])) { $joinName = current($join['name']); $joinAs = $platform->quoteIdentifier(key($join['name'])); } else { $joinName = $join['name']; } if ($joinName instanceof Expression) { $joinName = $joinName->getExpression(); } elseif ($joinName instanceof TableIdentifier) { $joinName = $joinName->getTableAndSchema(); $joinName = ($joinName[1] ? $platform->quoteIdentifier($joinName[1]) . $platform->getIdentifierSeparator() : '') . $platform->quoteIdentifier($joinName[0]); } elseif ($joinName instanceof Select) { $joinName = '(' . $this->processSubSelect($joinName, $platform, $driver, $parameterContainer) . ')'; } elseif (is_string($joinName) || (is_object($joinName) && is_callable([$joinName, '__toString']))) { $joinName = $platform->quoteIdentifier($joinName); } else { throw new Exception\InvalidArgumentException(sprintf('Join name expected to be Expression|TableIdentifier|Select|string, "%s" given', gettype($joinName))); } $joinSpecArgArray[$j] = [ strtoupper($join['type']), $this->renderTable($joinName, $joinAs), ]; // on expression // note: for Expression objects, pass them to processExpression with a prefix specific to each join (used for named parameters) $joinSpecArgArray[$j][] = ($join['on'] instanceof ExpressionInterface) ? $this->processExpression($join['on'], $platform, $driver, $parameterContainer, 'join' . ($j+1) . 'part') : $platform->quoteIdentifierInFragment($join['on'], ['=', 'AND', 'OR', '(', ')', 'BETWEEN', '<', '>']); // on } return [$joinSpecArgArray]; } /** * @param null|array|ExpressionInterface|Select $column * @param PlatformInterface $platform * @param null|DriverInterface $driver * @param null|string $namedParameterPrefix * @param null|ParameterContainer $parameterContainer * @return string */ protected function resolveColumnValue( $column, PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null, $namedParameterPrefix = null ) { $namedParameterPrefix = ! $namedParameterPrefix ? $namedParameterPrefix : $this->processInfo['paramPrefix'] . $namedParameterPrefix; $isIdentifier = false; $fromTable = ''; if (is_array($column)) { if (isset($column['isIdentifier'])) { $isIdentifier = (bool) $column['isIdentifier']; } if (isset($column['fromTable']) && $column['fromTable'] !== null) { $fromTable = $column['fromTable']; } $column = $column['column']; } if ($column instanceof ExpressionInterface) { return $this->processExpression($column, $platform, $driver, $parameterContainer, $namedParameterPrefix); } if ($column instanceof Select) { return '(' . $this->processSubSelect($column, $platform, $driver, $parameterContainer) . ')'; } if ($column === null) { return 'NULL'; } return $isIdentifier ? $fromTable . $platform->quoteIdentifierInFragment($column) : $platform->quoteValue($column); } /** * @param string|TableIdentifier|Select $table * @param PlatformInterface $platform * @param DriverInterface $driver * @param ParameterContainer $parameterContainer * @return string */ protected function resolveTable( $table, PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null ) { $schema = null; if ($table instanceof TableIdentifier) { list($table, $schema) = $table->getTableAndSchema(); } if ($table instanceof Select) { $table = '(' . $this->processSubselect($table, $platform, $driver, $parameterContainer) . ')'; } elseif ($table) { $table = $platform->quoteIdentifier($table); } if ($schema && $table) { $table = $platform->quoteIdentifier($schema) . $platform->getIdentifierSeparator() . $table; } return $table; } /** * Copy variables from the subject into the local properties */ protected function localizeVariables() { if (! $this instanceof PlatformDecoratorInterface) { return; } foreach (get_object_vars($this->subject) as $name => $value) { $this->{$name} = $value; } } } zend-db-release-2.8.1/src/Sql/Combine.php000066400000000000000000000130241270372430400201000ustar00rootroot00000000000000 '%1$s (%2$s) ', ]; /** * @var Select[][] */ private $combine = []; /** * @param Select|array|null $select * @param string $type * @param string $modifier */ public function __construct($select = null, $type = self::COMBINE_UNION, $modifier = '') { if ($select) { $this->combine($select, $type, $modifier); } } /** * Create combine clause * * @param Select|array $select * @param string $type * @param string $modifier * * @return self */ public function combine($select, $type = self::COMBINE_UNION, $modifier = '') { if (is_array($select)) { foreach ($select as $combine) { if ($combine instanceof Select) { $combine = [$combine]; } $this->combine( $combine[0], isset($combine[1]) ? $combine[1] : $type, isset($combine[2]) ? $combine[2] : $modifier ); } return $this; } if (! $select instanceof Select) { throw new Exception\InvalidArgumentException(sprintf( '$select must be a array or instance of Select, "%s" given', is_object($select) ? get_class($select) : gettype($select) )); } $this->combine[] = [ 'select' => $select, 'type' => $type, 'modifier' => $modifier ]; return $this; } /** * Create union clause * * @param Select|array $select * @param string $modifier * * @return self */ public function union($select, $modifier = '') { return $this->combine($select, self::COMBINE_UNION, $modifier); } /** * Create except clause * * @param Select|array $select * @param string $modifier * * @return self */ public function except($select, $modifier = '') { return $this->combine($select, self::COMBINE_EXCEPT, $modifier); } /** * Create intersect clause * * @param Select|array $select * @param string $modifier * @return self */ public function intersect($select, $modifier = '') { return $this->combine($select, self::COMBINE_INTERSECT, $modifier); } /** * Build sql string * * @param PlatformInterface $platform * @param DriverInterface $driver * @param ParameterContainer $parameterContainer * * @return string */ protected function buildSqlString(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { if (!$this->combine) { return; } $sql = ''; foreach ($this->combine as $i => $combine) { $type = $i == 0 ? '' : strtoupper($combine['type'] . ($combine['modifier'] ? ' ' . $combine['modifier'] : '')); $select = $this->processSubSelect($combine['select'], $platform, $driver, $parameterContainer); $sql .= sprintf( $this->specifications[self::COMBINE], $type, $select ); } return trim($sql, ' '); } /** * @return $this */ public function alignColumns() { if (!$this->combine) { return $this; } $allColumns = []; foreach ($this->combine as $combine) { $allColumns = array_merge( $allColumns, $combine['select']->getRawState(self::COLUMNS) ); } foreach ($this->combine as $combine) { $combineColumns = $combine['select']->getRawState(self::COLUMNS); $aligned = []; foreach ($allColumns as $alias => $column) { $aligned[$alias] = isset($combineColumns[$alias]) ? $combineColumns[$alias] : new Predicate\Expression('NULL'); } $combine['select']->columns($aligned, false); } return $this; } /** * Get raw state * * @param string $key * * @return array */ public function getRawState($key = null) { $rawState = [ self::COMBINE => $this->combine, self::COLUMNS => $this->combine ? $this->combine[0]['select']->getRawState(self::COLUMNS) : [], ]; return (isset($key) && array_key_exists($key, $rawState)) ? $rawState[$key] : $rawState; } } zend-db-release-2.8.1/src/Sql/Ddl/000077500000000000000000000000001270372430400165165ustar00rootroot00000000000000zend-db-release-2.8.1/src/Sql/Ddl/AlterTable.php000066400000000000000000000131671270372430400212560ustar00rootroot00000000000000 "ALTER TABLE %1\$s\n", self::ADD_COLUMNS => [ "%1\$s" => [ [1 => "ADD COLUMN %1\$s,\n", 'combinedby' => ""] ] ], self::CHANGE_COLUMNS => [ "%1\$s" => [ [2 => "CHANGE COLUMN %1\$s %2\$s,\n", 'combinedby' => ""], ] ], self::DROP_COLUMNS => [ "%1\$s" => [ [1 => "DROP COLUMN %1\$s,\n", 'combinedby' => ""], ] ], self::ADD_CONSTRAINTS => [ "%1\$s" => [ [1 => "ADD %1\$s,\n", 'combinedby' => ""], ] ], self::DROP_CONSTRAINTS => [ "%1\$s" => [ [1 => "DROP CONSTRAINT %1\$s,\n", 'combinedby' => ""], ] ] ]; /** * @var string */ protected $table = ''; /** * @param string $table */ public function __construct($table = '') { ($table) ? $this->setTable($table) : null; } /** * @param string $name * @return self */ public function setTable($name) { $this->table = $name; return $this; } /** * @param Column\ColumnInterface $column * @return self */ public function addColumn(Column\ColumnInterface $column) { $this->addColumns[] = $column; return $this; } /** * @param string $name * @param Column\ColumnInterface $column * @return self */ public function changeColumn($name, Column\ColumnInterface $column) { $this->changeColumns[$name] = $column; return $this; } /** * @param string $name * @return self */ public function dropColumn($name) { $this->dropColumns[] = $name; return $this; } /** * @param string $name * @return self */ public function dropConstraint($name) { $this->dropConstraints[] = $name; return $this; } /** * @param Constraint\ConstraintInterface $constraint * @return self */ public function addConstraint(Constraint\ConstraintInterface $constraint) { $this->addConstraints[] = $constraint; return $this; } /** * @param string|null $key * @return array */ public function getRawState($key = null) { $rawState = [ self::TABLE => $this->table, self::ADD_COLUMNS => $this->addColumns, self::DROP_COLUMNS => $this->dropColumns, self::CHANGE_COLUMNS => $this->changeColumns, self::ADD_CONSTRAINTS => $this->addConstraints, self::DROP_CONSTRAINTS => $this->dropConstraints, ]; return (isset($key) && array_key_exists($key, $rawState)) ? $rawState[$key] : $rawState; } protected function processTable(PlatformInterface $adapterPlatform = null) { return [$adapterPlatform->quoteIdentifier($this->table)]; } protected function processAddColumns(PlatformInterface $adapterPlatform = null) { $sqls = []; foreach ($this->addColumns as $column) { $sqls[] = $this->processExpression($column, $adapterPlatform); } return [$sqls]; } protected function processChangeColumns(PlatformInterface $adapterPlatform = null) { $sqls = []; foreach ($this->changeColumns as $name => $column) { $sqls[] = [ $adapterPlatform->quoteIdentifier($name), $this->processExpression($column, $adapterPlatform) ]; } return [$sqls]; } protected function processDropColumns(PlatformInterface $adapterPlatform = null) { $sqls = []; foreach ($this->dropColumns as $column) { $sqls[] = $adapterPlatform->quoteIdentifier($column); } return [$sqls]; } protected function processAddConstraints(PlatformInterface $adapterPlatform = null) { $sqls = []; foreach ($this->addConstraints as $constraint) { $sqls[] = $this->processExpression($constraint, $adapterPlatform); } return [$sqls]; } protected function processDropConstraints(PlatformInterface $adapterPlatform = null) { $sqls = []; foreach ($this->dropConstraints as $constraint) { $sqls[] = $adapterPlatform->quoteIdentifier($constraint); } return [$sqls]; } } zend-db-release-2.8.1/src/Sql/Ddl/Column/000077500000000000000000000000001270372430400177535ustar00rootroot00000000000000zend-db-release-2.8.1/src/Sql/Ddl/Column/AbstractLengthColumn.php000066400000000000000000000026731270372430400245570ustar00rootroot00000000000000setLength($length); parent::__construct($name, $nullable, $default, $options); } /** * @param int $length * * @return self */ public function setLength($length) { $this->length = (int) $length; return $this; } /** * @return int */ public function getLength() { return $this->length; } /** * @return string */ protected function getLengthExpression() { return (string) $this->length; } /** * @return array */ public function getExpressionData() { $data = parent::getExpressionData(); if ($this->getLengthExpression()) { $data[0][1][1] .= '(' . $this->getLengthExpression() . ')'; } return $data; } } zend-db-release-2.8.1/src/Sql/Ddl/Column/AbstractPrecisionColumn.php000066400000000000000000000032221270372430400252600ustar00rootroot00000000000000setDecimal($decimal); parent::__construct($name, $digits, $nullable, $default, $options); } /** * @param int $digits * * @return self */ public function setDigits($digits) { return $this->setLength($digits); } /** * @return int */ public function getDigits() { return $this->getLength(); } /** * @param int|null $decimal * @return self */ public function setDecimal($decimal) { $this->decimal = null === $decimal ? null : (int) $decimal; return $this; } /** * @return int|null */ public function getDecimal() { return $this->decimal; } /** * {@inheritDoc} */ protected function getLengthExpression() { if ($this->decimal !== null) { return $this->length . ',' . $this->decimal; } return $this->length; } } zend-db-release-2.8.1/src/Sql/Ddl/Column/AbstractTimestampColumn.php000066400000000000000000000031061270372430400252710ustar00rootroot00000000000000specification; $params = []; $params[] = $this->name; $params[] = $this->type; $types = [self::TYPE_IDENTIFIER, self::TYPE_LITERAL]; if (!$this->isNullable) { $spec .= ' NOT NULL'; } if ($this->default !== null) { $spec .= ' DEFAULT %s'; $params[] = $this->default; $types[] = self::TYPE_VALUE; } $options = $this->getOptions(); if (isset($options['on_update'])) { $spec .= ' %s'; $params[] = 'ON UPDATE CURRENT_TIMESTAMP'; $types[] = self::TYPE_LITERAL; } $data = [[ $spec, $params, $types, ]]; foreach ($this->constraints as $constraint) { $data[] = ' '; $data = array_merge($data, $constraint->getExpressionData()); } return $data; } } zend-db-release-2.8.1/src/Sql/Ddl/Column/BigInteger.php000066400000000000000000000007011270372430400225010ustar00rootroot00000000000000setName($name); $this->setNullable($nullable); $this->setDefault($default); $this->setOptions($options); } /** * @param string $name * @return self */ public function setName($name) { $this->name = (string) $name; return $this; } /** * @return null|string */ public function getName() { return $this->name; } /** * @param bool $nullable * @return self */ public function setNullable($nullable) { $this->isNullable = (bool) $nullable; return $this; } /** * @return bool */ public function isNullable() { return $this->isNullable; } /** * @param null|string|int $default * @return self */ public function setDefault($default) { $this->default = $default; return $this; } /** * @return null|string|int */ public function getDefault() { return $this->default; } /** * @param array $options * @return self */ public function setOptions(array $options) { $this->options = $options; return $this; } /** * @param string $name * @param string $value * @return self */ public function setOption($name, $value) { $this->options[$name] = $value; return $this; } /** * @return array */ public function getOptions() { return $this->options; } /** * @param ConstraintInterface $constraint * * @return self */ public function addConstraint(ConstraintInterface $constraint) { $this->constraints[] = $constraint; return $this; } /** * @return array */ public function getExpressionData() { $spec = $this->specification; $params = []; $params[] = $this->name; $params[] = $this->type; $types = [self::TYPE_IDENTIFIER, self::TYPE_LITERAL]; if (!$this->isNullable) { $spec .= ' NOT NULL'; } if ($this->default !== null) { $spec .= ' DEFAULT %s'; $params[] = $this->default; $types[] = self::TYPE_VALUE; } $data = [[ $spec, $params, $types, ]]; foreach ($this->constraints as $constraint) { $data[] = ' '; $data = array_merge($data, $constraint->getExpressionData()); } return $data; } } zend-db-release-2.8.1/src/Sql/Ddl/Column/ColumnInterface.php000066400000000000000000000015401270372430400235420ustar00rootroot00000000000000getOptions(); if (isset($options['length'])) { $data[0][1][1] .= '(' . $options['length'] . ')'; } return $data; } } zend-db-release-2.8.1/src/Sql/Ddl/Column/Text.php000066400000000000000000000007061270372430400214130ustar00rootroot00000000000000setColumns($columns); } $this->setName($name); } /** * @param string $name * @return self */ public function setName($name) { $this->name = (string) $name; return $this; } /** * @return string */ public function getName() { return $this->name; } /** * @param null|string|array $columns * @return self */ public function setColumns($columns) { $this->columns = (array) $columns; return $this; } /** * @param string $column * @return self */ public function addColumn($column) { $this->columns[] = $column; return $this; } /** * {@inheritDoc} */ public function getColumns() { return $this->columns; } /** * {@inheritDoc} */ public function getExpressionData() { $colCount = count($this->columns); $newSpecTypes = []; $values = []; $newSpec = ''; if ($this->name) { $newSpec .= $this->namedSpecification; $values[] = $this->name; $newSpecTypes[] = self::TYPE_IDENTIFIER; } $newSpec .= $this->specification; if ($colCount) { $values = array_merge($values, $this->columns); $newSpecParts = array_fill(0, $colCount, '%s'); $newSpecTypes = array_merge($newSpecTypes, array_fill(0, $colCount, self::TYPE_IDENTIFIER)); $newSpec .= sprintf($this->columnSpecification, implode(', ', $newSpecParts)); } return [[ $newSpec, $values, $newSpecTypes, ]]; } } zend-db-release-2.8.1/src/Sql/Ddl/Constraint/Check.php000066400000000000000000000025241270372430400223730ustar00rootroot00000000000000expression = $expression; $this->name = $name; } /** * {@inheritDoc} */ public function getExpressionData() { $newSpecTypes = [self::TYPE_LITERAL]; $values = [$this->expression]; $newSpec = ''; if ($this->name) { $newSpec .= $this->namedSpecification; array_unshift($values, $this->name); array_unshift($newSpecTypes, self::TYPE_IDENTIFIER); } return [[ $newSpec . $this->specification, $values, $newSpecTypes, ]]; } } zend-db-release-2.8.1/src/Sql/Ddl/Constraint/ConstraintInterface.php000066400000000000000000000007431270372430400253240ustar00rootroot00000000000000setName($name); $this->setColumns($columns); $this->setReferenceTable($referenceTable); $this->setReferenceColumn($referenceColumn); if ($onDeleteRule) { $this->setOnDeleteRule($onDeleteRule); } if ($onUpdateRule) { $this->setOnUpdateRule($onUpdateRule); } } /** * @param string $referenceTable * @return self */ public function setReferenceTable($referenceTable) { $this->referenceTable = (string) $referenceTable; return $this; } /** * @return string */ public function getReferenceTable() { return $this->referenceTable; } /** * @param null|string|array $referenceColumn * @return self */ public function setReferenceColumn($referenceColumn) { $this->referenceColumn = (array) $referenceColumn; return $this; } /** * @return array */ public function getReferenceColumn() { return $this->referenceColumn; } /** * @param string $onDeleteRule * @return self */ public function setOnDeleteRule($onDeleteRule) { $this->onDeleteRule = (string) $onDeleteRule; return $this; } /** * @return string */ public function getOnDeleteRule() { return $this->onDeleteRule; } /** * @param string $onUpdateRule * @return self */ public function setOnUpdateRule($onUpdateRule) { $this->onUpdateRule = (string) $onUpdateRule; return $this; } /** * @return string */ public function getOnUpdateRule() { return $this->onUpdateRule; } /** * @return array */ public function getExpressionData() { $data = parent::getExpressionData(); $colCount = count($this->referenceColumn); $newSpecTypes = [self::TYPE_IDENTIFIER]; $values = [$this->referenceTable]; $data[0][0] .= $this->referenceSpecification[0]; if ($colCount) { $values = array_merge($values, $this->referenceColumn); $newSpecParts = array_fill(0, $colCount, '%s'); $newSpecTypes = array_merge($newSpecTypes, array_fill(0, $colCount, self::TYPE_IDENTIFIER)); $data[0][0] .= sprintf('(%s) ', implode(', ', $newSpecParts)); } $data[0][0] .= $this->referenceSpecification[1]; $values[] = $this->onDeleteRule; $values[] = $this->onUpdateRule; $newSpecTypes[] = self::TYPE_LITERAL; $newSpecTypes[] = self::TYPE_LITERAL; $data[0][1] = array_merge($data[0][1], $values); $data[0][2] = array_merge($data[0][2], $newSpecTypes); return $data; } } zend-db-release-2.8.1/src/Sql/Ddl/Constraint/PrimaryKey.php000066400000000000000000000007361270372430400234550ustar00rootroot00000000000000 'CREATE %1$sTABLE %2$s (', self::COLUMNS => [ "\n %1\$s" => [ [1 => '%1$s', 'combinedby' => ",\n "] ] ], 'combinedBy' => ",", self::CONSTRAINTS => [ "\n %1\$s" => [ [1 => '%1$s', 'combinedby' => ",\n "] ] ], 'statementEnd' => '%1$s', ]; /** * @var string */ protected $table = ''; /** * @param string $table * @param bool $isTemporary */ public function __construct($table = '', $isTemporary = false) { $this->table = $table; $this->setTemporary($isTemporary); } /** * @param bool $temporary * @return self */ public function setTemporary($temporary) { $this->isTemporary = (bool) $temporary; return $this; } /** * @return bool */ public function isTemporary() { return $this->isTemporary; } /** * @param string $name * @return self */ public function setTable($name) { $this->table = $name; return $this; } /** * @param Column\ColumnInterface $column * @return self */ public function addColumn(Column\ColumnInterface $column) { $this->columns[] = $column; return $this; } /** * @param Constraint\ConstraintInterface $constraint * @return self */ public function addConstraint(Constraint\ConstraintInterface $constraint) { $this->constraints[] = $constraint; return $this; } /** * @param string|null $key * @return array */ public function getRawState($key = null) { $rawState = [ self::COLUMNS => $this->columns, self::CONSTRAINTS => $this->constraints, self::TABLE => $this->table, ]; return (isset($key) && array_key_exists($key, $rawState)) ? $rawState[$key] : $rawState; } /** * @param PlatformInterface $adapterPlatform * * @return string[] */ protected function processTable(PlatformInterface $adapterPlatform = null) { return [ $this->isTemporary ? 'TEMPORARY ' : '', $adapterPlatform->quoteIdentifier($this->table), ]; } /** * @param PlatformInterface $adapterPlatform * * @return string[][]|null */ protected function processColumns(PlatformInterface $adapterPlatform = null) { if (! $this->columns) { return; } $sqls = []; foreach ($this->columns as $column) { $sqls[] = $this->processExpression($column, $adapterPlatform); } return [$sqls]; } /** * @param PlatformInterface $adapterPlatform * * @return array|string */ protected function processCombinedby(PlatformInterface $adapterPlatform = null) { if ($this->constraints && $this->columns) { return $this->specifications['combinedBy']; } } /** * @param PlatformInterface $adapterPlatform * * @return string[][]|null */ protected function processConstraints(PlatformInterface $adapterPlatform = null) { if (!$this->constraints) { return; } $sqls = []; foreach ($this->constraints as $constraint) { $sqls[] = $this->processExpression($constraint, $adapterPlatform); } return [$sqls]; } /** * @param PlatformInterface $adapterPlatform * * @return string[] */ protected function processStatementEnd(PlatformInterface $adapterPlatform = null) { return ["\n)"]; } } zend-db-release-2.8.1/src/Sql/Ddl/DropTable.php000066400000000000000000000017221270372430400211050ustar00rootroot00000000000000 'DROP TABLE %1$s' ]; /** * @var string */ protected $table = ''; /** * @param string $table */ public function __construct($table = '') { $this->table = $table; } protected function processTable(PlatformInterface $adapterPlatform = null) { return [$adapterPlatform->quoteIdentifier($this->table)]; } } zend-db-release-2.8.1/src/Sql/Ddl/Index/000077500000000000000000000000001270372430400175655ustar00rootroot00000000000000zend-db-release-2.8.1/src/Sql/Ddl/Index/AbstractIndex.php000066400000000000000000000007101270372430400230270ustar00rootroot00000000000000setColumns($columns); $this->name = null === $name ? null : (string) $name; $this->lengths = $lengths; } /** * * @return array of array|string should return an array in the format: * * array ( * // a sprintf formatted string * string $specification, * * // the values for the above sprintf formatted string * array $values, * * // an array of equal length of the $values array, with either TYPE_IDENTIFIER or TYPE_VALUE for each value * array $types, * ) * */ public function getExpressionData() { $colCount = count($this->columns); $values = []; $values[] = $this->name ?: ''; $newSpecTypes = [self::TYPE_IDENTIFIER]; $newSpecParts = []; for ($i = 0; $i < $colCount; $i++) { $specPart = '%s'; if (isset($this->lengths[$i])) { $specPart .= "({$this->lengths[$i]})"; } $newSpecParts[] = $specPart; $newSpecTypes[] = self::TYPE_IDENTIFIER; } $newSpec = str_replace('...', implode(', ', $newSpecParts), $this->specification); return [[ $newSpec, array_merge($values, $this->columns), $newSpecTypes, ]]; } } zend-db-release-2.8.1/src/Sql/Ddl/SqlInterface.php000066400000000000000000000006711270372430400216130ustar00rootroot00000000000000 'DELETE FROM %1$s', self::SPECIFICATION_WHERE => 'WHERE %1$s' ]; /** * @var string|TableIdentifier */ protected $table = ''; /** * @var bool */ protected $emptyWhereProtection = true; /** * @var array */ protected $set = []; /** * @var null|string|Where */ protected $where = null; /** * Constructor * * @param null|string|TableIdentifier $table */ public function __construct($table = null) { if ($table) { $this->from($table); } $this->where = new Where(); } /** * Create from statement * * @param string|TableIdentifier $table * @return Delete */ public function from($table) { $this->table = $table; return $this; } /** * @param null $key * * @return mixed */ public function getRawState($key = null) { $rawState = [ 'emptyWhereProtection' => $this->emptyWhereProtection, 'table' => $this->table, 'set' => $this->set, 'where' => $this->where ]; return (isset($key) && array_key_exists($key, $rawState)) ? $rawState[$key] : $rawState; } /** * Create where clause * * @param Where|\Closure|string|array $predicate * @param string $combination One of the OP_* constants from Predicate\PredicateSet * * @return Delete */ public function where($predicate, $combination = Predicate\PredicateSet::OP_AND) { if ($predicate instanceof Where) { $this->where = $predicate; } else { $this->where->addPredicates($predicate, $combination); } return $this; } /** * @param PlatformInterface $platform * @param DriverInterface|null $driver * @param ParameterContainer|null $parameterContainer * * @return string */ protected function processDelete(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { return sprintf( $this->specifications[static::SPECIFICATION_DELETE], $this->resolveTable($this->table, $platform, $driver, $parameterContainer) ); } /** * @param PlatformInterface $platform * @param DriverInterface|null $driver * @param ParameterContainer|null $parameterContainer * * @return null|string */ protected function processWhere(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { if ($this->where->count() == 0) { return; } return sprintf( $this->specifications[static::SPECIFICATION_WHERE], $this->processExpression($this->where, $platform, $driver, $parameterContainer, 'where') ); } /** * Property overloading * * Overloads "where" only. * * @param string $name * * @return Where|null */ public function __get($name) { switch (strtolower($name)) { case 'where': return $this->where; } } } zend-db-release-2.8.1/src/Sql/Exception/000077500000000000000000000000001270372430400177515ustar00rootroot00000000000000zend-db-release-2.8.1/src/Sql/Exception/ExceptionInterface.php000066400000000000000000000006661270372430400242510ustar00rootroot00000000000000setExpression($expression); } if ($types) { // should be deprecated and removed version 3.0.0 if (is_array($parameters)) { foreach ($parameters as $i=>$parameter) { $parameters[$i] = [ $parameter => isset($types[$i]) ? $types[$i] : self::TYPE_VALUE, ]; } } elseif (is_scalar($parameters)) { $parameters = [ $parameters => $types[0], ]; } } if ($parameters) { $this->setParameters($parameters); } } /** * @param $expression * @return Expression * @throws Exception\InvalidArgumentException */ public function setExpression($expression) { if (!is_string($expression) || $expression == '') { throw new Exception\InvalidArgumentException('Supplied expression must be a string.'); } $this->expression = $expression; return $this; } /** * @return string */ public function getExpression() { return $this->expression; } /** * @param $parameters * @return Expression * @throws Exception\InvalidArgumentException */ public function setParameters($parameters) { if (!is_scalar($parameters) && !is_array($parameters)) { throw new Exception\InvalidArgumentException('Expression parameters must be a scalar or array.'); } $this->parameters = $parameters; return $this; } /** * @return array */ public function getParameters() { return $this->parameters; } /** * @deprecated * @param array $types * @return Expression */ public function setTypes(array $types) { $this->types = $types; return $this; } /** * @deprecated * @return array */ public function getTypes() { return $this->types; } /** * @return array * @throws Exception\RuntimeException */ public function getExpressionData() { $parameters = (is_scalar($this->parameters)) ? [$this->parameters] : $this->parameters; $parametersCount = count($parameters); $expression = str_replace('%', '%%', $this->expression); if ($parametersCount == 0) { return [ str_ireplace(self::PLACEHOLDER, '', $expression) ]; } // assign locally, escaping % signs $expression = str_replace(self::PLACEHOLDER, '%s', $expression, $count); if ($count !== $parametersCount) { throw new Exception\RuntimeException('The number of replacements in the expression does not match the number of parameters'); } foreach ($parameters as $parameter) { list($values[], $types[]) = $this->normalizeArgument($parameter, self::TYPE_VALUE); } return [[ $expression, $values, $types ]]; } } zend-db-release-2.8.1/src/Sql/ExpressionInterface.php000066400000000000000000000017771270372430400225200ustar00rootroot00000000000000 'INSERT INTO %1$s (%2$s) VALUES (%3$s)', self::SPECIFICATION_SELECT => 'INSERT INTO %1$s %2$s %3$s', ]; /** * @var string|TableIdentifier */ protected $table = null; protected $columns = []; /** * @var array|Select */ protected $select = null; /** * Constructor * * @param null|string|TableIdentifier $table */ public function __construct($table = null) { if ($table) { $this->into($table); } } /** * Create INTO clause * * @param string|TableIdentifier $table * @return Insert */ public function into($table) { $this->table = $table; return $this; } /** * Specify columns * * @param array $columns * @return Insert */ public function columns(array $columns) { $this->columns = array_flip($columns); return $this; } /** * Specify values to insert * * @param array|Select $values * @param string $flag one of VALUES_MERGE or VALUES_SET; defaults to VALUES_SET * @throws Exception\InvalidArgumentException * @return Insert */ public function values($values, $flag = self::VALUES_SET) { if ($values instanceof Select) { if ($flag == self::VALUES_MERGE) { throw new Exception\InvalidArgumentException( 'A Zend\Db\Sql\Select instance cannot be provided with the merge flag' ); } $this->select = $values; return $this; } if (!is_array($values)) { throw new Exception\InvalidArgumentException( 'values() expects an array of values or Zend\Db\Sql\Select instance' ); } if ($this->select && $flag == self::VALUES_MERGE) { throw new Exception\InvalidArgumentException( 'An array of values cannot be provided with the merge flag when a Zend\Db\Sql\Select instance already exists as the value source' ); } if ($flag == self::VALUES_SET) { $this->columns = $this->isAssocativeArray($values) ? $values : array_combine(array_keys($this->columns), array_values($values)); } else { foreach ($values as $column => $value) { $this->columns[$column] = $value; } } return $this; } /** * Simple test for an associative array * * @link http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential * @param array $array * @return bool */ private function isAssocativeArray(array $array) { return array_keys($array) !== range(0, count($array) - 1); } /** * Create INTO SELECT clause * * @param Select $select * @return self */ public function select(Select $select) { return $this->values($select); } /** * Get raw state * * @param string $key * @return mixed */ public function getRawState($key = null) { $rawState = [ 'table' => $this->table, 'columns' => array_keys($this->columns), 'values' => array_values($this->columns) ]; return (isset($key) && array_key_exists($key, $rawState)) ? $rawState[$key] : $rawState; } protected function processInsert(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { if ($this->select) { return; } if (!$this->columns) { throw new Exception\InvalidArgumentException('values or select should be present'); } $columns = []; $values = []; foreach ($this->columns as $column => $value) { $columns[] = $platform->quoteIdentifier($column); if (is_scalar($value) && $parameterContainer) { $values[] = $driver->formatParameterName($column); $parameterContainer->offsetSet($column, $value); } else { $values[] = $this->resolveColumnValue( $value, $platform, $driver, $parameterContainer ); } } return sprintf( $this->specifications[static::SPECIFICATION_INSERT], $this->resolveTable($this->table, $platform, $driver, $parameterContainer), implode(', ', $columns), implode(', ', $values) ); } protected function processSelect(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { if (!$this->select) { return; } $selectSql = $this->processSubSelect($this->select, $platform, $driver, $parameterContainer); $columns = array_map([$platform, 'quoteIdentifier'], array_keys($this->columns)); $columns = implode(', ', $columns); return sprintf( $this->specifications[static::SPECIFICATION_SELECT], $this->resolveTable($this->table, $platform, $driver, $parameterContainer), $columns ? "($columns)" : "", $selectSql ); } /** * Overloading: variable setting * * Proxies to values, using VALUES_MERGE strategy * * @param string $name * @param mixed $value * @return Insert */ public function __set($name, $value) { $this->columns[$name] = $value; return $this; } /** * Overloading: variable unset * * Proxies to values and columns * * @param string $name * @throws Exception\InvalidArgumentException * @return void */ public function __unset($name) { if (!array_key_exists($name, $this->columns)) { throw new Exception\InvalidArgumentException('The key ' . $name . ' was not found in this objects column list'); } unset($this->columns[$name]); } /** * Overloading: variable isset * * Proxies to columns; does a column of that name exist? * * @param string $name * @return bool */ public function __isset($name) { return array_key_exists($name, $this->columns); } /** * Overloading: variable retrieval * * Retrieves value by column name * * @param string $name * @throws Exception\InvalidArgumentException * @return mixed */ public function __get($name) { if (!array_key_exists($name, $this->columns)) { throw new Exception\InvalidArgumentException('The key ' . $name . ' was not found in this objects column list'); } return $this->columns[$name]; } } zend-db-release-2.8.1/src/Sql/Join.php000066400000000000000000000074201270372430400174260ustar00rootroot00000000000000position = 0; } /** * Rewind iterator. */ public function rewind() { $this->position = 0; } /** * Return current join specification. * * @return array */ public function current() { return $this->joins[$this->position]; } /** * Return the current iterator index. * * @return int */ public function key() { return $this->position; } /** * Advance to the next JOIN specification. */ public function next() { ++$this->position; } /** * Is the iterator at a valid position? * * @return bool */ public function valid() { return isset($this->joins[$this->position]); } /** * @return array */ public function getJoins() { return $this->joins; } /** * @param string|array $name A table name on which to join, or a single * element associative array, of the form alias => table * @param string $on A string specification describing the fields to join on. * @param string|string[]|int|int[] $columns A single column name, an array * of column names, or (a) specification(s) such as SQL_STAR representing * the columns to join. * @param string $type The JOIN type to use; see the JOIN_* constants. * @return self Implements a fluent interface. * @throws Exception\InvalidArgumentException for invalid $name values. */ public function join($name, $on, $columns = [Select::SQL_STAR], $type = Join::JOIN_INNER) { if (is_array($name) && (! is_string(key($name)) || count($name) !== 1)) { throw new Exception\InvalidArgumentException( sprintf("join() expects '%s' as a single element associative array", array_shift($name)) ); } if (! is_array($columns)) { $columns = [$columns]; } $this->joins[] = [ 'name' => $name, 'on' => $on, 'columns' => $columns, 'type' => $type ? $type : Join::JOIN_INNER ]; return $this; } /** * Reset to an empty list of JOIN specifications. * * @return self Implements a fluent interface. */ public function reset() { $this->joins = []; return $this; } /** * Get count of attached predicates * * @return int */ public function count() { return count($this->joins); } } zend-db-release-2.8.1/src/Sql/Literal.php000066400000000000000000000020671270372430400201250ustar00rootroot00000000000000literal = $literal; } /** * @param string $literal * @return Literal */ public function setLiteral($literal) { $this->literal = $literal; return $this; } /** * @return string */ public function getLiteral() { return $this->literal; } /** * @return array */ public function getExpressionData() { return [[ str_replace('%', '%%', $this->literal), [], [] ]]; } } zend-db-release-2.8.1/src/Sql/Platform/000077500000000000000000000000001270372430400175775ustar00rootroot00000000000000zend-db-release-2.8.1/src/Sql/Platform/AbstractPlatform.php000066400000000000000000000056271270372430400235720ustar00rootroot00000000000000subject = $subject; return $this; } /** * @param string $type * @param PlatformDecoratorInterface $decorator * * @return void */ public function setTypeDecorator($type, PlatformDecoratorInterface $decorator) { $this->decorators[$type] = $decorator; } /** * @param PreparableSqlInterface|SqlInterface $subject * @return PlatformDecoratorInterface|PreparableSqlInterface|SqlInterface */ public function getTypeDecorator($subject) { foreach ($this->decorators as $type => $decorator) { if ($subject instanceof $type) { $decorator->setSubject($subject); return $decorator; } } return $subject; } /** * @return array|PlatformDecoratorInterface[] */ public function getDecorators() { return $this->decorators; } /** * {@inheritDoc} * * @throws Exception\RuntimeException */ public function prepareStatement(AdapterInterface $adapter, StatementContainerInterface $statementContainer) { if (! $this->subject instanceof PreparableSqlInterface) { throw new Exception\RuntimeException('The subject does not appear to implement Zend\Db\Sql\PreparableSqlInterface, thus calling prepareStatement() has no effect'); } $this->getTypeDecorator($this->subject)->prepareStatement($adapter, $statementContainer); return $statementContainer; } /** * {@inheritDoc} * * @throws Exception\RuntimeException */ public function getSqlString(PlatformInterface $adapterPlatform = null) { if (! $this->subject instanceof SqlInterface) { throw new Exception\RuntimeException('The subject does not appear to implement Zend\Db\Sql\SqlInterface, thus calling prepareStatement() has no effect'); } return $this->getTypeDecorator($this->subject)->getSqlString($adapterPlatform); } } zend-db-release-2.8.1/src/Sql/Platform/IbmDb2/000077500000000000000000000000001270372430400206365ustar00rootroot00000000000000zend-db-release-2.8.1/src/Sql/Platform/IbmDb2/IbmDb2.php000066400000000000000000000012541270372430400224100ustar00rootroot00000000000000setTypeDecorator('Zend\Db\Sql\Select', ($selectDecorator) ?: new SelectDecorator()); } } zend-db-release-2.8.1/src/Sql/Platform/IbmDb2/SelectDecorator.php000066400000000000000000000125021270372430400244310ustar00rootroot00000000000000isSelectContainDistinct; } /** * @param boolean $isSelectContainDistinct */ public function setIsSelectContainDistinct($isSelectContainDistinct) { $this->isSelectContainDistinct = $isSelectContainDistinct; } /** * @param Select $select */ public function setSubject($select) { $this->subject = $select; } /** * @see Select::renderTable */ protected function renderTable($table, $alias = null) { return $table . ' ' . $alias; } protected function localizeVariables() { parent::localizeVariables(); // set specifications unset($this->specifications[self::LIMIT]); unset($this->specifications[self::OFFSET]); $this->specifications['LIMITOFFSET'] = null; } /** * @param PlatformInterface $platform * @param DriverInterface $driver * @param ParameterContainer $parameterContainer * @param array $sqls * @param array $parameters */ protected function processLimitOffset(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null, &$sqls, &$parameters) { if ($this->limit === null && $this->offset === null) { return; } $selectParameters = $parameters[self::SELECT]; $starSuffix = $platform->getIdentifierSeparator() . self::SQL_STAR; foreach ($selectParameters[0] as $i => $columnParameters) { if ($columnParameters[0] == self::SQL_STAR || (isset($columnParameters[1]) && $columnParameters[1] == self::SQL_STAR) || strpos($columnParameters[0], $starSuffix) ) { $selectParameters[0] = [[self::SQL_STAR]]; break; } if (isset($columnParameters[1])) { array_shift($columnParameters); $selectParameters[0][$i] = $columnParameters; } } // first, produce column list without compound names (using the AS portion only) array_unshift($sqls, $this->createSqlFromSpecificationAndParameters( ['SELECT %1$s FROM (' => current($this->specifications[self::SELECT])], $selectParameters )); if (preg_match('/DISTINCT/i', $sqls[0])) { $this->setIsSelectContainDistinct(true); } if ($parameterContainer) { // create bottom part of query, with offset and limit using row_number $limitParamName = $driver->formatParameterName('limit'); $offsetParamName = $driver->formatParameterName('offset'); array_push($sqls, sprintf( ") AS ZEND_IBMDB2_SERVER_LIMIT_OFFSET_EMULATION WHERE ZEND_IBMDB2_SERVER_LIMIT_OFFSET_EMULATION.ZEND_DB_ROWNUM BETWEEN %s AND %s", $offsetParamName, $limitParamName )); if ((int) $this->offset > 0) { $parameterContainer->offsetSet('offset', (int) $this->offset + 1); } else { $parameterContainer->offsetSet('offset', (int) $this->offset); } $parameterContainer->offsetSet('limit', (int) $this->limit + (int) $this->offset); } else { if ((int) $this->offset > 0) { $offset = (int) $this->offset + 1; } else { $offset = (int) $this->offset; } array_push($sqls, sprintf( ") AS ZEND_IBMDB2_SERVER_LIMIT_OFFSET_EMULATION WHERE ZEND_IBMDB2_SERVER_LIMIT_OFFSET_EMULATION.ZEND_DB_ROWNUM BETWEEN %d AND %d", $offset, (int) $this->limit + (int) $this->offset )); } if (isset($sqls[self::ORDER])) { $orderBy = $sqls[self::ORDER]; unset($sqls[self::ORDER]); } else { $orderBy = ''; } // add a column for row_number() using the order specification //dense_rank() if ($this->getIsSelectContainDistinct()) { $parameters[self::SELECT][0][] = ['DENSE_RANK() OVER (' . $orderBy . ')', 'ZEND_DB_ROWNUM']; } else { $parameters[self::SELECT][0][] = ['ROW_NUMBER() OVER (' . $orderBy . ')', 'ZEND_DB_ROWNUM']; } $sqls[self::SELECT] = $this->createSqlFromSpecificationAndParameters( $this->specifications[self::SELECT], $parameters[self::SELECT] ); } } zend-db-release-2.8.1/src/Sql/Platform/Mysql/000077500000000000000000000000001270372430400207045ustar00rootroot00000000000000zend-db-release-2.8.1/src/Sql/Platform/Mysql/Ddl/000077500000000000000000000000001270372430400214075ustar00rootroot00000000000000zend-db-release-2.8.1/src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php000066400000000000000000000174361270372430400260150ustar00rootroot00000000000000 0, 'zerofill' => 1, 'identity' => 2, 'serial' => 2, 'autoincrement' => 2, 'comment' => 3, 'columnformat' => 4, 'format' => 4, 'storage' => 5, ]; /** * @param AlterTable $subject * @return \Zend\Db\Sql\Platform\PlatformDecoratorInterface */ public function setSubject($subject) { $this->subject = $subject; return $this; } /** * @param string $sql * @return array */ protected function getSqlInsertOffsets($sql) { $sqlLength = strlen($sql); $insertStart = []; foreach (['NOT NULL', 'NULL', 'DEFAULT', 'UNIQUE', 'PRIMARY', 'REFERENCES'] as $needle) { $insertPos = strpos($sql, ' ' . $needle); if ($insertPos !== false) { switch ($needle) { case 'REFERENCES': $insertStart[2] = !isset($insertStart[2]) ? $insertPos : $insertStart[2]; // no break case 'PRIMARY': case 'UNIQUE': $insertStart[1] = !isset($insertStart[1]) ? $insertPos : $insertStart[1]; // no break default: $insertStart[0] = !isset($insertStart[0]) ? $insertPos : $insertStart[0]; } } } foreach (range(0, 3) as $i) { $insertStart[$i] = isset($insertStart[$i]) ? $insertStart[$i] : $sqlLength; } return $insertStart; } /** * @param PlatformInterface $adapterPlatform * @return array */ protected function processAddColumns(PlatformInterface $adapterPlatform = null) { $sqls = []; foreach ($this->addColumns as $i => $column) { $sql = $this->processExpression($column, $adapterPlatform); $insertStart = $this->getSqlInsertOffsets($sql); $columnOptions = $column->getOptions(); uksort($columnOptions, [$this, 'compareColumnOptions']); foreach ($columnOptions as $coName => $coValue) { $insert = ''; if (! $coValue) { continue; } switch ($this->normalizeColumnOption($coName)) { case 'unsigned': $insert = ' UNSIGNED'; $j = 0; break; case 'zerofill': $insert = ' ZEROFILL'; $j = 0; break; case 'identity': case 'serial': case 'autoincrement': $insert = ' AUTO_INCREMENT'; $j = 1; break; case 'comment': $insert = ' COMMENT ' . $adapterPlatform->quoteValue($coValue); $j = 2; break; case 'columnformat': case 'format': $insert = ' COLUMN_FORMAT ' . strtoupper($coValue); $j = 2; break; case 'storage': $insert = ' STORAGE ' . strtoupper($coValue); $j = 2; break; } if ($insert) { $j = isset($j) ? $j : 0; $sql = substr_replace($sql, $insert, $insertStart[$j], 0); $insertStartCount = count($insertStart); for (; $j < $insertStartCount; ++$j) { $insertStart[$j] += strlen($insert); } } } $sqls[$i] = $sql; } return [$sqls]; } /** * @param PlatformInterface $adapterPlatform * @return array */ protected function processChangeColumns(PlatformInterface $adapterPlatform = null) { $sqls = []; foreach ($this->changeColumns as $name => $column) { $sql = $this->processExpression($column, $adapterPlatform); $insertStart = $this->getSqlInsertOffsets($sql); $columnOptions = $column->getOptions(); uksort($columnOptions, [$this, 'compareColumnOptions']); foreach ($columnOptions as $coName => $coValue) { $insert = ''; if (! $coValue) { continue; } switch ($this->normalizeColumnOption($coName)) { case 'unsigned': $insert = ' UNSIGNED'; $j = 0; break; case 'zerofill': $insert = ' ZEROFILL'; $j = 0; break; case 'identity': case 'serial': case 'autoincrement': $insert = ' AUTO_INCREMENT'; $j = 1; break; case 'comment': $insert = ' COMMENT ' . $adapterPlatform->quoteValue($coValue); $j = 2; break; case 'columnformat': case 'format': $insert = ' COLUMN_FORMAT ' . strtoupper($coValue); $j = 2; break; case 'storage': $insert = ' STORAGE ' . strtoupper($coValue); $j = 2; break; } if ($insert) { $j = isset($j) ? $j : 0; $sql = substr_replace($sql, $insert, $insertStart[$j], 0); $insertStartCount = count($insertStart); for (; $j < $insertStartCount; ++$j) { $insertStart[$j] += strlen($insert); } } } $sqls[] = [ $adapterPlatform->quoteIdentifier($name), $sql ]; } return [$sqls]; } /** * @param string $name * * @return string */ private function normalizeColumnOption($name) { return strtolower(str_replace(['-', '_', ' '], '', $name)); } /** * * @param string $columnA * @param string $columnB * * @return int */ private function compareColumnOptions($columnA, $columnB) { $columnA = $this->normalizeColumnOption($columnA); $columnA = isset($this->columnOptionSortOrder[$columnA]) ? $this->columnOptionSortOrder[$columnA] : count($this->columnOptionSortOrder); $columnB = $this->normalizeColumnOption($columnB); $columnB = isset($this->columnOptionSortOrder[$columnB]) ? $this->columnOptionSortOrder[$columnB] : count($this->columnOptionSortOrder); return $columnA - $columnB; } } zend-db-release-2.8.1/src/Sql/Platform/Mysql/Ddl/CreateTableDecorator.php000066400000000000000000000125721270372430400261450ustar00rootroot00000000000000 0, 'zerofill' => 1, 'identity' => 2, 'serial' => 2, 'autoincrement' => 2, 'comment' => 3, 'columnformat' => 4, 'format' => 4, 'storage' => 5, ]; /** * @param CreateTable $subject * * @return self */ public function setSubject($subject) { $this->subject = $subject; return $this; } /** * @param string $sql * @return array */ protected function getSqlInsertOffsets($sql) { $sqlLength = strlen($sql); $insertStart = []; foreach (['NOT NULL', 'NULL', 'DEFAULT', 'UNIQUE', 'PRIMARY', 'REFERENCES'] as $needle) { $insertPos = strpos($sql, ' ' . $needle); if ($insertPos !== false) { switch ($needle) { case 'REFERENCES': $insertStart[2] = !isset($insertStart[2]) ? $insertPos : $insertStart[2]; // no break case 'PRIMARY': case 'UNIQUE': $insertStart[1] = !isset($insertStart[1]) ? $insertPos : $insertStart[1]; // no break default: $insertStart[0] = !isset($insertStart[0]) ? $insertPos : $insertStart[0]; } } } foreach (range(0, 3) as $i) { $insertStart[$i] = isset($insertStart[$i]) ? $insertStart[$i] : $sqlLength; } return $insertStart; } /** * {@inheritDoc} */ protected function processColumns(PlatformInterface $platform = null) { if (! $this->columns) { return; } $sqls = []; foreach ($this->columns as $i => $column) { $sql = $this->processExpression($column, $platform); $insertStart = $this->getSqlInsertOffsets($sql); $columnOptions = $column->getOptions(); uksort($columnOptions, [$this, 'compareColumnOptions']); foreach ($columnOptions as $coName => $coValue) { $insert = ''; if (! $coValue) { continue; } switch ($this->normalizeColumnOption($coName)) { case 'unsigned': $insert = ' UNSIGNED'; $j = 0; break; case 'zerofill': $insert = ' ZEROFILL'; $j = 0; break; case 'identity': case 'serial': case 'autoincrement': $insert = ' AUTO_INCREMENT'; $j = 1; break; case 'comment': $insert = ' COMMENT ' . $platform->quoteValue($coValue); $j = 2; break; case 'columnformat': case 'format': $insert = ' COLUMN_FORMAT ' . strtoupper($coValue); $j = 2; break; case 'storage': $insert = ' STORAGE ' . strtoupper($coValue); $j = 2; break; } if ($insert) { $j = isset($j) ? $j : 0; $sql = substr_replace($sql, $insert, $insertStart[$j], 0); $insertStartCount = count($insertStart); for (; $j < $insertStartCount; ++$j) { $insertStart[$j] += strlen($insert); } } } $sqls[$i] = $sql; } return [$sqls]; } /** * @param string $name * * @return string */ private function normalizeColumnOption($name) { return strtolower(str_replace(['-', '_', ' '], '', $name)); } /** * * @param string $columnA * @param string $columnB * * @return int */ private function compareColumnOptions($columnA, $columnB) { $columnA = $this->normalizeColumnOption($columnA); $columnA = isset($this->columnOptionSortOrder[$columnA]) ? $this->columnOptionSortOrder[$columnA] : count($this->columnOptionSortOrder); $columnB = $this->normalizeColumnOption($columnB); $columnB = isset($this->columnOptionSortOrder[$columnB]) ? $this->columnOptionSortOrder[$columnB] : count($this->columnOptionSortOrder); return $columnA - $columnB; } } zend-db-release-2.8.1/src/Sql/Platform/Mysql/Mysql.php000066400000000000000000000013541270372430400225250ustar00rootroot00000000000000setTypeDecorator('Zend\Db\Sql\Select', new SelectDecorator()); $this->setTypeDecorator('Zend\Db\Sql\Ddl\CreateTable', new Ddl\CreateTableDecorator()); $this->setTypeDecorator('Zend\Db\Sql\Ddl\AlterTable', new Ddl\AlterTableDecorator()); } } zend-db-release-2.8.1/src/Sql/Platform/Mysql/SelectDecorator.php000066400000000000000000000040751270372430400245050ustar00rootroot00000000000000subject = $select; } protected function localizeVariables() { parent::localizeVariables(); if ($this->limit === null && $this->offset !== null) { $this->specifications[self::LIMIT] = 'LIMIT 18446744073709551615'; } } protected function processLimit(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { if ($this->limit === null && $this->offset !== null) { return ['']; } if ($this->limit === null) { return; } if ($parameterContainer) { $parameterContainer->offsetSet('limit', $this->limit, ParameterContainer::TYPE_INTEGER); return [$driver->formatParameterName('limit')]; } return [$this->limit]; } protected function processOffset(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { if ($this->offset === null) { return; } if ($parameterContainer) { $parameterContainer->offsetSet('offset', $this->offset, ParameterContainer::TYPE_INTEGER); return [$driver->formatParameterName('offset')]; } return [$this->offset]; } } zend-db-release-2.8.1/src/Sql/Platform/Oracle/000077500000000000000000000000001270372430400210045ustar00rootroot00000000000000zend-db-release-2.8.1/src/Sql/Platform/Oracle/Oracle.php000066400000000000000000000011551270372430400227240ustar00rootroot00000000000000setTypeDecorator('Zend\Db\Sql\Select', ($selectDecorator) ?: new SelectDecorator()); } } zend-db-release-2.8.1/src/Sql/Platform/Oracle/SelectDecorator.php000066400000000000000000000117111270372430400246000ustar00rootroot00000000000000subject = $select; } /** * @see \Zend\Db\Sql\Select::renderTable */ protected function renderTable($table, $alias = null) { return $table . ($alias ? ' ' . $alias : ''); } protected function localizeVariables() { parent::localizeVariables(); unset($this->specifications[self::LIMIT]); unset($this->specifications[self::OFFSET]); $this->specifications['LIMITOFFSET'] = null; } /** * @param PlatformInterface $platform * @param DriverInterface $driver * @param ParameterContainer $parameterContainer * @param array $sqls * @param array $parameters * @return null */ protected function processLimitOffset( PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null, &$sqls = [], &$parameters = [] ) { if ($this->limit === null && $this->offset === null) { return; } $selectParameters = $parameters[self::SELECT]; $starSuffix = $platform->getIdentifierSeparator() . self::SQL_STAR; foreach ($selectParameters[0] as $i => $columnParameters) { if ($columnParameters[0] == self::SQL_STAR || (isset($columnParameters[1]) && $columnParameters[1] == self::SQL_STAR) || strpos($columnParameters[0], $starSuffix) ) { $selectParameters[0] = [[self::SQL_STAR]]; break; } if (isset($columnParameters[1])) { array_shift($columnParameters); $selectParameters[0][$i] = $columnParameters; } } if ($this->offset === null) { $this->offset = 0; } // first, produce column list without compound names (using the AS portion only) array_unshift($sqls, $this->createSqlFromSpecificationAndParameters([ 'SELECT %1$s FROM (SELECT b.%1$s, rownum b_rownum FROM (' => current($this->specifications[self::SELECT]), ], $selectParameters)); if ($parameterContainer) { $number = $this->processInfo['subselectCount'] ? $this->processInfo['subselectCount'] : ''; if ($this->limit === null) { array_push( $sqls, ') b ) WHERE b_rownum > (:offset' . $number . ')' ); $parameterContainer->offsetSet( 'offset' . $number, $this->offset, $parameterContainer::TYPE_INTEGER ); } else { // create bottom part of query, with offset and limit using row_number array_push( $sqls, ') b WHERE rownum <= (:offset' . $number . '+:limit' . $number . ')) WHERE b_rownum >= (:offset' . $number . ' + 1)' ); $parameterContainer->offsetSet( 'offset' . $number, $this->offset, $parameterContainer::TYPE_INTEGER ); $parameterContainer->offsetSet( 'limit' . $number, $this->limit, $parameterContainer::TYPE_INTEGER ); } $this->processInfo['subselectCount']++; } else { if ($this->limit === null) { array_push($sqls, ') b ) WHERE b_rownum > (' . (int) $this->offset . ')'); } else { array_push( $sqls, ') b WHERE rownum <= (' . (int) $this->offset . '+' . (int) $this->limit . ')) WHERE b_rownum >= (' . (int) $this->offset . ' + 1)' ); } } $sqls[self::SELECT] = $this->createSqlFromSpecificationAndParameters( $this->specifications[self::SELECT], $parameters[self::SELECT] ); } } zend-db-release-2.8.1/src/Sql/Platform/Platform.php000066400000000000000000000125371270372430400221040ustar00rootroot00000000000000defaultPlatform = $adapter->getPlatform(); $mySqlPlatform = new Mysql\Mysql(); $sqlServerPlatform = new SqlServer\SqlServer(); $oraclePlatform = new Oracle\Oracle(); $ibmDb2Platform = new IbmDb2\IbmDb2(); $this->decorators['mysql'] = $mySqlPlatform->getDecorators(); $this->decorators['sqlserver'] = $sqlServerPlatform->getDecorators(); $this->decorators['oracle'] = $oraclePlatform->getDecorators(); $this->decorators['ibmdb2'] = $ibmDb2Platform->getDecorators(); } /** * @param string $type * @param PlatformDecoratorInterface $decorator * @param AdapterInterface|PlatformInterface $adapterOrPlatform */ public function setTypeDecorator($type, PlatformDecoratorInterface $decorator, $adapterOrPlatform = null) { $platformName = $this->resolvePlatformName($adapterOrPlatform); $this->decorators[$platformName][$type] = $decorator; } /** * @param PreparableSqlInterface|SqlInterface $subject * @param AdapterInterface|PlatformInterface|null $adapterOrPlatform * @return PlatformDecoratorInterface|PreparableSqlInterface|SqlInterface */ public function getTypeDecorator($subject, $adapterOrPlatform = null) { $platformName = $this->resolvePlatformName($adapterOrPlatform); if (isset($this->decorators[$platformName])) { foreach ($this->decorators[$platformName] as $type => $decorator) { if ($subject instanceof $type && is_a($decorator, $type, true)) { $decorator->setSubject($subject); return $decorator; } } } return $subject; } /** * @return array|PlatformDecoratorInterface[] */ public function getDecorators() { $platformName = $this->resolvePlatformName($this->getDefaultPlatform()); return $this->decorators[$platformName]; } /** * {@inheritDoc} * * @throws Exception\RuntimeException */ public function prepareStatement(AdapterInterface $adapter, StatementContainerInterface $statementContainer) { if (! $this->subject instanceof PreparableSqlInterface) { throw new Exception\RuntimeException('The subject does not appear to implement Zend\Db\Sql\PreparableSqlInterface, thus calling prepareStatement() has no effect'); } $this->getTypeDecorator($this->subject, $adapter)->prepareStatement($adapter, $statementContainer); return $statementContainer; } /** * {@inheritDoc} * * @throws Exception\RuntimeException */ public function getSqlString(PlatformInterface $adapterPlatform = null) { if (! $this->subject instanceof SqlInterface) { throw new Exception\RuntimeException('The subject does not appear to implement Zend\Db\Sql\SqlInterface, thus calling prepareStatement() has no effect'); } $adapterPlatform = $this->resolvePlatform($adapterPlatform); return $this->getTypeDecorator($this->subject, $adapterPlatform)->getSqlString($adapterPlatform); } protected function resolvePlatformName($adapterOrPlatform) { $platformName = $this->resolvePlatform($adapterOrPlatform)->getName(); return str_replace([' ', '_'], '', strtolower($platformName)); } /** * @param null|PlatformInterface|AdapterInterface $adapterOrPlatform * * @return PlatformInterface * * @throws Exception\InvalidArgumentException */ protected function resolvePlatform($adapterOrPlatform) { if (! $adapterOrPlatform) { return $this->getDefaultPlatform(); } if ($adapterOrPlatform instanceof AdapterInterface) { return $adapterOrPlatform->getPlatform(); } if ($adapterOrPlatform instanceof PlatformInterface) { return $adapterOrPlatform; } throw new Exception\InvalidArgumentException(sprintf( '$adapterOrPlatform should be null, %s, or %s', 'Zend\Db\Adapter\AdapterInterface', 'Zend\Db\Adapter\Platform\PlatformInterface' )); } /** * @return PlatformInterface * * @throws Exception\RuntimeException */ protected function getDefaultPlatform() { if (! $this->defaultPlatform) { throw new Exception\RuntimeException('$this->defaultPlatform was not set'); } return $this->defaultPlatform; } } zend-db-release-2.8.1/src/Sql/Platform/PlatformDecoratorInterface.php000066400000000000000000000007541270372430400255660ustar00rootroot00000000000000subject = $subject; return $this; } /** * @param PlatformInterface $adapterPlatform * @return array */ protected function processTable(PlatformInterface $adapterPlatform = null) { $table = ($this->isTemporary ? '#' : '') . ltrim($this->table, '#'); return [ '', $adapterPlatform->quoteIdentifier($table), ]; } } zend-db-release-2.8.1/src/Sql/Platform/SqlServer/SelectDecorator.php000066400000000000000000000102121270372430400253140ustar00rootroot00000000000000subject = $select; } protected function localizeVariables() { parent::localizeVariables(); // set specifications unset($this->specifications[self::LIMIT]); unset($this->specifications[self::OFFSET]); $this->specifications['LIMITOFFSET'] = null; } /** * @param PlatformInterface $platform * @param DriverInterface $driver * @param ParameterContainer $parameterContainer * @param $sqls * @param $parameters * @return null */ protected function processLimitOffset(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null, &$sqls, &$parameters) { if ($this->limit === null && $this->offset === null) { return; } $selectParameters = $parameters[self::SELECT]; $starSuffix = $platform->getIdentifierSeparator() . self::SQL_STAR; foreach ($selectParameters[0] as $i => $columnParameters) { if ($columnParameters[0] == self::SQL_STAR || (isset($columnParameters[1]) && $columnParameters[1] == self::SQL_STAR) || strpos($columnParameters[0], $starSuffix)) { $selectParameters[0] = [[self::SQL_STAR]]; break; } if (isset($columnParameters[1])) { array_shift($columnParameters); $selectParameters[0][$i] = $columnParameters; } } // first, produce column list without compound names (using the AS portion only) array_unshift($sqls, $this->createSqlFromSpecificationAndParameters( ['SELECT %1$s FROM (' => current($this->specifications[self::SELECT])], $selectParameters )); if ($parameterContainer) { // create bottom part of query, with offset and limit using row_number $limitParamName = $driver->formatParameterName('limit'); $offsetParamName = $driver->formatParameterName('offset'); $offsetForSumParamName = $driver->formatParameterName('offsetForSum'); array_push($sqls, ') AS [ZEND_SQL_SERVER_LIMIT_OFFSET_EMULATION] WHERE [ZEND_SQL_SERVER_LIMIT_OFFSET_EMULATION].[__ZEND_ROW_NUMBER] BETWEEN ' . $offsetParamName . '+1 AND ' . $limitParamName . '+' . $offsetForSumParamName); $parameterContainer->offsetSet('offset', $this->offset); $parameterContainer->offsetSet('limit', $this->limit); $parameterContainer->offsetSetReference('offsetForSum', 'offset'); } else { array_push($sqls, ') AS [ZEND_SQL_SERVER_LIMIT_OFFSET_EMULATION] WHERE [ZEND_SQL_SERVER_LIMIT_OFFSET_EMULATION].[__ZEND_ROW_NUMBER] BETWEEN ' . (int) $this->offset . '+1 AND ' . (int) $this->limit . '+' . (int) $this->offset ); } if (isset($sqls[self::ORDER])) { $orderBy = $sqls[self::ORDER]; unset($sqls[self::ORDER]); } else { $orderBy = 'ORDER BY (SELECT 1)'; } // add a column for row_number() using the order specification $parameters[self::SELECT][0][] = ['ROW_NUMBER() OVER (' . $orderBy . ')', '[__ZEND_ROW_NUMBER]']; $sqls[self::SELECT] = $this->createSqlFromSpecificationAndParameters( $this->specifications[self::SELECT], $parameters[self::SELECT] ); } } zend-db-release-2.8.1/src/Sql/Platform/SqlServer/SqlServer.php000066400000000000000000000013231270372430400241630ustar00rootroot00000000000000setTypeDecorator('Zend\Db\Sql\Select', ($selectDecorator) ?: new SelectDecorator()); $this->setTypeDecorator('Zend\Db\Sql\Ddl\CreateTable', new Ddl\CreateTableDecorator()); } } zend-db-release-2.8.1/src/Sql/Predicate/000077500000000000000000000000001270372430400177135ustar00rootroot00000000000000zend-db-release-2.8.1/src/Sql/Predicate/Between.php000066400000000000000000000066141270372430400220240ustar00rootroot00000000000000setIdentifier($identifier); } if ($minValue !== null) { $this->setMinValue($minValue); } if ($maxValue !== null) { $this->setMaxValue($maxValue); } } /** * Set identifier for comparison * * @param string $identifier * @return Between */ public function setIdentifier($identifier) { $this->identifier = $identifier; return $this; } /** * Get identifier of comparison * * @return null|string */ public function getIdentifier() { return $this->identifier; } /** * Set minimum boundary for comparison * * @param int|float|string $minValue * @return Between */ public function setMinValue($minValue) { $this->minValue = $minValue; return $this; } /** * Get minimum boundary for comparison * * @return null|int|float|string */ public function getMinValue() { return $this->minValue; } /** * Set maximum boundary for comparison * * @param int|float|string $maxValue * @return Between */ public function setMaxValue($maxValue) { $this->maxValue = $maxValue; return $this; } /** * Get maximum boundary for comparison * * @return null|int|float|string */ public function getMaxValue() { return $this->maxValue; } /** * Set specification string to use in forming SQL predicate * * @param string $specification * @return Between */ public function setSpecification($specification) { $this->specification = $specification; return $this; } /** * Get specification string to use in forming SQL predicate * * @return string */ public function getSpecification() { return $this->specification; } /** * Return "where" parts * * @return array */ public function getExpressionData() { list($values[], $types[]) = $this->normalizeArgument($this->identifier, self::TYPE_IDENTIFIER); list($values[], $types[]) = $this->normalizeArgument($this->minValue, self::TYPE_VALUE); list($values[], $types[]) = $this->normalizeArgument($this->maxValue, self::TYPE_VALUE); return [ [ $this->getSpecification(), $values, $types, ], ]; } } zend-db-release-2.8.1/src/Sql/Predicate/Expression.php000066400000000000000000000016161270372430400225670ustar00rootroot00000000000000setExpression($expression); } $this->setParameters(is_array($valueParameter) ? $valueParameter : array_slice(func_get_args(), 1)); } } zend-db-release-2.8.1/src/Sql/Predicate/In.php000066400000000000000000000070651270372430400210020ustar00rootroot00000000000000setIdentifier($identifier); } if ($valueSet) { $this->setValueSet($valueSet); } } /** * Set identifier for comparison * * @param string|array $identifier * @return In */ public function setIdentifier($identifier) { $this->identifier = $identifier; return $this; } /** * Get identifier of comparison * * @return null|string|array */ public function getIdentifier() { return $this->identifier; } /** * Set set of values for IN comparison * * @param array|Select $valueSet * @throws Exception\InvalidArgumentException * @return In */ public function setValueSet($valueSet) { if (!is_array($valueSet) && !$valueSet instanceof Select) { throw new Exception\InvalidArgumentException( '$valueSet must be either an array or a Zend\Db\Sql\Select object, ' . gettype($valueSet) . ' given' ); } $this->valueSet = $valueSet; return $this; } /** * Gets set of values in IN comparision * * @return array|Select */ public function getValueSet() { return $this->valueSet; } /** * Return array of parts for where statement * * @return array */ public function getExpressionData() { $identifier = $this->getIdentifier(); $values = $this->getValueSet(); $replacements = []; if (is_array($identifier)) { $identifierSpecFragment = '(' . implode(', ', array_fill(0, count($identifier), '%s')) . ')'; $types = array_fill(0, count($identifier), self::TYPE_IDENTIFIER); $replacements = $identifier; } else { $identifierSpecFragment = '%s'; $replacements[] = $identifier; $types = [self::TYPE_IDENTIFIER]; } if ($values instanceof Select) { $specification = vsprintf( $this->specification, [$identifierSpecFragment, '%s'] ); $replacements[] = $values; $types[] = self::TYPE_VALUE; } else { foreach ($values as $argument) { list($replacements[], $types[]) = $this->normalizeArgument($argument, self::TYPE_VALUE); } $specification = vsprintf( $this->specification, [$identifierSpecFragment, '(' . implode(', ', array_fill(0, count($values), '%s')) . ')'] ); } return [[ $specification, $replacements, $types, ]]; } } zend-db-release-2.8.1/src/Sql/Predicate/IsNotNull.php000066400000000000000000000006561270372430400223220ustar00rootroot00000000000000setIdentifier($identifier); } } /** * Set identifier for comparison * * @param string $identifier * @return IsNull */ public function setIdentifier($identifier) { $this->identifier = $identifier; return $this; } /** * Get identifier of comparison * * @return null|string */ public function getIdentifier() { return $this->identifier; } /** * Set specification string to use in forming SQL predicate * * @param string $specification * @return IsNull */ public function setSpecification($specification) { $this->specification = $specification; return $this; } /** * Get specification string to use in forming SQL predicate * * @return string */ public function getSpecification() { return $this->specification; } /** * Get parts for where statement * * @return array */ public function getExpressionData() { $identifier = $this->normalizeArgument($this->identifier, self::TYPE_IDENTIFIER); return [[ $this->getSpecification(), [$identifier[0]], [$identifier[1]], ]]; } } zend-db-release-2.8.1/src/Sql/Predicate/Like.php000066400000000000000000000044231270372430400213130ustar00rootroot00000000000000setIdentifier($identifier); } if ($like) { $this->setLike($like); } } /** * @param string $identifier * @return self */ public function setIdentifier($identifier) { $this->identifier = $identifier; return $this; } /** * @return string */ public function getIdentifier() { return $this->identifier; } /** * @param string $like * @return self */ public function setLike($like) { $this->like = $like; return $this; } /** * @return string */ public function getLike() { return $this->like; } /** * @param string $specification * @return self */ public function setSpecification($specification) { $this->specification = $specification; return $this; } /** * @return string */ public function getSpecification() { return $this->specification; } /** * @return array */ public function getExpressionData() { list($values[], $types[]) = $this->normalizeArgument($this->identifier, self::TYPE_IDENTIFIER); list($values[], $types[]) = $this->normalizeArgument($this->like, self::TYPE_VALUE); return [ [ $this->specification, $values, $types, ] ]; } } zend-db-release-2.8.1/src/Sql/Predicate/Literal.php000066400000000000000000000007051270372430400220220ustar00rootroot00000000000000'; const OP_GT = '>'; const OPERATOR_GREATER_THAN_OR_EQUAL_TO = '>='; const OP_GTE = '>='; /** * {@inheritDoc} */ protected $allowedTypes = [ self::TYPE_IDENTIFIER, self::TYPE_VALUE, ]; /** * @var int|float|bool|string */ protected $left; /** * @var int|float|bool|string */ protected $right; /** * @var string */ protected $leftType = self::TYPE_IDENTIFIER; /** * @var string */ protected $rightType = self::TYPE_VALUE; /** * @var string */ protected $operator = self::OPERATOR_EQUAL_TO; /** * Constructor * * @param int|float|bool|string $left * @param string $operator * @param int|float|bool|string $right * @param string $leftType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_IDENTIFIER {@see allowedTypes} * @param string $rightType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_VALUE {@see allowedTypes} */ public function __construct( $left = null, $operator = self::OPERATOR_EQUAL_TO, $right = null, $leftType = self::TYPE_IDENTIFIER, $rightType = self::TYPE_VALUE ) { if ($left !== null) { $this->setLeft($left); } if ($operator !== self::OPERATOR_EQUAL_TO) { $this->setOperator($operator); } if ($right !== null) { $this->setRight($right); } if ($leftType !== self::TYPE_IDENTIFIER) { $this->setLeftType($leftType); } if ($rightType !== self::TYPE_VALUE) { $this->setRightType($rightType); } } /** * Set left side of operator * * @param int|float|bool|string $left * * @return Operator */ public function setLeft($left) { $this->left = $left; if (is_array($left)) { $left = $this->normalizeArgument($left, $this->leftType); $this->leftType = $left[1]; } return $this; } /** * Get left side of operator * * @return int|float|bool|string */ public function getLeft() { return $this->left; } /** * Set parameter type for left side of operator * * @param string $type TYPE_IDENTIFIER or TYPE_VALUE {@see allowedTypes} * * @return Operator * * @throws Exception\InvalidArgumentException */ public function setLeftType($type) { if (!in_array($type, $this->allowedTypes)) { throw new Exception\InvalidArgumentException(sprintf( 'Invalid type "%s" provided; must be of type "%s" or "%s"', $type, __CLASS__ . '::TYPE_IDENTIFIER', __CLASS__ . '::TYPE_VALUE' )); } $this->leftType = $type; return $this; } /** * Get parameter type on left side of operator * * @return string */ public function getLeftType() { return $this->leftType; } /** * Set operator string * * @param string $operator * @return Operator */ public function setOperator($operator) { $this->operator = $operator; return $this; } /** * Get operator string * * @return string */ public function getOperator() { return $this->operator; } /** * Set right side of operator * * @param int|float|bool|string $right * * @return Operator */ public function setRight($right) { $this->right = $right; if (is_array($right)) { $right = $this->normalizeArgument($right, $this->rightType); $this->rightType = $right[1]; } return $this; } /** * Get right side of operator * * @return int|float|bool|string */ public function getRight() { return $this->right; } /** * Set parameter type for right side of operator * * @param string $type TYPE_IDENTIFIER or TYPE_VALUE {@see allowedTypes} * @throws Exception\InvalidArgumentException * @return Operator */ public function setRightType($type) { if (!in_array($type, $this->allowedTypes)) { throw new Exception\InvalidArgumentException(sprintf( 'Invalid type "%s" provided; must be of type "%s" or "%s"', $type, __CLASS__ . '::TYPE_IDENTIFIER', __CLASS__ . '::TYPE_VALUE' )); } $this->rightType = $type; return $this; } /** * Get parameter type on right side of operator * * @return string */ public function getRightType() { return $this->rightType; } /** * Get predicate parts for where statement * * @return array */ public function getExpressionData() { list($values[], $types[]) = $this->normalizeArgument($this->left, $this->leftType); list($values[], $types[]) = $this->normalizeArgument($this->right, $this->rightType); return [[ '%s ' . $this->operator . ' %s', $values, $types ]]; } } zend-db-release-2.8.1/src/Sql/Predicate/Predicate.php000066400000000000000000000321521270372430400223270ustar00rootroot00000000000000setUnnest($this); $this->addPredicate($predicateSet, ($this->nextPredicateCombineOperator) ?: $this->defaultCombination); $this->nextPredicateCombineOperator = null; return $predicateSet; } /** * Indicate what predicate will be unnested * * @param Predicate $predicate * @return void */ public function setUnnest(Predicate $predicate) { $this->unnest = $predicate; } /** * Indicate end of nested predicate * * @return Predicate * @throws RuntimeException */ public function unnest() { if ($this->unnest === null) { throw new RuntimeException('Not nested'); } $unnest = $this->unnest; $this->unnest = null; return $unnest; } /** * Create "Equal To" predicate * * Utilizes Operator predicate * * @param int|float|bool|string $left * @param int|float|bool|string $right * @param string $leftType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_IDENTIFIER {@see allowedTypes} * @param string $rightType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_VALUE {@see allowedTypes} * @return Predicate */ public function equalTo($left, $right, $leftType = self::TYPE_IDENTIFIER, $rightType = self::TYPE_VALUE) { $this->addPredicate( new Operator($left, Operator::OPERATOR_EQUAL_TO, $right, $leftType, $rightType), ($this->nextPredicateCombineOperator) ?: $this->defaultCombination ); $this->nextPredicateCombineOperator = null; return $this; } /** * Create "Not Equal To" predicate * * Utilizes Operator predicate * * @param int|float|bool|string $left * @param int|float|bool|string $right * @param string $leftType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_IDENTIFIER {@see allowedTypes} * @param string $rightType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_VALUE {@see allowedTypes} * @return Predicate */ public function notEqualTo($left, $right, $leftType = self::TYPE_IDENTIFIER, $rightType = self::TYPE_VALUE) { $this->addPredicate( new Operator($left, Operator::OPERATOR_NOT_EQUAL_TO, $right, $leftType, $rightType), ($this->nextPredicateCombineOperator) ?: $this->defaultCombination ); $this->nextPredicateCombineOperator = null; return $this; } /** * Create "Less Than" predicate * * Utilizes Operator predicate * * @param int|float|bool|string $left * @param int|float|bool|string $right * @param string $leftType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_IDENTIFIER {@see allowedTypes} * @param string $rightType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_VALUE {@see allowedTypes} * @return Predicate */ public function lessThan($left, $right, $leftType = self::TYPE_IDENTIFIER, $rightType = self::TYPE_VALUE) { $this->addPredicate( new Operator($left, Operator::OPERATOR_LESS_THAN, $right, $leftType, $rightType), ($this->nextPredicateCombineOperator) ?: $this->defaultCombination ); $this->nextPredicateCombineOperator = null; return $this; } /** * Create "Greater Than" predicate * * Utilizes Operator predicate * * @param int|float|bool|string $left * @param int|float|bool|string $right * @param string $leftType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_IDENTIFIER {@see allowedTypes} * @param string $rightType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_VALUE {@see allowedTypes} * @return Predicate */ public function greaterThan($left, $right, $leftType = self::TYPE_IDENTIFIER, $rightType = self::TYPE_VALUE) { $this->addPredicate( new Operator($left, Operator::OPERATOR_GREATER_THAN, $right, $leftType, $rightType), ($this->nextPredicateCombineOperator) ?: $this->defaultCombination ); $this->nextPredicateCombineOperator = null; return $this; } /** * Create "Less Than Or Equal To" predicate * * Utilizes Operator predicate * * @param int|float|bool|string $left * @param int|float|bool|string $right * @param string $leftType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_IDENTIFIER {@see allowedTypes} * @param string $rightType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_VALUE {@see allowedTypes} * @return Predicate */ public function lessThanOrEqualTo($left, $right, $leftType = self::TYPE_IDENTIFIER, $rightType = self::TYPE_VALUE) { $this->addPredicate( new Operator($left, Operator::OPERATOR_LESS_THAN_OR_EQUAL_TO, $right, $leftType, $rightType), ($this->nextPredicateCombineOperator) ?: $this->defaultCombination ); $this->nextPredicateCombineOperator = null; return $this; } /** * Create "Greater Than Or Equal To" predicate * * Utilizes Operator predicate * * @param int|float|bool|string $left * @param int|float|bool|string $right * @param string $leftType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_IDENTIFIER {@see allowedTypes} * @param string $rightType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_VALUE {@see allowedTypes} * @return Predicate */ public function greaterThanOrEqualTo($left, $right, $leftType = self::TYPE_IDENTIFIER, $rightType = self::TYPE_VALUE) { $this->addPredicate( new Operator($left, Operator::OPERATOR_GREATER_THAN_OR_EQUAL_TO, $right, $leftType, $rightType), ($this->nextPredicateCombineOperator) ?: $this->defaultCombination ); $this->nextPredicateCombineOperator = null; return $this; } /** * Create "Like" predicate * * Utilizes Like predicate * * @param string $identifier * @param string $like * @return Predicate */ public function like($identifier, $like) { $this->addPredicate( new Like($identifier, $like), ($this->nextPredicateCombineOperator) ?: $this->defaultCombination ); $this->nextPredicateCombineOperator = null; return $this; } /** * Create "notLike" predicate * * Utilizes In predicate * * @param string $identifier * @param string $notLike * @return Predicate */ public function notLike($identifier, $notLike) { $this->addPredicate( new NotLike($identifier, $notLike), ($this->nextPredicateCombineOperator) ? : $this->defaultCombination ); $this->nextPredicateCombineOperator = null; return $this; } /** * Create an expression, with parameter placeholders * * @param $expression * @param $parameters * @return $this */ public function expression($expression, $parameters = null) { $this->addPredicate( new Expression($expression, $parameters), ($this->nextPredicateCombineOperator) ?: $this->defaultCombination ); $this->nextPredicateCombineOperator = null; return $this; } /** * Create "Literal" predicate * * Literal predicate, for parameters, use expression() * * @param string $literal * @return Predicate */ public function literal($literal) { // process deprecated parameters from previous literal($literal, $parameters = null) signature if (func_num_args() >= 2) { $parameters = func_get_arg(1); $predicate = new Expression($literal, $parameters); } // normal workflow for "Literals" here if (!isset($predicate)) { $predicate = new Literal($literal); } $this->addPredicate( $predicate, ($this->nextPredicateCombineOperator) ?: $this->defaultCombination ); $this->nextPredicateCombineOperator = null; return $this; } /** * Create "IS NULL" predicate * * Utilizes IsNull predicate * * @param string $identifier * @return Predicate */ public function isNull($identifier) { $this->addPredicate( new IsNull($identifier), ($this->nextPredicateCombineOperator) ?: $this->defaultCombination ); $this->nextPredicateCombineOperator = null; return $this; } /** * Create "IS NOT NULL" predicate * * Utilizes IsNotNull predicate * * @param string $identifier * @return Predicate */ public function isNotNull($identifier) { $this->addPredicate( new IsNotNull($identifier), ($this->nextPredicateCombineOperator) ?: $this->defaultCombination ); $this->nextPredicateCombineOperator = null; return $this; } /** * Create "IN" predicate * * Utilizes In predicate * * @param string $identifier * @param array|\Zend\Db\Sql\Select $valueSet * @return Predicate */ public function in($identifier, $valueSet = null) { $this->addPredicate( new In($identifier, $valueSet), ($this->nextPredicateCombineOperator) ?: $this->defaultCombination ); $this->nextPredicateCombineOperator = null; return $this; } /** * Create "NOT IN" predicate * * Utilizes NotIn predicate * * @param string $identifier * @param array|\Zend\Db\Sql\Select $valueSet * @return Predicate */ public function notIn($identifier, $valueSet = null) { $this->addPredicate( new NotIn($identifier, $valueSet), ($this->nextPredicateCombineOperator) ?: $this->defaultCombination ); $this->nextPredicateCombineOperator = null; return $this; } /** * Create "between" predicate * * Utilizes Between predicate * * @param string $identifier * @param int|float|string $minValue * @param int|float|string $maxValue * @return Predicate */ public function between($identifier, $minValue, $maxValue) { $this->addPredicate( new Between($identifier, $minValue, $maxValue), ($this->nextPredicateCombineOperator) ?: $this->defaultCombination ); $this->nextPredicateCombineOperator = null; return $this; } /** * Create "NOT BETWEEN" predicate * * Utilizes NotBetween predicate * * @param string $identifier * @param int|float|string $minValue * @param int|float|string $maxValue * @return Predicate */ public function notBetween($identifier, $minValue, $maxValue) { $this->addPredicate( new NotBetween($identifier, $minValue, $maxValue), ($this->nextPredicateCombineOperator) ?: $this->defaultCombination ); $this->nextPredicateCombineOperator = null; return $this; } /** * Use given predicate directly * * Contrary to {@link addPredicate()} this method respects formerly set * AND / OR combination operator, thus allowing generic predicates to be * used fluently within where chains as any other concrete predicate. * * @param PredicateInterface $predicate * @return Predicate */ public function predicate(PredicateInterface $predicate) { $this->addPredicate( $predicate, $this->nextPredicateCombineOperator ?: $this->defaultCombination ); $this->nextPredicateCombineOperator = null; return $this; } /** * Overloading * * Overloads "or", "and", "nest", and "unnest" * * @param string $name * @return Predicate */ public function __get($name) { switch (strtolower($name)) { case 'or': $this->nextPredicateCombineOperator = self::OP_OR; break; case 'and': $this->nextPredicateCombineOperator = self::OP_AND; break; case 'nest': return $this->nest(); case 'unnest': return $this->unnest(); } return $this; } } zend-db-release-2.8.1/src/Sql/Predicate/PredicateInterface.php000066400000000000000000000006731270372430400241530ustar00rootroot00000000000000defaultCombination = $defaultCombination; if ($predicates) { foreach ($predicates as $predicate) { $this->addPredicate($predicate); } } } /** * Add predicate to set * * @param PredicateInterface $predicate * @param string $combination * @return PredicateSet */ public function addPredicate(PredicateInterface $predicate, $combination = null) { if ($combination === null || !in_array($combination, [self::OP_AND, self::OP_OR])) { $combination = $this->defaultCombination; } if ($combination == self::OP_OR) { $this->orPredicate($predicate); return $this; } $this->andPredicate($predicate); return $this; } /** * Add predicates to set * * @param PredicateInterface|\Closure|string|array $predicates * @param string $combination * @return PredicateSet */ public function addPredicates($predicates, $combination = self::OP_AND) { if ($predicates === null) { throw new Exception\InvalidArgumentException('Predicate cannot be null'); } if ($predicates instanceof PredicateInterface) { $this->addPredicate($predicates, $combination); return $this; } if ($predicates instanceof \Closure) { $predicates($this); return $this; } if (is_string($predicates)) { // String $predicate should be passed as an expression $predicates = (strpos($predicates, Expression::PLACEHOLDER) !== false) ? new Expression($predicates) : new Literal($predicates); $this->addPredicate($predicates, $combination); return $this; } if (is_array($predicates)) { foreach ($predicates as $pkey => $pvalue) { // loop through predicates if (is_string($pkey)) { if (strpos($pkey, '?') !== false) { // First, process strings that the abstraction replacement character ? // as an Expression predicate $predicates = new Expression($pkey, $pvalue); } elseif ($pvalue === null) { // Otherwise, if still a string, do something intelligent with the PHP type provided // map PHP null to SQL IS NULL expression $predicates = new IsNull($pkey); } elseif (is_array($pvalue)) { // if the value is an array, assume IN() is desired $predicates = new In($pkey, $pvalue); } elseif ($pvalue instanceof PredicateInterface) { throw new Exception\InvalidArgumentException( 'Using Predicate must not use string keys' ); } else { // otherwise assume that array('foo' => 'bar') means "foo" = 'bar' $predicates = new Operator($pkey, Operator::OP_EQ, $pvalue); } } elseif ($pvalue instanceof PredicateInterface) { // Predicate type is ok $predicates = $pvalue; } else { // must be an array of expressions (with int-indexed array) $predicates = (strpos($pvalue, Expression::PLACEHOLDER) !== false) ? new Expression($pvalue) : new Literal($pvalue); } $this->addPredicate($predicates, $combination); } } return $this; } /** * Return the predicates * * @return PredicateInterface[] */ public function getPredicates() { return $this->predicates; } /** * Add predicate using OR operator * * @param PredicateInterface $predicate * @return PredicateSet */ public function orPredicate(PredicateInterface $predicate) { $this->predicates[] = [self::OP_OR, $predicate]; return $this; } /** * Add predicate using AND operator * * @param PredicateInterface $predicate * @return PredicateSet */ public function andPredicate(PredicateInterface $predicate) { $this->predicates[] = [self::OP_AND, $predicate]; return $this; } /** * Get predicate parts for where statement * * @return array */ public function getExpressionData() { $parts = []; for ($i = 0, $count = count($this->predicates); $i < $count; $i++) { /** @var $predicate PredicateInterface */ $predicate = $this->predicates[$i][1]; if ($predicate instanceof PredicateSet) { $parts[] = '('; } $parts = array_merge($parts, $predicate->getExpressionData()); if ($predicate instanceof PredicateSet) { $parts[] = ')'; } if (isset($this->predicates[$i+1])) { $parts[] = sprintf(' %s ', $this->predicates[$i+1][0]); } } return $parts; } /** * Get count of attached predicates * * @return int */ public function count() { return count($this->predicates); } } zend-db-release-2.8.1/src/Sql/PreparableSqlInterface.php000066400000000000000000000013311270372430400231000ustar00rootroot00000000000000 '%1$s', self::SELECT => [ 'SELECT %1$s FROM %2$s' => [ [1 => '%1$s', 2 => '%1$s AS %2$s', 'combinedby' => ', '], null ], 'SELECT %1$s %2$s FROM %3$s' => [ null, [1 => '%1$s', 2 => '%1$s AS %2$s', 'combinedby' => ', '], null ], 'SELECT %1$s' => [ [1 => '%1$s', 2 => '%1$s AS %2$s', 'combinedby' => ', '], ], ], self::JOINS => [ '%1$s' => [ [3 => '%1$s JOIN %2$s ON %3$s', 'combinedby' => ' '] ] ], self::WHERE => 'WHERE %1$s', self::GROUP => [ 'GROUP BY %1$s' => [ [1 => '%1$s', 'combinedby' => ', '] ] ], self::HAVING => 'HAVING %1$s', self::ORDER => [ 'ORDER BY %1$s' => [ [1 => '%1$s', 2 => '%1$s %2$s', 'combinedby' => ', '] ] ], self::LIMIT => 'LIMIT %1$s', self::OFFSET => 'OFFSET %1$s', 'statementEnd' => '%1$s', self::COMBINE => '%1$s ( %2$s )', ]; /** * @var bool */ protected $tableReadOnly = false; /** * @var bool */ protected $prefixColumnsWithTable = true; /** * @var string|array|TableIdentifier */ protected $table = null; /** * @var null|string|Expression */ protected $quantifier = null; /** * @var array */ protected $columns = [self::SQL_STAR]; /** * @var null|Join */ protected $joins = null; /** * @var Where */ protected $where = null; /** * @var array */ protected $order = []; /** * @var null|array */ protected $group = null; /** * @var null|string|array */ protected $having = null; /** * @var int|null */ protected $limit = null; /** * @var int|null */ protected $offset = null; /** * @var array */ protected $combine = []; /** * Constructor * * @param null|string|array|TableIdentifier $table */ public function __construct($table = null) { if ($table) { $this->from($table); $this->tableReadOnly = true; } $this->where = new Where; $this->joins = new Join; $this->having = new Having; } /** * Create from clause * * @param string|array|TableIdentifier $table * @throws Exception\InvalidArgumentException * @return Select */ public function from($table) { if ($this->tableReadOnly) { throw new Exception\InvalidArgumentException('Since this object was created with a table and/or schema in the constructor, it is read only.'); } if (!is_string($table) && !is_array($table) && !$table instanceof TableIdentifier) { throw new Exception\InvalidArgumentException('$table must be a string, array, or an instance of TableIdentifier'); } if (is_array($table) && (!is_string(key($table)) || count($table) !== 1)) { throw new Exception\InvalidArgumentException('from() expects $table as an array is a single element associative array'); } $this->table = $table; return $this; } /** * @param string|Expression $quantifier DISTINCT|ALL * @return Select */ public function quantifier($quantifier) { if (!is_string($quantifier) && !$quantifier instanceof ExpressionInterface) { throw new Exception\InvalidArgumentException( 'Quantifier must be one of DISTINCT, ALL, or some platform specific object implementing ExpressionInterface' ); } $this->quantifier = $quantifier; return $this; } /** * Specify columns from which to select * * Possible valid states: * * array(*) * * array(value, ...) * value can be strings or Expression objects * * array(string => value, ...) * key string will be use as alias, * value can be string or Expression objects * * @param array $columns * @param bool $prefixColumnsWithTable * @return Select */ public function columns(array $columns, $prefixColumnsWithTable = true) { $this->columns = $columns; $this->prefixColumnsWithTable = (bool) $prefixColumnsWithTable; return $this; } /** * Create join clause * * @param string|array $name * @param string $on * @param string|array $columns * @param string $type one of the JOIN_* constants * @throws Exception\InvalidArgumentException * @return Select */ public function join($name, $on, $columns = self::SQL_STAR, $type = self::JOIN_INNER) { $this->joins->join($name, $on, $columns, $type); return $this; } /** * Create where clause * * @param Where|\Closure|string|array|Predicate\PredicateInterface $predicate * @param string $combination One of the OP_* constants from Predicate\PredicateSet * @throws Exception\InvalidArgumentException * @return Select */ public function where($predicate, $combination = Predicate\PredicateSet::OP_AND) { if ($predicate instanceof Where) { $this->where = $predicate; } else { $this->where->addPredicates($predicate, $combination); } return $this; } public function group($group) { if (is_array($group)) { foreach ($group as $o) { $this->group[] = $o; } } else { $this->group[] = $group; } return $this; } /** * Create having clause * * @param Where|\Closure|string|array $predicate * @param string $combination One of the OP_* constants from Predicate\PredicateSet * @return Select */ public function having($predicate, $combination = Predicate\PredicateSet::OP_AND) { if ($predicate instanceof Having) { $this->having = $predicate; } else { $this->having->addPredicates($predicate, $combination); } return $this; } /** * @param string|array $order * @return Select */ public function order($order) { if (is_string($order)) { if (strpos($order, ',') !== false) { $order = preg_split('#,\s+#', $order); } else { $order = (array) $order; } } elseif (!is_array($order)) { $order = [$order]; } foreach ($order as $k => $v) { if (is_string($k)) { $this->order[$k] = $v; } else { $this->order[] = $v; } } return $this; } /** * @param int $limit * @return Select */ public function limit($limit) { if (!is_numeric($limit)) { throw new Exception\InvalidArgumentException(sprintf( '%s expects parameter to be numeric, "%s" given', __METHOD__, (is_object($limit) ? get_class($limit) : gettype($limit)) )); } $this->limit = $limit; return $this; } /** * @param int $offset * @return Select */ public function offset($offset) { if (!is_numeric($offset)) { throw new Exception\InvalidArgumentException(sprintf( '%s expects parameter to be numeric, "%s" given', __METHOD__, (is_object($offset) ? get_class($offset) : gettype($offset)) )); } $this->offset = $offset; return $this; } /** * @param Select $select * @param string $type * @param string $modifier * @return Select * @throws Exception\InvalidArgumentException */ public function combine(Select $select, $type = self::COMBINE_UNION, $modifier = '') { if ($this->combine !== []) { throw new Exception\InvalidArgumentException('This Select object is already combined and cannot be combined with multiple Selects objects'); } $this->combine = [ 'select' => $select, 'type' => $type, 'modifier' => $modifier ]; return $this; } /** * @param string $part * @return Select * @throws Exception\InvalidArgumentException */ public function reset($part) { switch ($part) { case self::TABLE: if ($this->tableReadOnly) { throw new Exception\InvalidArgumentException( 'Since this object was created with a table and/or schema in the constructor, it is read only.' ); } $this->table = null; break; case self::QUANTIFIER: $this->quantifier = null; break; case self::COLUMNS: $this->columns = []; break; case self::JOINS: $this->joins = new Join; break; case self::WHERE: $this->where = new Where; break; case self::GROUP: $this->group = null; break; case self::HAVING: $this->having = new Having; break; case self::LIMIT: $this->limit = null; break; case self::OFFSET: $this->offset = null; break; case self::ORDER: $this->order = []; break; case self::COMBINE: $this->combine = []; break; } return $this; } public function setSpecification($index, $specification) { if (!method_exists($this, 'process' . $index)) { throw new Exception\InvalidArgumentException('Not a valid specification name.'); } $this->specifications[$index] = $specification; return $this; } public function getRawState($key = null) { $rawState = [ self::TABLE => $this->table, self::QUANTIFIER => $this->quantifier, self::COLUMNS => $this->columns, self::JOINS => $this->joins, self::WHERE => $this->where, self::ORDER => $this->order, self::GROUP => $this->group, self::HAVING => $this->having, self::LIMIT => $this->limit, self::OFFSET => $this->offset, self::COMBINE => $this->combine ]; return (isset($key) && array_key_exists($key, $rawState)) ? $rawState[$key] : $rawState; } /** * Returns whether the table is read only or not. * * @return bool */ public function isTableReadOnly() { return $this->tableReadOnly; } protected function processStatementStart(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { if ($this->combine !== []) { return ['(']; } } protected function processStatementEnd(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { if ($this->combine !== []) { return [')']; } } /** * Process the select part * * @param PlatformInterface $platform * @param DriverInterface $driver * @param ParameterContainer $parameterContainer * @return null|array */ protected function processSelect(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { $expr = 1; list($table, $fromTable) = $this->resolveTable($this->table, $platform, $driver, $parameterContainer); // process table columns $columns = []; foreach ($this->columns as $columnIndexOrAs => $column) { if ($column === self::SQL_STAR) { $columns[] = [$fromTable . self::SQL_STAR]; continue; } $columnName = $this->resolveColumnValue( [ 'column' => $column, 'fromTable' => $fromTable, 'isIdentifier' => true, ], $platform, $driver, $parameterContainer, (is_string($columnIndexOrAs) ? $columnIndexOrAs : 'column') ); // process As portion if (is_string($columnIndexOrAs)) { $columnAs = $platform->quoteIdentifier($columnIndexOrAs); } elseif (stripos($columnName, ' as ') === false) { $columnAs = (is_string($column)) ? $platform->quoteIdentifier($column) : 'Expression' . $expr++; } $columns[] = (isset($columnAs)) ? [$columnName, $columnAs] : [$columnName]; } // process join columns foreach ($this->joins->getJoins() as $join) { $joinName = (is_array($join['name'])) ? key($join['name']) : $join['name']; $joinName = parent::resolveTable($joinName, $platform, $driver, $parameterContainer); foreach ($join['columns'] as $jKey => $jColumn) { $jColumns = []; $jFromTable = is_scalar($jColumn) ? $joinName . $platform->getIdentifierSeparator() : ''; $jColumns[] = $this->resolveColumnValue( [ 'column' => $jColumn, 'fromTable' => $jFromTable, 'isIdentifier' => true, ], $platform, $driver, $parameterContainer, (is_string($jKey) ? $jKey : 'column') ); if (is_string($jKey)) { $jColumns[] = $platform->quoteIdentifier($jKey); } elseif ($jColumn !== self::SQL_STAR) { $jColumns[] = $platform->quoteIdentifier($jColumn); } $columns[] = $jColumns; } } if ($this->quantifier) { $quantifier = ($this->quantifier instanceof ExpressionInterface) ? $this->processExpression($this->quantifier, $platform, $driver, $parameterContainer, 'quantifier') : $this->quantifier; } if (!isset($table)) { return [$columns]; } elseif (isset($quantifier)) { return [$quantifier, $columns, $table]; } else { return [$columns, $table]; } } protected function processJoins(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { return $this->processJoin($this->joins, $platform, $driver, $parameterContainer); } protected function processWhere(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { if ($this->where->count() == 0) { return; } return [ $this->processExpression($this->where, $platform, $driver, $parameterContainer, 'where') ]; } protected function processGroup(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { if ($this->group === null) { return; } // process table columns $groups = []; foreach ($this->group as $column) { $groups[] = $this->resolveColumnValue( [ 'column' => $column, 'isIdentifier' => true, ], $platform, $driver, $parameterContainer, 'group' ); } return [$groups]; } protected function processHaving(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { if ($this->having->count() == 0) { return; } return [ $this->processExpression($this->having, $platform, $driver, $parameterContainer, 'having') ]; } protected function processOrder(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { if (empty($this->order)) { return; } $orders = []; foreach ($this->order as $k => $v) { if ($v instanceof ExpressionInterface) { $orders[] = [ $this->processExpression($v, $platform, $driver, $parameterContainer) ]; continue; } if (is_int($k)) { if (strpos($v, ' ') !== false) { list($k, $v) = preg_split('# #', $v, 2); } else { $k = $v; $v = self::ORDER_ASCENDING; } } if (strtoupper($v) == self::ORDER_DESCENDING) { $orders[] = [$platform->quoteIdentifierInFragment($k), self::ORDER_DESCENDING]; } else { $orders[] = [$platform->quoteIdentifierInFragment($k), self::ORDER_ASCENDING]; } } return [$orders]; } protected function processLimit(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { if ($this->limit === null) { return; } if ($parameterContainer) { $parameterContainer->offsetSet('limit', $this->limit, ParameterContainer::TYPE_INTEGER); return [$driver->formatParameterName('limit')]; } return [$platform->quoteValue($this->limit)]; } protected function processOffset(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { if ($this->offset === null) { return; } if ($parameterContainer) { $parameterContainer->offsetSet('offset', $this->offset, ParameterContainer::TYPE_INTEGER); return [$driver->formatParameterName('offset')]; } return [$platform->quoteValue($this->offset)]; } protected function processCombine(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { if ($this->combine == []) { return; } $type = $this->combine['type']; if ($this->combine['modifier']) { $type .= ' ' . $this->combine['modifier']; } return [ strtoupper($type), $this->processSubSelect($this->combine['select'], $platform, $driver, $parameterContainer), ]; } /** * Variable overloading * * @param string $name * @throws Exception\InvalidArgumentException * @return mixed */ public function __get($name) { switch (strtolower($name)) { case 'where': return $this->where; case 'having': return $this->having; case 'joins': return $this->joins; default: throw new Exception\InvalidArgumentException('Not a valid magic property for this object'); } } /** * __clone * * Resets the where object each time the Select is cloned. * * @return void */ public function __clone() { $this->where = clone $this->where; $this->joins = clone $this->joins; $this->having = clone $this->having; } /** * @param string|TableIdentifier|Select $table * @param PlatformInterface $platform * @param DriverInterface $driver * @param ParameterContainer $parameterContainer * @return string */ protected function resolveTable($table, PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { $alias = null; if (is_array($table)) { $alias = key($table); $table = current($table); } $table = parent::resolveTable($table, $platform, $driver, $parameterContainer); if ($alias) { $fromTable = $platform->quoteIdentifier($alias); $table = $this->renderTable($table, $fromTable); } else { $fromTable = $table; } if ($this->prefixColumnsWithTable && $fromTable) { $fromTable .= $platform->getIdentifierSeparator(); } else { $fromTable = ''; } return [ $table, $fromTable ]; } } zend-db-release-2.8.1/src/Sql/Sql.php000066400000000000000000000120401270372430400172600ustar00rootroot00000000000000adapter = $adapter; if ($table) { $this->setTable($table); } $this->sqlPlatform = $sqlPlatform ?: new Platform\Platform($adapter); } /** * @return null|\Zend\Db\Adapter\AdapterInterface */ public function getAdapter() { return $this->adapter; } public function hasTable() { return ($this->table !== null); } public function setTable($table) { if (is_string($table) || is_array($table) || $table instanceof TableIdentifier) { $this->table = $table; } else { throw new Exception\InvalidArgumentException('Table must be a string, array or instance of TableIdentifier.'); } return $this; } public function getTable() { return $this->table; } public function getSqlPlatform() { return $this->sqlPlatform; } public function select($table = null) { if ($this->table !== null && $table !== null) { throw new Exception\InvalidArgumentException(sprintf( 'This Sql object is intended to work with only the table "%s" provided at construction time.', $this->table )); } return new Select(($table) ?: $this->table); } public function insert($table = null) { if ($this->table !== null && $table !== null) { throw new Exception\InvalidArgumentException(sprintf( 'This Sql object is intended to work with only the table "%s" provided at construction time.', $this->table )); } return new Insert(($table) ?: $this->table); } public function update($table = null) { if ($this->table !== null && $table !== null) { throw new Exception\InvalidArgumentException(sprintf( 'This Sql object is intended to work with only the table "%s" provided at construction time.', $this->table )); } return new Update(($table) ?: $this->table); } public function delete($table = null) { if ($this->table !== null && $table !== null) { throw new Exception\InvalidArgumentException(sprintf( 'This Sql object is intended to work with only the table "%s" provided at construction time.', $this->table )); } return new Delete(($table) ?: $this->table); } /** * @param PreparableSqlInterface $sqlObject * @param StatementInterface $statement * @param AdapterInterface $adapter * * @return StatementInterface */ public function prepareStatementForSqlObject(PreparableSqlInterface $sqlObject, StatementInterface $statement = null, AdapterInterface $adapter = null) { $adapter = $adapter ?: $this->adapter; $statement = $statement ?: $adapter->getDriver()->createStatement(); return $this->sqlPlatform->setSubject($sqlObject)->prepareStatement($adapter, $statement); } /** * Get sql string using platform or sql object * * @param SqlInterface $sqlObject * @param PlatformInterface|null $platform * * @return string * * @deprecated Deprecated in 2.4. Use buildSqlString() instead */ public function getSqlStringForSqlObject(SqlInterface $sqlObject, PlatformInterface $platform = null) { $platform = ($platform) ?: $this->adapter->getPlatform(); return $this->sqlPlatform->setSubject($sqlObject)->getSqlString($platform); } /** * @param SqlInterface $sqlObject * @param AdapterInterface $adapter * * @return string * * @throws Exception\InvalidArgumentException */ public function buildSqlString(SqlInterface $sqlObject, AdapterInterface $adapter = null) { return $this ->sqlPlatform ->setSubject($sqlObject) ->getSqlString($adapter ? $adapter->getPlatform() : $this->adapter->getPlatform()); } } zend-db-release-2.8.1/src/Sql/SqlInterface.php000066400000000000000000000011651270372430400211070ustar00rootroot00000000000000table = (string) $table; if ('' === $this->table) { throw new Exception\InvalidArgumentException('$table must be a valid table name, empty string given'); } if (null === $schema) { $this->schema = null; } else { if (! (is_string($schema) || is_callable([$schema, '__toString']))) { throw new Exception\InvalidArgumentException(sprintf( '$schema must be a valid schema name, parameter of type %s given', is_object($schema) ? get_class($schema) : gettype($schema) )); } $this->schema = (string) $schema; if ('' === $this->schema) { throw new Exception\InvalidArgumentException( '$schema must be a valid schema name or null, empty string given' ); } } } /** * @param string $table * * @deprecated please use the constructor and build a new {@see TableIdentifier} instead */ public function setTable($table) { $this->table = $table; } /** * @return string */ public function getTable() { return $this->table; } /** * @return bool */ public function hasSchema() { return ($this->schema !== null); } /** * @param $schema * * @deprecated please use the constructor and build a new {@see TableIdentifier} instead */ public function setSchema($schema) { $this->schema = $schema; } /** * @return null|string */ public function getSchema() { return $this->schema; } public function getTableAndSchema() { return [$this->table, $this->schema]; } } zend-db-release-2.8.1/src/Sql/Update.php000066400000000000000000000152461270372430400177560ustar00rootroot00000000000000 'UPDATE %1$s', self::SPECIFICATION_JOIN => [ '%1$s' => [ [3 => '%1$s JOIN %2$s ON %3$s', 'combinedby' => ' '] ] ], self::SPECIFICATION_SET => 'SET %1$s', self::SPECIFICATION_WHERE => 'WHERE %1$s', ]; /** * @var string|TableIdentifier */ protected $table = ''; /** * @var bool */ protected $emptyWhereProtection = true; /** * @var PriorityList */ protected $set; /** * @var string|Where */ protected $where = null; /** * @var null|Join */ protected $joins = null; /** * Constructor * * @param null|string|TableIdentifier $table */ public function __construct($table = null) { if ($table) { $this->table($table); } $this->where = new Where(); $this->joins = new Join(); $this->set = new PriorityList(); $this->set->isLIFO(false); } /** * Specify table for statement * * @param string|TableIdentifier $table * @return Update */ public function table($table) { $this->table = $table; return $this; } /** * Set key/value pairs to update * * @param array $values Associative array of key values * @param string $flag One of the VALUES_* constants * @throws Exception\InvalidArgumentException * @return Update */ public function set(array $values, $flag = self::VALUES_SET) { if ($values === null) { throw new Exception\InvalidArgumentException('set() expects an array of values'); } if ($flag == self::VALUES_SET) { $this->set->clear(); } $priority = is_numeric($flag) ? $flag : 0; foreach ($values as $k => $v) { if (!is_string($k)) { throw new Exception\InvalidArgumentException('set() expects a string for the value key'); } $this->set->insert($k, $v, $priority); } return $this; } /** * Create where clause * * @param Where|\Closure|string|array $predicate * @param string $combination One of the OP_* constants from Predicate\PredicateSet * @throws Exception\InvalidArgumentException * @return Update */ public function where($predicate, $combination = Predicate\PredicateSet::OP_AND) { if ($predicate instanceof Where) { $this->where = $predicate; } else { $this->where->addPredicates($predicate, $combination); } return $this; } /** * Create join clause * * @param string|array $name * @param string $on * @param string $type one of the JOIN_* constants * @throws Exception\InvalidArgumentException * @return Update */ public function join($name, $on, $type = Join::JOIN_INNER) { $this->joins->join($name, $on, [], $type); return $this; } public function getRawState($key = null) { $rawState = [ 'emptyWhereProtection' => $this->emptyWhereProtection, 'table' => $this->table, 'set' => $this->set->toArray(), 'where' => $this->where, 'joins' => $this->joins ]; return (isset($key) && array_key_exists($key, $rawState)) ? $rawState[$key] : $rawState; } protected function processUpdate(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { return sprintf( $this->specifications[static::SPECIFICATION_UPDATE], $this->resolveTable($this->table, $platform, $driver, $parameterContainer) ); } protected function processSet(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { $setSql = []; foreach ($this->set as $column => $value) { $prefix = $platform->quoteIdentifier($column) . ' = '; if (is_scalar($value) && $parameterContainer) { $setSql[] = $prefix . $driver->formatParameterName($column); $parameterContainer->offsetSet($column, $value); } else { $setSql[] = $prefix . $this->resolveColumnValue( $value, $platform, $driver, $parameterContainer ); } } return sprintf( $this->specifications[static::SPECIFICATION_SET], implode(', ', $setSql) ); } protected function processWhere(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { if ($this->where->count() == 0) { return; } return sprintf( $this->specifications[static::SPECIFICATION_WHERE], $this->processExpression($this->where, $platform, $driver, $parameterContainer, 'where') ); } protected function processJoins(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null) { return $this->processJoin($this->joins, $platform, $driver, $parameterContainer); } /** * Variable overloading * * Proxies to "where" only * * @param string $name * @return mixed */ public function __get($name) { if (strtolower($name) == 'where') { return $this->where; } } /** * __clone * * Resets the where object each time the Update is cloned. * * @return void */ public function __clone() { $this->where = clone $this->where; $this->set = clone $this->set; } } zend-db-release-2.8.1/src/Sql/Where.php000066400000000000000000000005721270372430400176020ustar00rootroot00000000000000isInitialized; } /** * Initialize * * @throws Exception\RuntimeException * @return null */ public function initialize() { if ($this->isInitialized) { return; } if (!$this->featureSet instanceof Feature\FeatureSet) { $this->featureSet = new Feature\FeatureSet; } $this->featureSet->setTableGateway($this); $this->featureSet->apply(EventFeatureEventsInterface::EVENT_PRE_INITIALIZE, []); if (!$this->adapter instanceof AdapterInterface) { throw new Exception\RuntimeException('This table does not have an Adapter setup'); } if (!is_string($this->table) && !$this->table instanceof TableIdentifier && !is_array($this->table)) { throw new Exception\RuntimeException('This table object does not have a valid table set.'); } if (!$this->resultSetPrototype instanceof ResultSetInterface) { $this->resultSetPrototype = new ResultSet; } if (!$this->sql instanceof Sql) { $this->sql = new Sql($this->adapter, $this->table); } $this->featureSet->apply(EventFeatureEventsInterface::EVENT_POST_INITIALIZE, []); $this->isInitialized = true; } /** * Get table name * * @return string */ public function getTable() { return $this->table; } /** * Get adapter * * @return AdapterInterface */ public function getAdapter() { return $this->adapter; } /** * @return array */ public function getColumns() { return $this->columns; } /** * @return Feature\FeatureSet */ public function getFeatureSet() { return $this->featureSet; } /** * Get select result prototype * * @return ResultSet */ public function getResultSetPrototype() { return $this->resultSetPrototype; } /** * @return Sql */ public function getSql() { return $this->sql; } /** * Select * * @param Where|\Closure|string|array $where * @return ResultSet */ public function select($where = null) { if (!$this->isInitialized) { $this->initialize(); } $select = $this->sql->select(); if ($where instanceof \Closure) { $where($select); } elseif ($where !== null) { $select->where($where); } return $this->selectWith($select); } /** * @param Select $select * @return null|ResultSetInterface * @throws \RuntimeException */ public function selectWith(Select $select) { if (!$this->isInitialized) { $this->initialize(); } return $this->executeSelect($select); } /** * @param Select $select * @return ResultSet * @throws Exception\RuntimeException */ protected function executeSelect(Select $select) { $selectState = $select->getRawState(); if ($selectState['table'] != $this->table && (is_array($selectState['table']) && end($selectState['table']) != $this->table) ) { throw new Exception\RuntimeException( 'The table name of the provided select object must match that of the table' ); } if ($selectState['columns'] == [Select::SQL_STAR] && $this->columns !== []) { $select->columns($this->columns); } // apply preSelect features $this->featureSet->apply(EventFeatureEventsInterface::EVENT_PRE_SELECT, [$select]); // prepare and execute $statement = $this->sql->prepareStatementForSqlObject($select); $result = $statement->execute(); // build result set $resultSet = clone $this->resultSetPrototype; $resultSet->initialize($result); // apply postSelect features $this->featureSet->apply(EventFeatureEventsInterface::EVENT_POST_SELECT, [$statement, $result, $resultSet]); return $resultSet; } /** * Insert * * @param array $set * @return int */ public function insert($set) { if (!$this->isInitialized) { $this->initialize(); } $insert = $this->sql->insert(); $insert->values($set); return $this->executeInsert($insert); } /** * @param Insert $insert * @return int */ public function insertWith(Insert $insert) { if (!$this->isInitialized) { $this->initialize(); } return $this->executeInsert($insert); } /** * @todo add $columns support * * @param Insert $insert * @return int * @throws Exception\RuntimeException */ protected function executeInsert(Insert $insert) { $insertState = $insert->getRawState(); if ($insertState['table'] != $this->table) { throw new Exception\RuntimeException( 'The table name of the provided Insert object must match that of the table' ); } // apply preInsert features $this->featureSet->apply(EventFeatureEventsInterface::EVENT_PRE_INSERT, [$insert]); // Most RDBMS solutions do not allow using table aliases in INSERTs // See https://github.com/zendframework/zf2/issues/7311 $unaliasedTable = false; if (is_array($insertState['table'])) { $tableData = array_values($insertState['table']); $unaliasedTable = array_shift($tableData); $insert->into($unaliasedTable); } $statement = $this->sql->prepareStatementForSqlObject($insert); $result = $statement->execute(); $this->lastInsertValue = $this->adapter->getDriver()->getConnection()->getLastGeneratedValue(); // apply postInsert features $this->featureSet->apply(EventFeatureEventsInterface::EVENT_POST_INSERT, [$statement, $result]); // Reset original table information in Insert instance, if necessary if ($unaliasedTable) { $insert->into($insertState['table']); } return $result->getAffectedRows(); } /** * Update * * @param array $set * @param string|array|\Closure $where * @param null|array $joins * @return int */ public function update($set, $where = null, array $joins = null) { if (!$this->isInitialized) { $this->initialize(); } $sql = $this->sql; $update = $sql->update(); $update->set($set); if ($where !== null) { $update->where($where); } if ($joins) { foreach ($joins as $join) { $type = isset($join['type']) ? $join['type'] : $update::JOIN_INNER; $update->join($join['name'], $join['on'], $type); } } return $this->executeUpdate($update); } /** * @param \Zend\Db\Sql\Update $update * @return int */ public function updateWith(Update $update) { if (!$this->isInitialized) { $this->initialize(); } return $this->executeUpdate($update); } /** * @todo add $columns support * * @param Update $update * @return int * @throws Exception\RuntimeException */ protected function executeUpdate(Update $update) { $updateState = $update->getRawState(); if ($updateState['table'] != $this->table) { throw new Exception\RuntimeException( 'The table name of the provided Update object must match that of the table' ); } // apply preUpdate features $this->featureSet->apply(EventFeatureEventsInterface::EVENT_PRE_UPDATE, [$update]); $unaliasedTable = false; if (is_array($updateState['table'])) { $tableData = array_values($updateState['table']); $unaliasedTable = array_shift($tableData); $update->table($unaliasedTable); } $statement = $this->sql->prepareStatementForSqlObject($update); $result = $statement->execute(); // apply postUpdate features $this->featureSet->apply(EventFeatureEventsInterface::EVENT_POST_UPDATE, [$statement, $result]); // Reset original table information in Update instance, if necessary if ($unaliasedTable) { $update->table($updateState['table']); } return $result->getAffectedRows(); } /** * Delete * * @param Where|\Closure|string|array $where * @return int */ public function delete($where) { if (!$this->isInitialized) { $this->initialize(); } $delete = $this->sql->delete(); if ($where instanceof \Closure) { $where($delete); } else { $delete->where($where); } return $this->executeDelete($delete); } /** * @param Delete $delete * @return int */ public function deleteWith(Delete $delete) { $this->initialize(); return $this->executeDelete($delete); } /** * @todo add $columns support * * @param Delete $delete * @return int * @throws Exception\RuntimeException */ protected function executeDelete(Delete $delete) { $deleteState = $delete->getRawState(); if ($deleteState['table'] != $this->table) { throw new Exception\RuntimeException( 'The table name of the provided Update object must match that of the table' ); } // pre delete update $this->featureSet->apply(EventFeatureEventsInterface::EVENT_PRE_DELETE, [$delete]); $statement = $this->sql->prepareStatementForSqlObject($delete); $result = $statement->execute(); // apply postDelete features $this->featureSet->apply(EventFeatureEventsInterface::EVENT_POST_DELETE, [$statement, $result]); return $result->getAffectedRows(); } /** * Get last insert value * * @return int */ public function getLastInsertValue() { return $this->lastInsertValue; } /** * __get * * @param string $property * @throws Exception\InvalidArgumentException * @return mixed */ public function __get($property) { switch (strtolower($property)) { case 'lastinsertvalue': return $this->lastInsertValue; case 'adapter': return $this->adapter; case 'table': return $this->table; } if ($this->featureSet->canCallMagicGet($property)) { return $this->featureSet->callMagicGet($property); } throw new Exception\InvalidArgumentException('Invalid magic property access in ' . __CLASS__ . '::__get()'); } /** * @param string $property * @param mixed $value * @return mixed * @throws Exception\InvalidArgumentException */ public function __set($property, $value) { if ($this->featureSet->canCallMagicSet($property)) { return $this->featureSet->callMagicSet($property, $value); } throw new Exception\InvalidArgumentException('Invalid magic property access in ' . __CLASS__ . '::__set()'); } /** * @param $method * @param $arguments * @return mixed * @throws Exception\InvalidArgumentException */ public function __call($method, $arguments) { if ($this->featureSet->canCallMagicCall($method)) { return $this->featureSet->callMagicCall($method, $arguments); } throw new Exception\InvalidArgumentException(sprintf( 'Invalid method (%s) called, caught by %s::__call()', $method, __CLASS__ )); } /** * __clone */ public function __clone() { $this->resultSetPrototype = (isset($this->resultSetPrototype)) ? clone $this->resultSetPrototype : null; $this->sql = clone $this->sql; if (is_object($this->table)) { $this->table = clone $this->table; } elseif (is_array($this->table) && count($this->table) == 1 && is_object(reset($this->table)) ) { foreach ($this->table as $alias => &$tableObject) { $tableObject = clone $tableObject; } } } } zend-db-release-2.8.1/src/TableGateway/Exception/000077500000000000000000000000001270372430400215635ustar00rootroot00000000000000zend-db-release-2.8.1/src/TableGateway/Exception/ExceptionInterface.php000066400000000000000000000006771270372430400260650ustar00rootroot00000000000000tableGateway = $tableGateway; } public function initialize() { throw new Exception\RuntimeException('This method is not intended to be called on this object.'); } public function getMagicMethodSpecifications() { return []; } /* public function preInitialize(); public function postInitialize(); public function preSelect(Select $select); public function postSelect(StatementInterface $statement, ResultInterface $result, ResultSetInterface $resultSet); public function preInsert(Insert $insert); public function postInsert(StatementInterface $statement, ResultInterface $result); public function preUpdate(Update $update); public function postUpdate(StatementInterface $statement, ResultInterface $result); public function preDelete(Delete $delete); public function postDelete(StatementInterface $statement, ResultInterface $result); */ } zend-db-release-2.8.1/src/TableGateway/Feature/EventFeature.php000066400000000000000000000165031270372430400243330ustar00rootroot00000000000000eventManager = ($eventManager instanceof EventManagerInterface) ? $eventManager : new EventManager; $this->eventManager->addIdentifiers([ 'Zend\Db\TableGateway\TableGateway', ]); $this->event = ($tableGatewayEvent) ?: new EventFeature\TableGatewayEvent(); } /** * Retrieve composed event manager instance * * @return EventManagerInterface */ public function getEventManager() { return $this->eventManager; } /** * Retrieve composed event instance * * @return EventFeature\TableGatewayEvent */ public function getEvent() { return $this->event; } /** * Initialize feature and trigger "preInitialize" event * * Ensures that the composed TableGateway has identifiers based on the * class name, and that the event target is set to the TableGateway * instance. It then triggers the "preInitialize" event. * * @return void */ public function preInitialize() { if (get_class($this->tableGateway) != 'Zend\Db\TableGateway\TableGateway') { $this->eventManager->addIdentifiers([get_class($this->tableGateway)]); } $this->event->setTarget($this->tableGateway); $this->event->setName(static::EVENT_PRE_INITIALIZE); $this->eventManager->triggerEvent($this->event); } /** * Trigger the "postInitialize" event * * @return void */ public function postInitialize() { $this->event->setName(static::EVENT_POST_INITIALIZE); $this->eventManager->triggerEvent($this->event); } /** * Trigger the "preSelect" event * * Triggers the "preSelect" event mapping the following parameters: * - $select as "select" * * @param Select $select * @return void */ public function preSelect(Select $select) { $this->event->setName(static::EVENT_PRE_SELECT); $this->event->setParams(['select' => $select]); $this->eventManager->triggerEvent($this->event); } /** * Trigger the "postSelect" event * * Triggers the "postSelect" event mapping the following parameters: * - $statement as "statement" * - $result as "result" * - $resultSet as "result_set" * * @param StatementInterface $statement * @param ResultInterface $result * @param ResultSetInterface $resultSet * @return void */ public function postSelect(StatementInterface $statement, ResultInterface $result, ResultSetInterface $resultSet) { $this->event->setName(static::EVENT_POST_SELECT); $this->event->setParams([ 'statement' => $statement, 'result' => $result, 'result_set' => $resultSet ]); $this->eventManager->triggerEvent($this->event); } /** * Trigger the "preInsert" event * * Triggers the "preInsert" event mapping the following parameters: * - $insert as "insert" * * @param Insert $insert * @return void */ public function preInsert(Insert $insert) { $this->event->setName(static::EVENT_PRE_INSERT); $this->event->setParams(['insert' => $insert]); $this->eventManager->triggerEvent($this->event); } /** * Trigger the "postInsert" event * * Triggers the "postInsert" event mapping the following parameters: * - $statement as "statement" * - $result as "result" * * @param StatementInterface $statement * @param ResultInterface $result * @return void */ public function postInsert(StatementInterface $statement, ResultInterface $result) { $this->event->setName(static::EVENT_POST_INSERT); $this->event->setParams([ 'statement' => $statement, 'result' => $result, ]); $this->eventManager->triggerEvent($this->event); } /** * Trigger the "preUpdate" event * * Triggers the "preUpdate" event mapping the following parameters: * - $update as "update" * * @param Update $update * @return void */ public function preUpdate(Update $update) { $this->event->setName(static::EVENT_PRE_UPDATE); $this->event->setParams(['update' => $update]); $this->eventManager->triggerEvent($this->event); } /** * Trigger the "postUpdate" event * * Triggers the "postUpdate" event mapping the following parameters: * - $statement as "statement" * - $result as "result" * * @param StatementInterface $statement * @param ResultInterface $result * @return void */ public function postUpdate(StatementInterface $statement, ResultInterface $result) { $this->event->setName(static::EVENT_POST_UPDATE); $this->event->setParams([ 'statement' => $statement, 'result' => $result, ]); $this->eventManager->triggerEvent($this->event); } /** * Trigger the "preDelete" event * * Triggers the "preDelete" event mapping the following parameters: * - $delete as "delete" * * @param Delete $delete * @return void */ public function preDelete(Delete $delete) { $this->event->setName(static::EVENT_PRE_DELETE); $this->event->setParams(['delete' => $delete]); $this->eventManager->triggerEvent($this->event); } /** * Trigger the "postDelete" event * * Triggers the "postDelete" event mapping the following parameters: * - $statement as "statement" * - $result as "result" * * @param StatementInterface $statement * @param ResultInterface $result * @return void */ public function postDelete(StatementInterface $statement, ResultInterface $result) { $this->event->setName(static::EVENT_POST_DELETE); $this->event->setParams([ 'statement' => $statement, 'result' => $result, ]); $this->eventManager->triggerEvent($this->event); } } zend-db-release-2.8.1/src/TableGateway/Feature/EventFeature/000077500000000000000000000000001270372430400236155ustar00rootroot00000000000000zend-db-release-2.8.1/src/TableGateway/Feature/EventFeature/TableGatewayEvent.php000066400000000000000000000053411270372430400277040ustar00rootroot00000000000000name; } /** * Get target/context from which event was triggered * * @return null|string|object */ public function getTarget() { return $this->target; } /** * Get parameters passed to the event * * @return array|\ArrayAccess */ public function getParams() { return $this->params; } /** * Get a single parameter by name * * @param string $name * @param mixed $default Default value to return if parameter does not exist * @return mixed */ public function getParam($name, $default = null) { return (isset($this->params[$name]) ? $this->params[$name] : $default); } /** * Set the event name * * @param string $name * @return void */ public function setName($name) { $this->name = $name; } /** * Set the event target/context * * @param null|string|object $target * @return void */ public function setTarget($target) { $this->target = $target; } /** * Set event parameters * * @param string $params * @return void */ public function setParams($params) { $this->params = $params; } /** * Set a single parameter by key * * @param string $name * @param mixed $value * @return void */ public function setParam($name, $value) { $this->params[$name] = $value; } /** * Indicate whether or not the parent EventManagerInterface should stop propagating events * * @param bool $flag * @return void */ public function stopPropagation($flag = true) { return; } /** * Has this event indicated event propagation should stop? * * @return bool */ public function propagationIsStopped() { return false; } } zend-db-release-2.8.1/src/TableGateway/Feature/EventFeatureEventsInterface.php000066400000000000000000000023001270372430400273270ustar00rootroot00000000000000addFeatures($features); } } public function setTableGateway(AbstractTableGateway $tableGateway) { $this->tableGateway = $tableGateway; foreach ($this->features as $feature) { $feature->setTableGateway($this->tableGateway); } return $this; } public function getFeatureByClassName($featureClassName) { $feature = false; foreach ($this->features as $potentialFeature) { if ($potentialFeature instanceof $featureClassName) { $feature = $potentialFeature; break; } } return $feature; } public function addFeatures(array $features) { foreach ($features as $feature) { $this->addFeature($feature); } return $this; } public function addFeature(AbstractFeature $feature) { if ($this->tableGateway instanceof TableGatewayInterface) { $feature->setTableGateway($this->tableGateway); } $this->features[] = $feature; return $this; } public function apply($method, $args) { foreach ($this->features as $feature) { if (method_exists($feature, $method)) { $return = call_user_func_array([$feature, $method], $args); if ($return === self::APPLY_HALT) { break; } } } } /** * @param string $property * @return bool */ public function canCallMagicGet($property) { return false; } /** * @param string $property * @return mixed */ public function callMagicGet($property) { $return = null; return $return; } /** * @param string $property * @return bool */ public function canCallMagicSet($property) { return false; } /** * @param $property * @param $value * @return mixed */ public function callMagicSet($property, $value) { $return = null; return $return; } /** * Is the method requested available in one of the added features * @param string $method * @return bool */ public function canCallMagicCall($method) { if (!empty($this->features)) { foreach ($this->features as $feature) { if (method_exists($feature, $method)) { return true; } } } return false; } /** * Call method of on added feature as though it were a local method * @param string $method * @param array $arguments * @return mixed */ public function callMagicCall($method, $arguments) { foreach ($this->features as $feature) { if (method_exists($feature, $method)) { return $feature->$method($arguments); } } return; } } zend-db-release-2.8.1/src/TableGateway/Feature/GlobalAdapterFeature.php000066400000000000000000000032671270372430400257560ustar00rootroot00000000000000tableGateway->adapter = self::getStaticAdapter(); } } zend-db-release-2.8.1/src/TableGateway/Feature/MasterSlaveFeature.php000066400000000000000000000037441270372430400255030ustar00rootroot00000000000000slaveAdapter = $slaveAdapter; if ($slaveSql) { $this->slaveSql = $slaveSql; } } public function getSlaveAdapter() { return $this->slaveAdapter; } /** * @return Sql */ public function getSlaveSql() { return $this->slaveSql; } /** * after initialization, retrieve the original adapter as "master" */ public function postInitialize() { $this->masterSql = $this->tableGateway->sql; if ($this->slaveSql === null) { $this->slaveSql = new Sql( $this->slaveAdapter, $this->tableGateway->sql->getTable(), $this->tableGateway->sql->getSqlPlatform() ); } } /** * preSelect() * Replace adapter with slave temporarily */ public function preSelect() { $this->tableGateway->sql = $this->slaveSql; } /** * postSelect() * Ensure to return to the master adapter */ public function postSelect() { $this->tableGateway->sql = $this->masterSql; } } zend-db-release-2.8.1/src/TableGateway/Feature/MetadataFeature.php000066400000000000000000000045761270372430400250010ustar00rootroot00000000000000metadata = $metadata; } $this->sharedData['metadata'] = [ 'primaryKey' => null, 'columns' => [] ]; } public function postInitialize() { if ($this->metadata === null) { $this->metadata = SourceFactory::createSourceFromAdapter($this->tableGateway->adapter); } // localize variable for brevity $t = $this->tableGateway; $m = $this->metadata; // get column named $columns = $m->getColumnNames($t->table); $t->columns = $columns; // set locally $this->sharedData['metadata']['columns'] = $columns; // process primary key only if table is a table; there are no PK constraints on views if (!($m->getTable($t->table) instanceof TableObject)) { return; } $pkc = null; foreach ($m->getConstraints($t->table) as $constraint) { /** @var $constraint \Zend\Db\Metadata\Object\ConstraintObject */ if ($constraint->getType() == 'PRIMARY KEY') { $pkc = $constraint; break; } } if ($pkc === null) { throw new Exception\RuntimeException('A primary key for this column could not be found in the metadata.'); } if (count($pkc->getColumns()) == 1) { $pkck = $pkc->getColumns(); $primaryKey = $pkck[0]; } else { $primaryKey = $pkc->getColumns(); } $this->sharedData['metadata']['primaryKey'] = $primaryKey; } } zend-db-release-2.8.1/src/TableGateway/Feature/RowGatewayFeature.php000066400000000000000000000051061270372430400253400ustar00rootroot00000000000000constructorArguments = func_get_args(); } public function postInitialize() { $args = $this->constructorArguments; /** @var $resultSetPrototype ResultSet */ $resultSetPrototype = $this->tableGateway->resultSetPrototype; if (!$this->tableGateway->resultSetPrototype instanceof ResultSet) { throw new Exception\RuntimeException( 'This feature ' . __CLASS__ . ' expects the ResultSet to be an instance of Zend\Db\ResultSet\ResultSet' ); } if (isset($args[0])) { if (is_string($args[0])) { $primaryKey = $args[0]; $rowGatewayPrototype = new RowGateway($primaryKey, $this->tableGateway->table, $this->tableGateway->adapter); $resultSetPrototype->setArrayObjectPrototype($rowGatewayPrototype); } elseif ($args[0] instanceof RowGatewayInterface) { $rowGatewayPrototype = $args[0]; $resultSetPrototype->setArrayObjectPrototype($rowGatewayPrototype); } } else { // get from metadata feature $metadata = $this->tableGateway->featureSet->getFeatureByClassName('Zend\Db\TableGateway\Feature\MetadataFeature'); if ($metadata === false || !isset($metadata->sharedData['metadata'])) { throw new Exception\RuntimeException( 'No information was provided to the RowGatewayFeature and/or no MetadataFeature could be consulted to find the primary key necessary for RowGateway object creation.' ); } $primaryKey = $metadata->sharedData['metadata']['primaryKey']; $rowGatewayPrototype = new RowGateway($primaryKey, $this->tableGateway->table, $this->tableGateway->adapter); $resultSetPrototype->setArrayObjectPrototype($rowGatewayPrototype); } } } zend-db-release-2.8.1/src/TableGateway/Feature/SequenceFeature.php000066400000000000000000000073741270372430400250300ustar00rootroot00000000000000primaryKeyField = $primaryKeyField; $this->sequenceName = $sequenceName; } /** * @param Insert $insert * @return Insert */ public function preInsert(Insert $insert) { $columns = $insert->getRawState('columns'); $values = $insert->getRawState('values'); $key = array_search($this->primaryKeyField, $columns); if ($key !== false) { $this->sequenceValue = $values[$key]; return $insert; } $this->sequenceValue = $this->nextSequenceId(); if ($this->sequenceValue === null) { return $insert; } $insert->values([$this->primaryKeyField => $this->sequenceValue], Insert::VALUES_MERGE); return $insert; } /** * @param StatementInterface $statement * @param ResultInterface $result */ public function postInsert(StatementInterface $statement, ResultInterface $result) { if ($this->sequenceValue !== null) { $this->tableGateway->lastInsertValue = $this->sequenceValue; } } /** * Generate a new value from the specified sequence in the database, and return it. * @return int */ public function nextSequenceId() { $platform = $this->tableGateway->adapter->getPlatform(); $platformName = $platform->getName(); switch ($platformName) { case 'Oracle': $sql = 'SELECT ' . $platform->quoteIdentifier($this->sequenceName) . '.NEXTVAL as "nextval" FROM dual'; break; case 'PostgreSQL': $sql = 'SELECT NEXTVAL(\'"' . $this->sequenceName . '"\')'; break; default : return; } $statement = $this->tableGateway->adapter->createStatement(); $statement->prepare($sql); $result = $statement->execute(); $sequence = $result->current(); unset($statement, $result); return $sequence['nextval']; } /** * Return the most recent value from the specified sequence in the database. * @return int */ public function lastSequenceId() { $platform = $this->tableGateway->adapter->getPlatform(); $platformName = $platform->getName(); switch ($platformName) { case 'Oracle': $sql = 'SELECT ' . $platform->quoteIdentifier($this->sequenceName) . '.CURRVAL as "currval" FROM dual'; break; case 'PostgreSQL': $sql = 'SELECT CURRVAL(\'' . $this->sequenceName . '\')'; break; default : return; } $statement = $this->tableGateway->adapter->createStatement(); $statement->prepare($sql); $result = $statement->execute(); $sequence = $result->current(); unset($statement, $result); return $sequence['currval']; } } zend-db-release-2.8.1/src/TableGateway/TableGateway.php000066400000000000000000000055631270372430400227200ustar00rootroot00000000000000table = $table; // adapter $this->adapter = $adapter; // process features if ($features !== null) { if ($features instanceof Feature\AbstractFeature) { $features = [$features]; } if (is_array($features)) { $this->featureSet = new Feature\FeatureSet($features); } elseif ($features instanceof Feature\FeatureSet) { $this->featureSet = $features; } else { throw new Exception\InvalidArgumentException( 'TableGateway expects $feature to be an instance of an AbstractFeature or a FeatureSet, or an array of AbstractFeatures' ); } } else { $this->featureSet = new Feature\FeatureSet(); } // result prototype $this->resultSetPrototype = ($resultSetPrototype) ?: new ResultSet; // Sql object (factory for select, insert, update, delete) $this->sql = ($sql) ?: new Sql($this->adapter, $this->table); // check sql object bound to same table if ($this->sql->getTable() != $this->table) { throw new Exception\InvalidArgumentException('The table inside the provided Sql object must match the table of this TableGateway'); } $this->initialize(); } } zend-db-release-2.8.1/src/TableGateway/TableGatewayInterface.php000066400000000000000000000010751270372430400245330ustar00rootroot00000000000000