Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 033ac60208 | |||
| d8e0be18c8 | |||
| f96bf9eb81 | |||
| b76a335dc9 | |||
| 375eae1a5c | |||
| ca216b5296 | |||
| c212d118ba | |||
| 292d20595d | |||
| 1e7ac8ba15 | |||
| 1954f80fa3 | |||
| a5c42edbe5 | |||
| 3b465f419a | |||
| 0f489e80ad | |||
| 95a748152e | |||
| d050e6e04e | |||
| ae3ea39a4c | |||
| 943a9a2e09 | |||
| 76ccd69cec | |||
| 88d95823b2 | |||
| ac4364040d | |||
| b37d318159 | |||
| b11203537e | |||
| a79175330e | |||
| 49c17fc391 | |||
| 5afdfec91d | |||
| 2051a5db5d | |||
| 4984a72d0d | |||
| 45003593e1 | |||
| f53dd22cd9 | |||
| 526e704c9f | |||
| 4682846d3e | |||
| 95ef80e6db | |||
| 4fd069b479 | |||
| 2024d424cd | |||
| 6d94455540 | |||
| 2871896d54 | |||
| e9a63900de | |||
| baab13ae13 | |||
| 5192eecce2 | |||
| 7581d55428 | |||
| aae17d4ae8 | |||
| a366ba4c0c | |||
| 2cfc7f7454 | |||
| e9e84b5c3b | |||
| c32a99b14c | |||
| 758ae42df0 | |||
| 0970a3c60e | |||
| 6b78ca1a5a | |||
| e899c9989e |
@@ -1,15 +0,0 @@
|
||||
codecov:
|
||||
branch: stable22
|
||||
ci:
|
||||
- drone.nextcloud.com
|
||||
- !scrutinizer-ci.com
|
||||
|
||||
coverage:
|
||||
precision: 2
|
||||
round: down
|
||||
range: "70...100"
|
||||
status:
|
||||
project: off
|
||||
patch: off
|
||||
|
||||
comment: off
|
||||
@@ -1,47 +0,0 @@
|
||||
FROM ubuntu:focal
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# PHP
|
||||
RUN apt-get update -y
|
||||
RUN apt-get install --no-install-recommends -y \
|
||||
php7.4 \
|
||||
php7.4-gd \
|
||||
php7.4-zip \
|
||||
php7.4-curl \
|
||||
php7.4-xml \
|
||||
php7.4-mbstring \
|
||||
php7.4-sqlite \
|
||||
php7.4-xdebug \
|
||||
php7.4-pgsql \
|
||||
php7.4-intl \
|
||||
php7.4-imagick \
|
||||
php7.4-gmp \
|
||||
php7.4-apcu \
|
||||
php7.4-bcmath \
|
||||
libmagickcore-6.q16-3-extra \
|
||||
curl \
|
||||
vim \
|
||||
lsof \
|
||||
make \
|
||||
nodejs \
|
||||
npm
|
||||
|
||||
RUN echo "xdebug.remote_enable = 1" >> /etc/php/7.4/cli/conf.d/20-xdebug.ini
|
||||
RUN echo "xdebug.remote_autostart = 1" >> /etc/php/7.4/cli/conf.d/20-xdebug.ini
|
||||
|
||||
# Docker
|
||||
RUN apt-get -y install \
|
||||
apt-transport-https \
|
||||
ca-certificates \
|
||||
curl \
|
||||
gnupg-agent \
|
||||
software-properties-common
|
||||
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
|
||||
RUN add-apt-repository \
|
||||
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
|
||||
$(lsb_release -cs) \
|
||||
stable"
|
||||
RUN apt-get update -y
|
||||
RUN apt-get install -y docker-ce docker-ce-cli containerd.io
|
||||
RUN ln -s /var/run/docker-host.sock /var/run/docker.sock
|
||||
@@ -1,18 +0,0 @@
|
||||
<?php
|
||||
|
||||
$cloudEnvironmentId = getenv('CLOUDENV_ENVIRONMENT_ID');
|
||||
|
||||
$CONFIG = [
|
||||
'mail_from_address' => 'no-reply',
|
||||
'mail_smtpmode' => 'smtp',
|
||||
'mail_sendmailmode' => 'smtp',
|
||||
'mail_domain' => 'example.com',
|
||||
'mail_smtphost' => 'localhost',
|
||||
'mail_smtpport' => '1025',
|
||||
'memcache.local' => '\OC\Memcache\APCu',
|
||||
];
|
||||
|
||||
if($cloudEnvironmentId !== true) {
|
||||
$CONFIG['overwritehost'] = $cloudEnvironmentId . '-80.apps.codespaces.githubusercontent.com';
|
||||
$CONFIG['overwriteprotocol'] = 'https';
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"name": "NextcloudServer",
|
||||
"dockerComposeFile": "docker-compose.yml",
|
||||
"service": "nextclouddev",
|
||||
"postCreateCommand": ".devcontainer/setup.sh",
|
||||
"forwardPorts": [
|
||||
80,
|
||||
8080,
|
||||
8025
|
||||
],
|
||||
"runArgs": [
|
||||
"--privileged"
|
||||
],
|
||||
"extensions": [
|
||||
"felixfbecker.php-debug",
|
||||
"felixfbecker.php-intellisense",
|
||||
"ms-azuretools.vscode-docker"
|
||||
],
|
||||
"settings": {
|
||||
"php.suggest.basic": false,
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
version: '3'
|
||||
services:
|
||||
nextclouddev:
|
||||
build: .
|
||||
volumes:
|
||||
- .:/workspace:cached
|
||||
- /var/run/docker.sock:/var/run/docker-host.sock
|
||||
command: /bin/sh -c "while sleep 1000; do :; done"
|
||||
ports:
|
||||
- 80:80
|
||||
- 8080:8080
|
||||
- 8025:8025
|
||||
|
||||
db:
|
||||
image: postgres
|
||||
restart: always
|
||||
environment:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
network_mode: service:nextclouddev
|
||||
|
||||
adminer:
|
||||
image: adminer
|
||||
restart: always
|
||||
network_mode: service:nextclouddev
|
||||
|
||||
mailhog:
|
||||
image: mailhog/mailhog
|
||||
restart: always
|
||||
network_mode: service:nextclouddev
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/bin/bash
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
cd $DIR/
|
||||
git submodule update --init
|
||||
|
||||
# Codespace config
|
||||
cp .devcontainer/codespace.config.php config/codespace.config.php
|
||||
-2387
File diff suppressed because it is too large
Load Diff
@@ -1,25 +0,0 @@
|
||||
# https://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = tab
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.feature]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
||||
[*.yml]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.svg]
|
||||
insert_final_newline = false
|
||||
@@ -1,11 +0,0 @@
|
||||
# Ignoring folders for eslint
|
||||
node_modules/
|
||||
3rdparty/
|
||||
**/vendor/
|
||||
**/l10n/
|
||||
**/js/*
|
||||
*.config.js
|
||||
tests/lib/
|
||||
|
||||
# TODO: remove when comments files is not using handlebar templates anymore
|
||||
apps/comments/src/templates.js
|
||||
@@ -1,17 +0,0 @@
|
||||
module.exports = {
|
||||
globals: {
|
||||
__webpack_nonce__: true,
|
||||
__webpack_public_path__: true,
|
||||
_: true,
|
||||
$: true,
|
||||
moment: true,
|
||||
escapeHTML: true,
|
||||
oc_userconfig: true,
|
||||
dayNames: true,
|
||||
firstDay: true,
|
||||
},
|
||||
extends: ['@nextcloud'],
|
||||
rules: {
|
||||
'no-tabs': 'warn',
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/core/js/dist/*.js binary
|
||||
/core/js/dist/*.js.map binary
|
||||
|
||||
/apps/accessibility/js/*.js binary
|
||||
/apps/accessibility/js/*.js.map binary
|
||||
/apps/comments/js/*.js binary
|
||||
/apps/comments/js/*.js.map binary
|
||||
/apps/dashboard/js/*.js binary
|
||||
/apps/dashboard/js/*.js.map binary
|
||||
/apps/files/js/dist/*.js binary
|
||||
/apps/files/js/dist/*.js.map binary
|
||||
/apps/files_sharing/js/dist/*.js binary
|
||||
/apps/files_sharing/js/dist/*.js.map binary
|
||||
/apps/files_trashbin/js/*.js binary
|
||||
/apps/files_trashbin/js/*.js.map binary
|
||||
/apps/files_versions/js/*.js binary
|
||||
/apps/files_versions/js/*.js.map binary
|
||||
/apps/oauth2/js/*.js binary
|
||||
/apps/oauth2/js/*.js.map binary
|
||||
/apps/settings/js/vue* binary
|
||||
/apps/systemtags/js/systemtags.js binary
|
||||
/apps/systemtags/js/systemtags.js.map binary
|
||||
/apps/twofactor_backupcodes/js/*.js binary
|
||||
/apps/twofactor_backupcodes/js/*.js.map binary
|
||||
/apps/updatenotification/js/updatenotification.js binary
|
||||
/apps/updatenotification/js/updatenotification.js.map binary
|
||||
/apps/user_status/js/*.js binary
|
||||
/apps/user_status/js/*.js.map binary
|
||||
/apps/weather_status/js/*.js binary
|
||||
/apps/weather_status/js/*.js.map binary
|
||||
/apps/workflowengine/js/*.js binary
|
||||
/apps/workflowengine/js/*.js.map binary
|
||||
@@ -1,2 +0,0 @@
|
||||
*/Activity/* @nickvergessen
|
||||
*/Notifications/* @nickvergessen
|
||||
@@ -1,68 +0,0 @@
|
||||
## Submitting issues
|
||||
|
||||
If you have questions about how to install or use Nextcloud, please direct these to our [forum][forum]. We are also available on [IRC][irc].
|
||||
|
||||
### Short version
|
||||
|
||||
* The [**issue templates can be found here**][templates] but be aware of the different repositories! See list below. Please always use an issue template when reporting issues.
|
||||
|
||||
### Guidelines
|
||||
* Please search the existing issues first, it's likely that your issue was already reported or even fixed.
|
||||
- Go to one of the repositories, click "issues" and type any word in the top search/command bar.
|
||||
- You can also filter by appending e. g. "state:open" to the search string.
|
||||
- More info on [search syntax within github](https://help.github.com/articles/searching-issues)
|
||||
* This repository ([server](https://github.com/nextcloud/server/issues)) is *only* for issues within the Nextcloud Server code. This also includes the apps: files, encryption, external storage, sharing, deleted files, versions, LDAP, and WebDAV Auth
|
||||
* __SECURITY__: Report any potential security bug to us via [our HackerOne page](https://hackerone.com/nextcloud) following our [security policy](https://nextcloud.com/security/) instead of filing an issue in our bug tracker.
|
||||
* The issues in other components should be reported in their respective repositories: You will find them in our [GitHub Organization](https://github.com/nextcloud/)
|
||||
|
||||
* Report the issue using one of our [templates][templates], they include all the information we need to track down the issue.
|
||||
|
||||
Help us to maximize the effort we can spend fixing issues and adding new features, by not reporting duplicate issues.
|
||||
|
||||
[templates]: ./ISSUE_TEMPLATE
|
||||
[forum]: https://help.nextcloud.com/
|
||||
[irc]: https://webchat.freenode.net/?channels=nextcloud
|
||||
|
||||
## Contributing to Source Code
|
||||
|
||||
Thanks for wanting to contribute source code to Nextcloud. That's great!
|
||||
|
||||
Please read the [Developer Manuals][devmanual] to learn how to create your first application or how to test the Nextcloud code with PHPUnit.
|
||||
|
||||
### Tests
|
||||
|
||||
In order to constantly increase the quality of our software we can no longer accept pull request which submit un-tested code.
|
||||
It is a must have that changed and added code segments are unit tested.
|
||||
In some areas unit testing is hard (aka almost impossible) as of today - in these areas refactoring WHILE fixing a bug is encouraged to enable unit testing.
|
||||
|
||||
### Sign your work
|
||||
|
||||
We use the Developer Certificate of Origin (DCO) as a additional safeguard
|
||||
for the Nextcloud project. This is a well established and widely used
|
||||
mechanism to assure contributors have confirmed their right to license
|
||||
their contribution under the project's license.
|
||||
Please read [contribute/developer-certificate-of-origin][dcofile].
|
||||
If you can certify it, then just add a line to every git commit message:
|
||||
|
||||
````
|
||||
Signed-off-by: Random J Developer <random@developer.example.org>
|
||||
````
|
||||
|
||||
Use your real name (sorry, no pseudonyms or anonymous contributions).
|
||||
If you set your `user.name` and `user.email` git configs, you can sign your
|
||||
commit automatically with `git commit -s`. You can also use git [aliases](https://git-scm.com/book/tr/v2/Git-Basics-Git-Aliases)
|
||||
like `git config --global alias.ci 'commit -s'`. Now you can commit with
|
||||
`git ci` and the commit will be signed.
|
||||
|
||||
### Apply a license
|
||||
|
||||
In case you are not sure how to add or update the license header correctly please have a look at [contribute/HowToApplyALicense.md][applyalicense]
|
||||
|
||||
[devmanual]: https://docs.nextcloud.com/server/latest/developer_manual/
|
||||
[dcofile]: https://github.com/nextcloud/server/blob/master/contribute/developer-certificate-of-origin
|
||||
[applyalicense]: https://github.com/nextcloud/server/blob/master/contribute/HowToApplyALicense.md
|
||||
|
||||
## Translations
|
||||
Please submit translations via [Transifex][transifex].
|
||||
|
||||
[transifex]: https://www.transifex.com/nextcloud
|
||||
@@ -1 +0,0 @@
|
||||
custom: https://nextcloud.com/include/
|
||||
@@ -1,166 +0,0 @@
|
||||
---
|
||||
name: 🐛 Bug report
|
||||
about: Help us improving by reporting a bug
|
||||
labels: bug, 0. Needs triage
|
||||
---
|
||||
|
||||
<!--
|
||||
Thanks for reporting issues back to Nextcloud!
|
||||
|
||||
Note: This is the **issue tracker of Nextcloud**, please do NOT use this to get answers to your questions or get help for fixing your installation. This is a place to report bugs to developers, after your server has been debugged. You can find help debugging your system on our home user forums: https://help.nextcloud.com or, if you use Nextcloud in a large organization, ask our engineers on https://portal.nextcloud.com. See also https://nextcloud.com/support for support options.
|
||||
|
||||
Nextcloud is an open source project backed by Nextcloud GmbH. Most of our volunteers are home users and thus primarily care about issues that affect home users. Our paid engineers prioritize issues of our customers. If you are neither a home user nor a customer, consider paying somebody to fix your issue, do it yourself or become a customer.
|
||||
|
||||
Guidelines for submitting issues:
|
||||
|
||||
* Please search the existing issues first, it's likely that your issue was already reported or even fixed.
|
||||
- Go to https://github.com/nextcloud and type any word in the top search/command bar. You probably see something like "We couldn’t find any repositories matching ..." then click "Issues" in the left navigation.
|
||||
- You can also filter by appending e. g. "state:open" to the search string.
|
||||
- More info on search syntax within github: https://help.github.com/articles/searching-issues
|
||||
|
||||
* This repository https://github.com/nextcloud/server/issues is *only* for issues within the Nextcloud Server code. This also includes the apps: files, encryption, external storage, sharing, deleted files, versions, LDAP, and WebDAV Auth
|
||||
|
||||
* SECURITY: Report any potential security bug to us via our HackerOne page (https://hackerone.com/nextcloud) following our security policy (https://nextcloud.com/security/) instead of filing an issue in our bug tracker.
|
||||
|
||||
* The issues in other components should be reported in their respective repositories: You will find them in our GitHub Organization (https://github.com/nextcloud/)
|
||||
|
||||
* You can also use the Issue Template app to prefill most of the required information: https://apps.nextcloud.com/apps/issuetemplate
|
||||
-->
|
||||
|
||||
<!--- Please keep this note for other contributors -->
|
||||
|
||||
### How to use GitHub
|
||||
|
||||
* Please use the 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to show that you are affected by the same issue.
|
||||
* Please don't comment if you have no relevant information to add. It's just extra noise for everyone subscribed to this issue.
|
||||
* Subscribe to receive notifications on status change and new comments.
|
||||
|
||||
|
||||
### Steps to reproduce
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
### Expected behaviour
|
||||
Tell us what should happen
|
||||
|
||||
### Actual behaviour
|
||||
Tell us what happens instead
|
||||
|
||||
### Server configuration
|
||||
|
||||
**Operating system:**
|
||||
|
||||
**Web server:**
|
||||
|
||||
**Database:**
|
||||
|
||||
**PHP version:**
|
||||
|
||||
**Nextcloud version:** (see Nextcloud admin page)
|
||||
|
||||
**Updated from an older Nextcloud/ownCloud or fresh install:**
|
||||
|
||||
**Where did you install Nextcloud from:**
|
||||
|
||||
**Signing status:**
|
||||
<details>
|
||||
<summary>Signing status</summary>
|
||||
|
||||
```
|
||||
Login as admin user into your Nextcloud and access
|
||||
http://example.com/index.php/settings/integrity/failed
|
||||
paste the results here.
|
||||
```
|
||||
</details>
|
||||
|
||||
**List of activated apps:**
|
||||
<details>
|
||||
<summary>App list</summary>
|
||||
|
||||
```
|
||||
If you have access to your command line run e.g.:
|
||||
sudo -u www-data php occ app:list
|
||||
from within your Nextcloud installation folder
|
||||
```
|
||||
</details>
|
||||
|
||||
**Nextcloud configuration:**
|
||||
<details>
|
||||
<summary>Config report</summary>
|
||||
|
||||
```
|
||||
If you have access to your command line run e.g.:
|
||||
sudo -u www-data php occ config:list system
|
||||
from within your Nextcloud installation folder
|
||||
|
||||
or
|
||||
|
||||
Insert your config.php content here.
|
||||
Make sure to remove all sensitive content such as passwords. (e.g. database password, passwordsalt, secret, smtp password, …)
|
||||
```
|
||||
</details>
|
||||
|
||||
**Are you using external storage, if yes which one:** local/smb/sftp/...
|
||||
|
||||
**Are you using encryption:** yes/no
|
||||
|
||||
**Are you using an external user-backend, if yes which one:** LDAP/ActiveDirectory/Webdav/...
|
||||
|
||||
#### LDAP configuration (delete this part if not used)
|
||||
<details>
|
||||
<summary>LDAP config</summary>
|
||||
|
||||
```
|
||||
With access to your command line run e.g.:
|
||||
sudo -u www-data php occ ldap:show-config
|
||||
from within your Nextcloud installation folder
|
||||
|
||||
Without access to your command line download the data/owncloud.db to your local
|
||||
computer or access your SQL server remotely and run the select query:
|
||||
SELECT * FROM `oc_appconfig` WHERE `appid` = 'user_ldap';
|
||||
|
||||
|
||||
Eventually replace sensitive data as the name/IP-address of your LDAP server or groups.
|
||||
```
|
||||
</details>
|
||||
|
||||
### Client configuration
|
||||
**Browser:**
|
||||
|
||||
**Operating system:**
|
||||
|
||||
### Logs
|
||||
|
||||
<!--- Reports without logs might be closed as unqualified reports! -->
|
||||
|
||||
#### Web server error log
|
||||
<details>
|
||||
<summary>Web server error log</summary>
|
||||
|
||||
```
|
||||
Insert your webserver log here
|
||||
```
|
||||
</details>
|
||||
|
||||
#### Nextcloud log (data/nextcloud.log)
|
||||
<details>
|
||||
<summary>Nextcloud log</summary>
|
||||
|
||||
```
|
||||
Insert your Nextcloud log here
|
||||
```
|
||||
</details>
|
||||
|
||||
#### Browser log
|
||||
<details>
|
||||
<summary>Browser log</summary>
|
||||
|
||||
```
|
||||
Insert your browser log here, this could for example include:
|
||||
|
||||
a) The javascript console log
|
||||
b) The network log
|
||||
c) ...
|
||||
```
|
||||
</details>
|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
name: 🚀 Feature request
|
||||
about: Suggest an idea for this project
|
||||
labels: enhancement, 0. Needs triage
|
||||
---
|
||||
|
||||
<!--
|
||||
Thanks for reporting issues back to Nextcloud!
|
||||
|
||||
Note: This is the **issue tracker of Nextcloud**, please do NOT use this to get answers to your questions or get help for fixing your installation. This is a place to report bugs to developers, after your server has been debugged. You can find help debugging your system on our home user forums: https://help.nextcloud.com or, if you use Nextcloud in a large organization, ask our engineers on https://portal.nextcloud.com. See also https://nextcloud.com/support for support options.
|
||||
|
||||
Nextcloud is an open source project backed by Nextcloud GmbH. Most of our volunteers are home users and thus primarily care about issues that affect home users. Our paid engineers prioritize issues of our customers. If you are neither a home user nor a customer, consider paying somebody to fix your issue, do it yourself or become a customer.
|
||||
|
||||
Guidelines for submitting issues:
|
||||
|
||||
* Please search the existing issues first, it's likely that your issue was already reported or even fixed.
|
||||
- Go to https://github.com/nextcloud and type any word in the top search/command bar. You probably see something like "We couldn’t find any repositories matching ..." then click "Issues" in the left navigation.
|
||||
- You can also filter by appending e. g. "state:open" to the search string.
|
||||
- More info on search syntax within github: https://help.github.com/articles/searching-issues
|
||||
|
||||
* This repository https://github.com/nextcloud/server/issues is *only* for issues within the Nextcloud Server code. This also includes the apps: files, encryption, external storage, sharing, deleted files, versions, LDAP, and WebDAV Auth
|
||||
|
||||
* SECURITY: Report any potential security bug to us via our HackerOne page (https://hackerone.com/nextcloud) following our security policy (https://nextcloud.com/security/) instead of filing an issue in our bug tracker.
|
||||
|
||||
* The issues in other components should be reported in their respective repositories: You will find them in our GitHub Organization (https://github.com/nextcloud/)
|
||||
-->
|
||||
|
||||
|
||||
<!--- Please keep this note for other contributors -->
|
||||
|
||||
### How to use GitHub
|
||||
|
||||
* Please use the 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to show that you are interested into the same feature.
|
||||
* Please don't comment if you have no relevant information to add. It's just extra noise for everyone subscribed to this issue.
|
||||
* Subscribe to receive notifications on status change and new comments.
|
||||
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
@@ -1,8 +0,0 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: ❓ Community Support and Help
|
||||
url: https://help.nextcloud.com/
|
||||
about: Configuration, webserver/proxy or performance issues and other questions
|
||||
- name: 💼 Nextcloud Enterprise
|
||||
url: https://portal.nextcloud.com/
|
||||
about: If you are a Nextcloud Enterprise customer, or need Professional support, so it can be resolved directly by our dedicated engineers more quickly
|
||||
@@ -1,3 +0,0 @@
|
||||
firstPRMergeComment: >
|
||||
Thanks for your first pull request and welcome to the community!
|
||||
Feel free to keep them coming! If you are looking for issues to tackle then have a look at this selection: https://github.com/nextcloud/server/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22
|
||||
@@ -1,165 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
# Linting and coding style
|
||||
- package-ecosystem: composer
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: saturday
|
||||
time: "03:00"
|
||||
timezone: Europe/Paris
|
||||
labels:
|
||||
- "3. to review"
|
||||
- "feature: dependencies"
|
||||
reviewers:
|
||||
- "nextcloud/server-dependabot"
|
||||
|
||||
# Main master npm
|
||||
- package-ecosystem: npm
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: saturday
|
||||
time: "03:00"
|
||||
timezone: Europe/Paris
|
||||
open-pull-requests-limit: 10
|
||||
labels:
|
||||
- "3. to review"
|
||||
- "feature: dependencies"
|
||||
reviewers:
|
||||
- "nextcloud/server-dependabot"
|
||||
|
||||
# Testing master npm
|
||||
- package-ecosystem: npm
|
||||
directory: "/build"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: saturday
|
||||
time: "03:00"
|
||||
timezone: Europe/Paris
|
||||
labels:
|
||||
- "3. to review"
|
||||
- "feature: dependencies"
|
||||
|
||||
# Testing master composer
|
||||
- package-ecosystem: composer
|
||||
directory: "/build/integration"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: saturday
|
||||
time: "03:00"
|
||||
timezone: Europe/Paris
|
||||
labels:
|
||||
- "3. to review"
|
||||
- "feature: dependencies"
|
||||
|
||||
|
||||
# Main stableXX npm
|
||||
- package-ecosystem: npm
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: saturday
|
||||
time: "03:00"
|
||||
timezone: Europe/Paris
|
||||
target-branch: stable19
|
||||
labels:
|
||||
- "3. to review"
|
||||
- "feature: dependencies"
|
||||
reviewers:
|
||||
- "nextcloud/server-dependabot"
|
||||
ignore:
|
||||
# ignore all GitHub linguist patch updates
|
||||
- dependency-name: "*"
|
||||
update-types: ["version-update:semver-major", "version-update:semver-minor"]
|
||||
|
||||
- package-ecosystem: npm
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: saturday
|
||||
time: "03:00"
|
||||
timezone: Europe/Paris
|
||||
target-branch: stable20
|
||||
labels:
|
||||
- "3. to review"
|
||||
- "feature: dependencies"
|
||||
reviewers:
|
||||
- "nextcloud/server-dependabot"
|
||||
ignore:
|
||||
# ignore all GitHub linguist patch updates
|
||||
- dependency-name: "*"
|
||||
update-types: ["version-update:semver-major", "version-update:semver-minor"]
|
||||
|
||||
- package-ecosystem: npm
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: saturday
|
||||
time: "03:00"
|
||||
timezone: Europe/Paris
|
||||
target-branch: stable21
|
||||
labels:
|
||||
- "3. to review"
|
||||
- "feature: dependencies"
|
||||
reviewers:
|
||||
- "nextcloud/server-dependabot"
|
||||
ignore:
|
||||
# ignore all GitHub linguist patch updates
|
||||
- dependency-name: "*"
|
||||
update-types: ["version-update:semver-major", "version-update:semver-minor"]
|
||||
|
||||
# Testing StableXX composer
|
||||
- package-ecosystem: composer
|
||||
directory: "/build/integration"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: saturday
|
||||
time: "03:00"
|
||||
timezone: Europe/Paris
|
||||
target-branch: stable19
|
||||
labels:
|
||||
- "3. to review"
|
||||
- "feature: dependencies"
|
||||
reviewers:
|
||||
- "nextcloud/server-dependabot"
|
||||
ignore:
|
||||
# ignore all GitHub linguist patch updates
|
||||
- dependency-name: "*"
|
||||
update-types: ["version-update:semver-major", "version-update:semver-minor"]
|
||||
|
||||
- package-ecosystem: composer
|
||||
directory: "/build/integration"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: saturday
|
||||
time: "03:00"
|
||||
timezone: Europe/Paris
|
||||
target-branch: stable20
|
||||
labels:
|
||||
- "3. to review"
|
||||
- "feature: dependencies"
|
||||
reviewers:
|
||||
- "nextcloud/server-dependabot"
|
||||
ignore:
|
||||
# ignore all GitHub linguist patch updates
|
||||
- dependency-name: "*"
|
||||
update-types: ["version-update:semver-major", "version-update:semver-minor"]
|
||||
|
||||
- package-ecosystem: composer
|
||||
directory: "/build/integration"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: saturday
|
||||
time: "03:00"
|
||||
timezone: Europe/Paris
|
||||
target-branch: stable21
|
||||
labels:
|
||||
- "3. to review"
|
||||
- "feature: dependencies"
|
||||
reviewers:
|
||||
- "nextcloud/server-dependabot"
|
||||
ignore:
|
||||
# ignore all GitHub linguist patch updates
|
||||
- dependency-name: "*"
|
||||
update-types: ["version-update:semver-major", "version-update:semver-minor"]
|
||||
@@ -1,33 +0,0 @@
|
||||
# We wait 1 months to check
|
||||
daysUntilStale: 30
|
||||
|
||||
# If no answer after two weeks, we close
|
||||
daysUntilClose: 14
|
||||
|
||||
# Only issues that requires info from the op
|
||||
onlyLabels:
|
||||
- "needs info"
|
||||
|
||||
# Only if issues that are not triaged
|
||||
exemptLabels:
|
||||
- "1. to develop"
|
||||
- "2. developing"
|
||||
- "3. to review"
|
||||
- "4. to release"
|
||||
- security
|
||||
|
||||
# Label to use when marking as stale
|
||||
staleLabel: stale
|
||||
|
||||
# Comment to post when marking as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity and seems to be missing some essential information.
|
||||
It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
|
||||
# Limit the number of actions per hour, from 1-30. Default is 30
|
||||
limitPerRun: 30
|
||||
|
||||
# Limit to only `issues` or `pulls`
|
||||
only: issues
|
||||
@@ -1,30 +0,0 @@
|
||||
# This workflow is provided via the organization template repository
|
||||
#
|
||||
# https://github.com/nextcloud/.github
|
||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
||||
|
||||
name: Pull request checks
|
||||
|
||||
on: pull_request
|
||||
|
||||
jobs:
|
||||
block-merges-eol:
|
||||
name: Block merges for EOL branches
|
||||
|
||||
# Only run on stableXX branches
|
||||
if: startsWith( github.base_ref, 'stable')
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Download updater config
|
||||
run: curl https://raw.githubusercontent.com/nextcloud/updater_server/production/config/config.php --output config.php
|
||||
|
||||
- name: Set server major version environment
|
||||
run: |
|
||||
# retrieve version number from branch reference
|
||||
server_major=$(echo "${{ github.base_ref }}" | sed -En 's/stable//p')
|
||||
echo "server_major=$server_major" >> $GITHUB_ENV
|
||||
|
||||
- name: Checking if ${{ env.server_major }} is EOL
|
||||
run: |
|
||||
php -r 'echo json_encode(require_once "config.php");' | jq --arg version "${{ env.server_major }}" '.stable[$version]["100"].eol' | grep --silent -i 'false'
|
||||
@@ -1,21 +0,0 @@
|
||||
# This workflow is provided via the organization template repository
|
||||
#
|
||||
# https://github.com/nextcloud/.github
|
||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
||||
|
||||
name: Pull request checks
|
||||
|
||||
on: pull_request
|
||||
|
||||
jobs:
|
||||
block-merges-during-freeze:
|
||||
name: Block merges during feature freezes
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Download version.php from ${{ github.base_ref }}
|
||||
run: curl https://raw.githubusercontent.com/nextcloud/server/${{ github.base_ref }}/version.php --output version.php
|
||||
|
||||
- name: Run check
|
||||
run: cat version.php | grep 'OC_VersionString' | grep -i -v 'RC'
|
||||
@@ -1,29 +0,0 @@
|
||||
# This workflow is provided via the organization template repository
|
||||
#
|
||||
# https://github.com/nextcloud/.github
|
||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
||||
|
||||
name: Dependabot
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
branches:
|
||||
- master
|
||||
- stable*
|
||||
|
||||
jobs:
|
||||
auto-merge:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Default github action approve
|
||||
- uses: hmarr/auto-approve-action@b40d6c9ed2fa10c9a2749eca7eb004418a705501 # v2
|
||||
if: github.actor == 'dependabot[bot]'
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Nextcloud bot approve and merge request
|
||||
- uses: ahmadnassri/action-dependabot-auto-merge@45fc124d949b19b6b8bf6645b6c9d55f4f9ac61a # v2.6.6
|
||||
if: github.actor == 'dependabot[bot]'
|
||||
with:
|
||||
target: minor
|
||||
github-token: ${{ secrets.DEPENDABOT_AUTOMERGE_TOKEN }}
|
||||
@@ -1,12 +0,0 @@
|
||||
name: Pull request checks
|
||||
on: pull_request
|
||||
|
||||
jobs:
|
||||
commit-message-check:
|
||||
name: Block fixup and squash commits
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Run check
|
||||
uses: xt0rted/block-autosquash-commits-action@79880c36b4811fe549cfffe20233df88876024e7 # v2.2.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,64 +0,0 @@
|
||||
name: Lint
|
||||
on: pull_request
|
||||
|
||||
jobs:
|
||||
php-linters:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['7.3', '7.4', '8.0']
|
||||
name: php${{ matrix.php-versions }} lint
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- name: Set up php${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.36.0
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
extensions: ctype,curl,dom,fileinfo,gd,intl,json,mbstring,openssl,pdo_sqlite,posix,sqlite,xml,zip
|
||||
coverage: none
|
||||
- name: Lint
|
||||
run: composer run lint
|
||||
|
||||
php-cs-fixer:
|
||||
name: php-cs check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- name: Set up php
|
||||
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.36.0
|
||||
with:
|
||||
php-version: 7.4
|
||||
extensions: ctype,curl,dom,fileinfo,gd,intl,json,mbstring,openssl,pdo_sqlite,posix,sqlite,xml,zip
|
||||
coverage: none
|
||||
tools: cs2pr
|
||||
- name: Install dependencies
|
||||
run: composer i
|
||||
- name: Run coding standards check
|
||||
run: |
|
||||
composer run cs:check -- --format=checkstyle | cs2pr
|
||||
composer run cs:check || ( echo 'Please run `composer run cs:fix` to format your code' && exit 1 )
|
||||
shell: bash
|
||||
|
||||
node:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [12.x]
|
||||
|
||||
name: eslint node${{ matrix.node-version }}
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Set up node ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@f1f314fca9dfce2769ece7d933488f076716723e # v1.4.6
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Lint
|
||||
run: npm run lint
|
||||
@@ -1,95 +0,0 @@
|
||||
name: Node
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- stable*
|
||||
|
||||
jobs:
|
||||
versions:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
nodeVersion: ${{ steps.versions.outputs.nodeVersion }}
|
||||
npmVersion: ${{ steps.versions.outputs.npmVersion }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0
|
||||
|
||||
- name: Read package.json node and npm engines version
|
||||
uses: skjnldsv/read-package-engines-version-actions@1e2f46e78e31476bc71ebd909105e6e033d5a6f4 # v1.1
|
||||
id: versions
|
||||
with:
|
||||
fallbackNode: '^12'
|
||||
fallbackNpm: '^6'
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
needs: versions
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0
|
||||
|
||||
- name: Set up node ${{ needs.versions.outputs.nodeVersion }}
|
||||
uses: actions/setup-node@7c12f8017d5436eb855f1ed4399f037a36fbd9e8 # v2.5.2
|
||||
with:
|
||||
node-version: ${{ needs.versions.outputs.nodeVersion }}
|
||||
|
||||
- name: Set up npm ${{ needs.versions.outputs.npmVersion }}
|
||||
run: npm i -g npm@"${{ needs.versions.outputs.npmVersion }}"
|
||||
|
||||
- name: Install dependencies
|
||||
env:
|
||||
CYPRESS_INSTALL_BINARY: 0
|
||||
PUPPETEER_SKIP_DOWNLOAD: true
|
||||
run: npm ci
|
||||
|
||||
- name: Test
|
||||
run: npm run test
|
||||
|
||||
jsunit:
|
||||
runs-on: ubuntu-latest
|
||||
needs: versions
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0
|
||||
|
||||
- name: Set up node ${{ needs.versions.outputs.nodeVersion }}
|
||||
uses: actions/setup-node@7c12f8017d5436eb855f1ed4399f037a36fbd9e8 # v2.5.2
|
||||
with:
|
||||
node-version: ${{ needs.versions.outputs.nodeVersion }}
|
||||
|
||||
- name: Set up npm ${{ needs.versions.outputs.npmVersion }}
|
||||
run: npm i -g npm@"${{ needs.versions.outputs.npmVersion }}"
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Test
|
||||
run: ./autotest-js.sh
|
||||
|
||||
handlebars:
|
||||
runs-on: ubuntu-latest
|
||||
needs: versions
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0
|
||||
|
||||
- name: Set up node ${{ needs.versions.outputs.nodeVersion }}
|
||||
uses: actions/setup-node@7c12f8017d5436eb855f1ed4399f037a36fbd9e8 # v2.5.2
|
||||
with:
|
||||
node-version: ${{ needs.versions.outputs.nodeVersion }}
|
||||
|
||||
- name: Set up npm ${{ needs.versions.outputs.npmVersion }}
|
||||
run: npm i -g npm@"${{ needs.versions.outputs.npmVersion }}"
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Run compile
|
||||
run: ./build/compile-handlebars-templates.sh
|
||||
@@ -1,58 +0,0 @@
|
||||
# This workflow is provided via the organization template repository
|
||||
#
|
||||
# https://github.com/nextcloud/.github
|
||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
||||
|
||||
name: Node
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
- stable*
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
name: node
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
|
||||
|
||||
- name: Read package.json node and npm engines version
|
||||
uses: skjnldsv/read-package-engines-version-actions@1bdcee71fa343c46b18dc6aceffb4cd1e35209c6 # v1.2
|
||||
id: versions
|
||||
with:
|
||||
fallbackNode: '^12'
|
||||
fallbackNpm: '^6'
|
||||
|
||||
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
|
||||
uses: actions/setup-node@3235b876344d2a9aa001b8d1453c930bba69e610 # v3.9.1
|
||||
with:
|
||||
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
||||
|
||||
- name: Set up npm ${{ steps.versions.outputs.npmVersion }}
|
||||
run: npm i -g npm@"${{ steps.versions.outputs.npmVersion }}"
|
||||
|
||||
- name: Install dependencies & build
|
||||
run: |
|
||||
npm ci
|
||||
npm run build --if-present
|
||||
|
||||
- name: Check webpack build changes
|
||||
run: |
|
||||
bash -c "[[ ! \"`git status --porcelain `\" ]] || (echo 'Please recompile and commit the assets, see the section \"Show changes on failure\" for details' && exit 1)"
|
||||
|
||||
- name: Show changes on failure
|
||||
if: failure()
|
||||
run: |
|
||||
git status
|
||||
git --no-pager diff
|
||||
exit 1 # make it red to grab attention
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
name: PHPUnit
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- stable*
|
||||
|
||||
jobs:
|
||||
phpunit-oci8:
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
strategy:
|
||||
# do not stop on another job's failure
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: [ '7.4' ]
|
||||
databases: [ 'oci' ]
|
||||
|
||||
name: php${{ matrix.php-versions }}-${{ matrix.databases }}
|
||||
|
||||
services:
|
||||
oracle:
|
||||
image: ghcr.io/gvenzl/oracle-xe:11
|
||||
|
||||
# Provide passwords and other environment variables to container
|
||||
env:
|
||||
ORACLE_RANDOM_PASSWORD: true
|
||||
APP_USER: autotest
|
||||
APP_USER_PASSWORD: owncloud
|
||||
|
||||
# Forward Oracle port
|
||||
ports:
|
||||
- 1521:1521/tcp
|
||||
|
||||
# Provide healthcheck script options for startup
|
||||
options: >-
|
||||
--health-cmd healthcheck.sh
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 10
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0
|
||||
|
||||
- name: Checkout submodules
|
||||
shell: bash
|
||||
run: |
|
||||
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
|
||||
git submodule sync --recursive
|
||||
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.36.0
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
extensions: ctype,curl,dom,fileinfo,gd,intl,json,mbstring,oci8,openssl,pcntl,pdo_sqlite,posix,sqlite,xml,zip
|
||||
tools: phpunit:8.5.2
|
||||
coverage: none
|
||||
|
||||
- name: Set up Nextcloud
|
||||
run: |
|
||||
mkdir data
|
||||
./occ maintenance:install --verbose --database=oci --database-name=XE --database-host=127.0.0.1 --database-port=1521 --database-user=autotest --database-pass=owncloud --admin-user admin --admin-pass admin
|
||||
php -f index.php
|
||||
|
||||
- name: PHPUnit
|
||||
working-directory: tests
|
||||
run: phpunit --configuration phpunit-autotest.xml --group DB,SLOWDB
|
||||
@@ -1,28 +0,0 @@
|
||||
name: Psalm show github
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- stable*
|
||||
|
||||
jobs:
|
||||
psalm:
|
||||
name: Psalm
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Psalm
|
||||
uses: docker://vimeo/psalm-github-actions:4.9.3
|
||||
continue-on-error: true
|
||||
with:
|
||||
composer_ignore_platform_reqs: false
|
||||
report_file: results.sarif
|
||||
- name: Upload Analysis results to GitHub
|
||||
uses: github/codeql-action/upload-sarif@231aa2c8a89117b126725a0e11897209b7118144 # v1.1.39
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
@@ -1,28 +0,0 @@
|
||||
name: Psalm Security Analysis
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- stable*
|
||||
|
||||
jobs:
|
||||
psalm:
|
||||
name: Psalm
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Psalm
|
||||
uses: docker://vimeo/psalm-github-actions:4.9.3
|
||||
with:
|
||||
security_analysis: true
|
||||
composer_ignore_platform_reqs: false
|
||||
report_file: results.sarif
|
||||
- name: Upload Security Analysis results to GitHub
|
||||
uses: github/codeql-action/upload-sarif@231aa2c8a89117b126725a0e11897209b7118144 # v1.1.39
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
@@ -1,124 +0,0 @@
|
||||
name: S3 External storage
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- stable*
|
||||
paths:
|
||||
- 'apps/files_external/**'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'apps/files_external/**'
|
||||
|
||||
env:
|
||||
APP_NAME: files_external
|
||||
|
||||
jobs:
|
||||
s3-external-tests-minio:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
# do not stop on another job's failure
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['7.4', '8.0']
|
||||
|
||||
name: php${{ matrix.php-versions }}-minio
|
||||
|
||||
services:
|
||||
minio:
|
||||
env:
|
||||
MINIO_ACCESS_KEY: minio
|
||||
MINIO_SECRET_KEY: minio123
|
||||
image: bitnami/minio:2021.10.6
|
||||
ports:
|
||||
- "9000:9000"
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.36.0
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
tools: phpunit:8.5.2
|
||||
extensions: mbstring, fileinfo, intl, sqlite, pdo_sqlite, zip, gd
|
||||
|
||||
- name: Set up Nextcloud
|
||||
run: |
|
||||
mkdir data
|
||||
./occ maintenance:install --verbose --database=sqlite --database-name=nextcloud --database-host=127.0.0.1 --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass password
|
||||
./occ app:enable --force ${{ env.APP_NAME }}
|
||||
php -S localhost:8080 &
|
||||
- name: PHPUnit
|
||||
run: |
|
||||
echo "<?php return ['run' => true,'hostname' => 'localhost','key' => 'minio','secret' => 'minio123', 'bucket' => 'bucket', 'port' => 9000, 'use_ssl' => false, 'autocreate' => true, 'use_path_style' => true];" > apps/${{ env.APP_NAME }}/tests/config.amazons3.php
|
||||
phpunit --configuration tests/phpunit-autotest-external.xml apps/files_external/tests/Storage/Amazons3Test.php
|
||||
phpunit --configuration tests/phpunit-autotest-external.xml apps/files_external/tests/Storage/VersionedAmazonS3Test.php
|
||||
- name: S3 logs
|
||||
if: always()
|
||||
run: |
|
||||
docker ps -a
|
||||
docker logs $(docker ps -aq)
|
||||
s3-external-tests-localstack:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
# do not stop on another job's failure
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['7.4', '8.0']
|
||||
|
||||
name: php${{ matrix.php-versions }}-localstack
|
||||
|
||||
services:
|
||||
minio:
|
||||
env:
|
||||
SERVICES: s3
|
||||
DEBUG: 1
|
||||
image: localstack/localstack:0.12.7
|
||||
ports:
|
||||
- "4566:4566"
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.36.0
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
tools: phpunit:8.5.2
|
||||
extensions: mbstring, fileinfo, intl, sqlite, pdo_sqlite, zip, gd
|
||||
|
||||
- name: Set up Nextcloud
|
||||
run: |
|
||||
mkdir data
|
||||
./occ maintenance:install --verbose --database=sqlite --database-name=nextcloud --database-host=127.0.0.1 --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass password
|
||||
./occ app:enable --force ${{ env.APP_NAME }}
|
||||
php -S localhost:8080 &
|
||||
- name: PHPUnit
|
||||
run: |
|
||||
echo "<?php return ['run' => true,'hostname' => 'localhost','key' => 'ignored','secret' => 'ignored', 'bucket' => 'bucket', 'port' => 4566, 'use_ssl' => false, 'autocreate' => true, 'use_path_style' => true];" > apps/${{ env.APP_NAME }}/tests/config.amazons3.php
|
||||
phpunit --configuration tests/phpunit-autotest-external.xml apps/files_external/tests/Storage/Amazons3Test.php
|
||||
phpunit --configuration tests/phpunit-autotest-external.xml apps/files_external/tests/Storage/VersionedAmazonS3Test.php
|
||||
- name: S3 logs
|
||||
if: always()
|
||||
run: |
|
||||
docker ps -a
|
||||
docker logs $(docker ps -aq)
|
||||
|
||||
s3-external-summary:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [s3-external-tests-minio, s3-external-tests-localstack]
|
||||
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.s3-external-tests-minio.result != 'success' }} || ${{ needs.s3-external-tests-localstack.result != 'success' }}; then exit 1; fi
|
||||
@@ -1,78 +0,0 @@
|
||||
name: Samba Kerberos SSO
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- stable*
|
||||
paths:
|
||||
- 'apps/files_external/**'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'apps/files_external/**'
|
||||
|
||||
jobs:
|
||||
smb-kerberos-tests:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['7.4', '8.0']
|
||||
|
||||
name: php${{ matrix.php-versions }}-${{ matrix.ftpd }}
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0
|
||||
with:
|
||||
submodules: true
|
||||
- name: Pull images
|
||||
run: |
|
||||
docker pull icewind1991/samba-krb-test-dc
|
||||
docker pull icewind1991/samba-krb-test-apache
|
||||
docker pull icewind1991/samba-krb-test-client
|
||||
- name: Setup AD-DC
|
||||
run: |
|
||||
mkdir data
|
||||
sudo chown -R 33 data apps config
|
||||
apps/files_external/tests/setup-krb.sh
|
||||
- name: Set up Nextcloud
|
||||
run: |
|
||||
docker exec --user 33 apache ./occ maintenance:install --verbose --database=sqlite --database-name=nextcloud --database-host=127.0.0.1 --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass password
|
||||
docker exec --user 33 apache ./occ config:system:set trusted_domains 1 --value 'httpd.domain.test'
|
||||
|
||||
# setup user_saml
|
||||
docker exec --user 33 apache ./occ app:enable user_saml --force
|
||||
docker exec --user 33 apache ./occ config:app:set user_saml type --value 'environment-variable'
|
||||
docker exec --user 33 apache ./occ config:app:set user_saml general-uid_mapping --value REMOTE_USER
|
||||
|
||||
# setup external storage
|
||||
docker exec --user 33 apache ./occ app:enable files_external --force
|
||||
docker exec --user 33 apache ./occ files_external:create smb smb smb::kerberosapache
|
||||
docker exec --user 33 apache ./occ files_external:config 1 host krb.domain.test
|
||||
docker exec --user 33 apache ./occ files_external:config 1 share netlogon
|
||||
docker exec --user 33 apache ./occ files_external:list
|
||||
- name: Test SSO
|
||||
run: |
|
||||
mkdir cookies
|
||||
chmod 0777 cookies
|
||||
|
||||
DC_IP=$(docker inspect dc --format '{{.NetworkSettings.IPAddress}}')
|
||||
docker run --rm --name client -v $PWD/cookies:/cookies -v /tmp/shared:/shared --dns $DC_IP --hostname client.domain.test icewind1991/samba-krb-test-client \
|
||||
curl -c /cookies/jar -s --negotiate -u testuser@DOMAIN.TEST: --delegation always http://httpd.domain.test/index.php/apps/user_saml/saml/login
|
||||
CONTENT=$(docker run --rm --name client -v $PWD/cookies:/cookies -v /tmp/shared:/shared --dns $DC_IP --hostname client.domain.test icewind1991/samba-krb-test-client \
|
||||
curl -b /cookies/jar -s --negotiate -u testuser@DOMAIN.TEST: --delegation always http://httpd.domain.test/remote.php/webdav/smb/test.txt)
|
||||
echo $CONTENT
|
||||
CONTENT=$(echo $CONTENT | tr -d '[:space:]')
|
||||
[[ $CONTENT == "testfile" ]]
|
||||
|
||||
|
||||
smb-kerberos-summary:
|
||||
runs-on: ubuntu-latest
|
||||
needs: smb-kerberos-tests
|
||||
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.smb-kerberos-tests.result != 'success' }}; then exit 1; fi
|
||||
@@ -1,56 +0,0 @@
|
||||
name: Static code analysis
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
static-code-analysis:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0
|
||||
- name: Checkout submodules
|
||||
shell: bash
|
||||
run: |
|
||||
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
|
||||
git submodule sync --recursive
|
||||
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
|
||||
- name: Set up php7.4
|
||||
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.36.0
|
||||
with:
|
||||
php-version: 7.4
|
||||
extensions: ctype,curl,dom,fileinfo,gd,intl,json,mbstring,openssl,pdo_sqlite,posix,sqlite,xml,zip
|
||||
coverage: none
|
||||
- name: Composer install
|
||||
run: composer i
|
||||
- name: Psalm
|
||||
run: composer run psalm -- --monochrome --no-progress --output-format=github --update-baseline || ( git diff -- . ':!lib/composer' && exit 1 )
|
||||
- name: Check diff
|
||||
run: git diff -- . ':!lib/composer'
|
||||
- name: Show potential changes in Psalm baseline
|
||||
run: |
|
||||
bash -c "[[ ! \"`git status --porcelain build/psalm-baseline.xml`\" ]] || ( echo 'Uncommited changes in Psalm baseline' && git status && git diff build/psalm-baseline.xml)"
|
||||
|
||||
static-code-analysis-ocp:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0
|
||||
- name: Checkout submodules
|
||||
shell: bash
|
||||
run: |
|
||||
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
|
||||
git submodule sync --recursive
|
||||
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
|
||||
- name: Set up php7.4
|
||||
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.36.0
|
||||
with:
|
||||
php-version: 7.4
|
||||
extensions: ctype,curl,dom,fileinfo,gd,intl,json,mbstring,openssl,pdo_sqlite,posix,sqlite,xml,zip
|
||||
coverage: none
|
||||
- name: Composer install
|
||||
run: composer i
|
||||
- name: Psalm
|
||||
run: composer run psalm -- -c psalm-ocp.xml --monochrome --no-progress --output-format=github --update-baseline || ( git diff -- . ':!lib/composer' && exit 1 )
|
||||
- name: Check diff
|
||||
run: git diff -- . ':!lib/composer'
|
||||
- name: Show potential changes in Psalm baseline
|
||||
run: |
|
||||
bash -c "[[ ! \"`git status --porcelain build/psalm-baseline-ocp.xml`\" ]] || ( echo 'Uncommited changes in Psalm baseline' && git status && git diff build/psalm-baseline.xml)"
|
||||
@@ -1,53 +0,0 @@
|
||||
name: Update Psalm baseline
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '5 4 * * *'
|
||||
|
||||
jobs:
|
||||
update-psalm-baseline:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Set up php7.4
|
||||
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.36.0
|
||||
with:
|
||||
php-version: 7.4
|
||||
extensions: ctype,curl,dom,fileinfo,gd,intl,json,mbstring,openssl,pdo_sqlite,posix,sqlite,xml,zip
|
||||
coverage: none
|
||||
|
||||
- name: Composer install
|
||||
run: composer install
|
||||
|
||||
- name: Psalm
|
||||
run: composer run psalm -- --monochrome --no-progress --output-format=text --update-baseline
|
||||
continue-on-error: true
|
||||
|
||||
- name: Reset composer
|
||||
run: |
|
||||
git clean -f lib/composer
|
||||
git checkout composer.json composer.lock lib/composer
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@18f7dc018cc2cd597073088f7c7591b9d1c02672 # v3.14.0
|
||||
with:
|
||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
commit-message: Update psalm baseline
|
||||
committer: GitHub <noreply@github.com>
|
||||
author: nextcloud-command <nextcloud-command@users.noreply.github.com>
|
||||
signoff: true
|
||||
branch: automated/noid/psalm-baseline-update
|
||||
# Make sure we can open multiple PRs
|
||||
branch-suffix: timestamp
|
||||
title: '[Automated] Update psalm-baseline.xml'
|
||||
body: |
|
||||
Auto-generated update psalm-baseline.xml with fixed psalm warnings
|
||||
labels: |
|
||||
automated pr
|
||||
3. to review
|
||||
team-reviewers: server-backend
|
||||
+7
-119
@@ -1,62 +1,9 @@
|
||||
# the default generated dir + db file
|
||||
/data
|
||||
/config/config.php
|
||||
/config/*.config.php
|
||||
/config/mimetype*.json
|
||||
/config/mount.php
|
||||
/apps/inc.php
|
||||
/assets
|
||||
/.htaccess
|
||||
/node_modules
|
||||
/translationfiles
|
||||
/translationtool.phar
|
||||
|
||||
# ignore all apps except core ones
|
||||
/apps*/*
|
||||
!/apps/accessibility
|
||||
!/apps/cloud_federation_api
|
||||
!/apps/comments
|
||||
!/apps/contactsinteraction
|
||||
!/apps/dashboard
|
||||
!/apps/dav
|
||||
!/apps/files
|
||||
!/apps/federation
|
||||
!/apps/federatedfilesharing
|
||||
!/apps/sharebymail
|
||||
!/apps/encryption
|
||||
!/apps/files_external
|
||||
!/apps/files_sharing
|
||||
!/apps/files_trashbin
|
||||
!/apps/files_versions
|
||||
!/apps/lookup_server_connector
|
||||
!/apps/user_ldap
|
||||
!/apps/oauth2
|
||||
!/apps/provisioning_api
|
||||
!/apps/settings
|
||||
!/apps/systemtags
|
||||
!/apps/testing
|
||||
!/apps/admin_audit
|
||||
!/apps/updatenotification
|
||||
!/apps/theming
|
||||
!/apps/twofactor_backupcodes
|
||||
!/apps/user_status
|
||||
!/apps/weather_status
|
||||
!/apps/workflowengine
|
||||
/apps/files_external/3rdparty/irodsphp/PHPUnitTest
|
||||
/apps/files_external/3rdparty/irodsphp/web
|
||||
/apps/files_external/3rdparty/irodsphp/prods/test
|
||||
/apps/files_external/3rdparty/irodsphp/prods/tutorials
|
||||
/apps/files_external/3rdparty/irodsphp/prods/test*
|
||||
/apps/files_external/tests/config.*.php
|
||||
|
||||
# apps modules
|
||||
/apps/*/node_modules
|
||||
|
||||
|
||||
# ignore themes except the example and the README
|
||||
/themes/*
|
||||
!/themes/example
|
||||
!/themes/README
|
||||
data
|
||||
owncloud
|
||||
config/config.php
|
||||
config/mount.php
|
||||
apps/inc.php
|
||||
|
||||
# just sane ignores
|
||||
.*.sw[po]
|
||||
@@ -72,13 +19,10 @@ _darcs/*
|
||||
CVS/*
|
||||
.svn/*
|
||||
RCS/*
|
||||
*.backup*
|
||||
.php_cs.cache
|
||||
|
||||
# kdevelop
|
||||
.kdev
|
||||
*.kdev4
|
||||
*.kate-swp
|
||||
|
||||
# Lokalize
|
||||
*lokalize*
|
||||
@@ -87,77 +31,21 @@ RCS/*
|
||||
.project
|
||||
.settings
|
||||
|
||||
# netbeans
|
||||
# netbeans
|
||||
nbproject
|
||||
|
||||
# phpStorm
|
||||
.idea
|
||||
*.iml
|
||||
|
||||
# vscode
|
||||
.vscode
|
||||
|
||||
# geany
|
||||
*.geany
|
||||
|
||||
# Cloud9IDE
|
||||
.settings.xml
|
||||
.c9revisions
|
||||
|
||||
# vim ex mode
|
||||
.vimrc
|
||||
|
||||
# ack(-grep)
|
||||
.ackrc
|
||||
|
||||
|
||||
# Mac OS
|
||||
.DS_Store
|
||||
|
||||
# WebFinger
|
||||
.well-known
|
||||
/.buildpath
|
||||
|
||||
# Tests
|
||||
/tests/phpunit.xml
|
||||
|
||||
# Node Modules
|
||||
/build/node_modules/
|
||||
|
||||
# nodejs
|
||||
/build/bin
|
||||
/build/lib/
|
||||
/build/jsdocs/
|
||||
/npm-debug.log
|
||||
/PhantomJS_*
|
||||
/build/package-lock.json
|
||||
|
||||
# puphpet
|
||||
puphpet
|
||||
|
||||
# vagrant
|
||||
.vagrant
|
||||
Vagrantfile
|
||||
|
||||
# Tests - auto-generated files
|
||||
/data-autotest
|
||||
/tests/.phpunit.result.cache
|
||||
/tests/coverage*
|
||||
/tests/css
|
||||
/tests/karma-coverage
|
||||
/tests/autoconfig*
|
||||
/tests/autotest*
|
||||
/tests/data/lorem-copy.txt
|
||||
/tests/data/testimage-copy.png
|
||||
/tests/ui-regression/out/
|
||||
/tests/ui-regression/node_modules/
|
||||
/tests/ui-regression/package-lock.json
|
||||
/config/config-autotest-backup.php
|
||||
/config/autoconfig.php
|
||||
clover.xml
|
||||
|
||||
# Tests - dependencies
|
||||
tests/acceptance/vendor/
|
||||
|
||||
composer.phar
|
||||
/lib/composer/bin
|
||||
/vendor-bin/**/vendor
|
||||
@@ -1,3 +0,0 @@
|
||||
[submodule "3rdparty"]
|
||||
path = 3rdparty
|
||||
url = https://github.com/nextcloud/3rdparty.git
|
||||
@@ -1,107 +1,22 @@
|
||||
<IfModule mod_headers.c>
|
||||
<IfModule mod_setenvif.c>
|
||||
<IfModule mod_fcgid.c>
|
||||
SetEnvIfNoCase ^Authorization$ "(.+)" XAUTHORIZATION=$1
|
||||
RequestHeader set XAuthorization %{XAUTHORIZATION}e env=XAUTHORIZATION
|
||||
</IfModule>
|
||||
<IfModule mod_proxy_fcgi.c>
|
||||
SetEnvIfNoCase Authorization "(.+)" HTTP_AUTHORIZATION=$1
|
||||
</IfModule>
|
||||
<IfModule mod_lsapi.c>
|
||||
SetEnvIfNoCase ^Authorization$ "(.+)" XAUTHORIZATION=$1
|
||||
RequestHeader set XAuthorization %{XAUTHORIZATION}e env=XAUTHORIZATION
|
||||
</IfModule>
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_env.c>
|
||||
# Add security and privacy related headers
|
||||
|
||||
# Avoid doubled headers by unsetting headers in "onsuccess" table,
|
||||
# then add headers to "always" table: https://github.com/nextcloud/server/pull/19002
|
||||
Header onsuccess unset Referrer-Policy
|
||||
Header always set Referrer-Policy "no-referrer"
|
||||
|
||||
Header onsuccess unset X-Content-Type-Options
|
||||
Header always set X-Content-Type-Options "nosniff"
|
||||
|
||||
Header onsuccess unset X-Download-Options
|
||||
Header always set X-Download-Options "noopen"
|
||||
|
||||
Header onsuccess unset X-Frame-Options
|
||||
Header always set X-Frame-Options "SAMEORIGIN"
|
||||
|
||||
Header onsuccess unset X-Permitted-Cross-Domain-Policies
|
||||
Header always set X-Permitted-Cross-Domain-Policies "none"
|
||||
|
||||
Header onsuccess unset X-Robots-Tag
|
||||
Header always set X-Robots-Tag "none"
|
||||
|
||||
Header onsuccess unset X-XSS-Protection
|
||||
Header always set X-XSS-Protection "1; mode=block"
|
||||
|
||||
SetEnv modHeadersAvailable true
|
||||
</IfModule>
|
||||
|
||||
# Add cache control for static resources
|
||||
<FilesMatch "\.(css|js|svg|gif|png|jpg|ico)$">
|
||||
Header set Cache-Control "max-age=15778463"
|
||||
</FilesMatch>
|
||||
|
||||
<FilesMatch "\.(css|js|svg|gif|png|jpg|ico|wasm|tflite)(\?v=.*)?$">
|
||||
Header set Cache-Control "max-age=15778463, immutable"
|
||||
</FilesMatch>
|
||||
|
||||
# Let browsers cache WOFF files for a week
|
||||
<FilesMatch "\.woff2?$">
|
||||
Header set Cache-Control "max-age=604800"
|
||||
</FilesMatch>
|
||||
ErrorDocument 403 /core/templates/403.php
|
||||
ErrorDocument 404 /core/templates/404.php
|
||||
<IfModule mod_php5.c>
|
||||
php_value upload_max_filesize 513M
|
||||
php_value post_max_size 513M
|
||||
php_value memory_limit 512M
|
||||
<IfModule env_module>
|
||||
SetEnv htaccessWorking true
|
||||
</IfModule>
|
||||
|
||||
# PHP 7.x
|
||||
<IfModule mod_php7.c>
|
||||
php_value mbstring.func_overload 0
|
||||
php_value default_charset 'UTF-8'
|
||||
php_value output_buffering 0
|
||||
<IfModule mod_env.c>
|
||||
SetEnv htaccessWorking true
|
||||
</IfModule>
|
||||
</IfModule>
|
||||
|
||||
# PHP 8+
|
||||
<IfModule mod_php.c>
|
||||
php_value mbstring.func_overload 0
|
||||
php_value default_charset 'UTF-8'
|
||||
php_value output_buffering 0
|
||||
<IfModule mod_env.c>
|
||||
SetEnv htaccessWorking true
|
||||
</IfModule>
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_mime.c>
|
||||
AddType image/svg+xml svg svgz
|
||||
AddEncoding gzip svgz
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_dir.c>
|
||||
DirectoryIndex index.php index.html
|
||||
</IfModule>
|
||||
|
||||
<IfModule pagespeed_module>
|
||||
ModPagespeed Off
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine on
|
||||
RewriteCond %{HTTP_USER_AGENT} DavClnt
|
||||
RewriteRule ^$ /remote.php/webdav/ [L,R=302]
|
||||
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
||||
RewriteRule ^\.well-known/carddav /remote.php/dav/ [R=301,L]
|
||||
RewriteRule ^\.well-known/caldav /remote.php/dav/ [R=301,L]
|
||||
RewriteRule ^remote/(.*) remote.php [QSA,L]
|
||||
RewriteRule ^(?:build|tests|config|lib|3rdparty|templates)/.* - [R=404,L]
|
||||
RewriteRule ^\.well-known/(?!acme-challenge|pki-validation) /index.php [QSA,L]
|
||||
RewriteRule ^(?:\.(?!well-known)|autotest|occ|issue|indie|db_|console).* - [R=404,L]
|
||||
RewriteEngine on
|
||||
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
||||
RewriteRule ^.well-known/host-meta /public.php?service=host-meta [QSA,L]
|
||||
RewriteRule ^.well-known/carddav /remote.php/carddav/ [R]
|
||||
RewriteRule ^.well-known/caldav /remote.php/caldav/ [R]
|
||||
RewriteRule ^apps/calendar/caldav.php remote.php/caldav/ [QSA,L]
|
||||
RewriteRule ^apps/contacts/carddav.php remote.php/carddav/ [QSA,L]
|
||||
RewriteRule ^apps/([^/]*)/(.*\.(css|php))$ index.php?app=$1&getfile=$2 [QSA,L]
|
||||
RewriteRule ^remote/(.*) remote.php [QSA,L]
|
||||
</IfModule>
|
||||
|
||||
AddDefaultCharset utf-8
|
||||
Options -Indexes
|
||||
|
||||
Generated
-52
@@ -1,52 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectCodeStyleSettingsManager">
|
||||
<option name="PER_PROJECT_SETTINGS">
|
||||
<value>
|
||||
<option name="RIGHT_MARGIN" value="80" />
|
||||
<PHPCodeStyleSettings>
|
||||
<option name="PHPDOC_BLANK_LINE_BEFORE_TAGS" value="true" />
|
||||
<option name="LOWER_CASE_BOOLEAN_CONST" value="true" />
|
||||
<option name="LOWER_CASE_NULL_CONST" value="true" />
|
||||
</PHPCodeStyleSettings>
|
||||
<XML>
|
||||
<option name="XML_KEEP_BLANK_LINES" value="1" />
|
||||
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
|
||||
</XML>
|
||||
<codeStyleSettings language="CSS">
|
||||
<indentOptions>
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="HTML">
|
||||
<indentOptions>
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="JavaScript">
|
||||
<option name="SPACE_BEFORE_METHOD_PARENTHESES" value="true" />
|
||||
<indentOptions>
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="PHP">
|
||||
<option name="CLASS_BRACE_STYLE" value="1" />
|
||||
<option name="METHOD_BRACE_STYLE" value="1" />
|
||||
<option name="DOWHILE_BRACE_FORCE" value="3" />
|
||||
<option name="WHILE_BRACE_FORCE" value="3" />
|
||||
<option name="FOR_BRACE_FORCE" value="3" />
|
||||
<indentOptions>
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="XML">
|
||||
<indentOptions>
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
</value>
|
||||
</option>
|
||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||
</component>
|
||||
</project>
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
{
|
||||
"camelcase": true,
|
||||
"eqeqeq": true,
|
||||
"immed": true,
|
||||
"latedef": false,
|
||||
"noarg": true,
|
||||
"nonbsp": true,
|
||||
"undef": true,
|
||||
"unused": true,
|
||||
"trailing": true,
|
||||
"maxparams": 5,
|
||||
"curly": true,
|
||||
"jquery": true,
|
||||
"maxlen": 120,
|
||||
"indent": 4,
|
||||
"browser": true,
|
||||
"laxbreak": true,
|
||||
"globals": {
|
||||
"console": true,
|
||||
"it": true,
|
||||
"xit": true,
|
||||
"expect": true,
|
||||
"describe": true,
|
||||
"beforeEach": true,
|
||||
"afterEach": true,
|
||||
"sinon": true,
|
||||
"fakeServer": true,
|
||||
"_": true,
|
||||
"OC": true,
|
||||
"OCA": true,
|
||||
"OCP": true,
|
||||
"t": true,
|
||||
"n": true,
|
||||
"escapeHTML": true,
|
||||
"Promise": true
|
||||
}
|
||||
}
|
||||
@@ -1,431 +0,0 @@
|
||||
Aamir Khan <ak4u2009@gmail.com>
|
||||
Aaron Reichman <areichman.kde@gmail.com>
|
||||
Adam Williamson <awilliam@redhat.com>
|
||||
Aditya Patawari <adimania@gmail.com>
|
||||
Administrator <Administrator@WINDOWS-2012>
|
||||
adrien <adrien.waksberg@believedigital.com>
|
||||
Aldo "xoen" Giambelluca <xoen@xoen.org>
|
||||
Alessandro Cosentino <cosenal@gmail.com>
|
||||
Alexander Bergolth <leo@strike.wu.ac.at> root <leo@strike.wu.ac.at>
|
||||
Alexander Bogdanov <syn@li.ru>
|
||||
Alexander Wigen <alex@wigen.net>
|
||||
Aloisio Almeida Jr <aloisio.almeida@openbossa.org>
|
||||
Anders Nor Berle <anders@berle.cc>
|
||||
Andreas Fischer <bantu@owncloud.com>
|
||||
Andreas Schönebeck <aschoenebeck@web.de>
|
||||
Andreas Ergenzinger <andreas.ergenzinger@gmx.de> AndreasErgenzinger <andreas.ergenzinger@gmx.de>
|
||||
Andrew Brown <andrew@casabrown.com>
|
||||
André Gaul <gaul@web-yard.de>
|
||||
Arthur Schiwon <blizzz@arthur-schiwon.de> Arthur Schiwon <blizzz@owncloud.com>
|
||||
Arthur Schiwon <blizzz@arthur-schiwon.de> blizzz <blizzz@owncloud.com>
|
||||
Artur Duque de Souza <asouza@kde.org>
|
||||
Axel Roenn <axel@mpim-bonn.mpg.de>
|
||||
Bagera <victor@baquero-wihlborg.se>
|
||||
Bart Visscher <bartv@thisnet.nl> Bart Visscher <bart@thisnet.nl>
|
||||
Bart Visscher <bartv@thisnet.nl> Bart Visscher <github@thisnet.nl>
|
||||
Bartek Przybylski <bart.p.pl@gmail.com>
|
||||
Bastien Ho <bastienho@urbancube.fr>
|
||||
ben-denham <bend@catalyst.net.nz>
|
||||
Benjamin Diele <benjamin@diele.be>
|
||||
Benjamin Liles <benliles@arch.tamu.edu>
|
||||
Bernhard Posselt <dev@bernhard-posselt.com> Bernhard Posselt <nukeawhale@gmail.com>
|
||||
Bernhard Posselt <dev@bernhard-posselt.com> Bernhard Posselt <Raydiation@users.noreply.github.com>
|
||||
Bernhard Posselt <dev@bernhard-posselt.com> Bernhard Posselt <BernhardPosselt@users.noreply.github.com>
|
||||
Bernhard Reiter <ockham@raz.or.at>
|
||||
Birk Borkason <daniel.niccoli@gmail.com>
|
||||
Björn Schießle <bjoern@schiessle.org> Bjoern Schiessle <schiesbn@woody.(none)>
|
||||
Björn Schießle <bjoern@schiessle.org> Björn Schießle <schiessle@owncloud.com>
|
||||
Björn Schießle <bjoern@schiessle.org> Björn Schießle <schiesbn@potato.(none)>
|
||||
Björn Schießle <bjoern@schiessle.org> Björn Schiessle <schiessle@owncloud.com>
|
||||
Björn Schießle <bjoern@schiessle.org> Bjoern Schießle <schiessle@owncloud.com>
|
||||
Björn Schießle <bjoern@schiessle.org> Bjoern Schiessle <schiessle@owncloud.com>
|
||||
Björn Schießle <bjoern@schiessle.org> Björn Schießle <schiessle@owncloud.com>
|
||||
BlackEagle <ike.devolder@gmail.com>
|
||||
Boris Rybalkin <ribalkin@gmail.com>
|
||||
Borjan Tchakaloff <borjan@tchakaloff.fr>
|
||||
Brice Maron <brice@bmaron.net>
|
||||
brumsel <brumsel@losecatcher.de> brumsoel <brumsel@losecatcher.de>
|
||||
Byron Marohn <combustible@live.com> eMerzh <brice@bmaron.net>
|
||||
Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org>
|
||||
Carla Schroder <carla@owncloud.com>
|
||||
Carlos Cerrillo <ccerrillo@gmail.com>
|
||||
cbhp <cbhp@users.noreply.github.com>
|
||||
cbojar <chris@cbojar.net>
|
||||
Ceri Davies <ceri@submonkey.net>
|
||||
cetra3 <peter@parashift.com.au>
|
||||
Charles-Edouard Coste <contact@ccoste.fr>
|
||||
CharlyCoste <contact@ccoste.fr>
|
||||
chli1 <chli1@users.noreply.github.com>
|
||||
Chris Kankiewicz <Chris@ChrisKankiewicz.com>
|
||||
Chris LeBlanc <chris@leblaaanc.com>
|
||||
Chris Wilson <chris+github@qwirx.com>
|
||||
Christian Berendt <berendt@b1-systems.de>
|
||||
Christian Kampka <christian@kampka.net>
|
||||
Christian Koch <koch.chris@gmail.com>
|
||||
Christian Reiner <github@christian-reiner.info> Christian Reiner <arkascha@balder.site>
|
||||
Christoph Wurst <christoph@winzerhof-wurst.at> Christoph Wurst <ChristophWurst@users.noreply.github.com>
|
||||
Christoph Wurst <christoph@winzerhof-wurst.at> Christoph Wurst <christoph@owncloud.com>
|
||||
Christopher Bunn <b11.chris@gmail.com>
|
||||
Christopher Schäpers <kondou@ts.unde.re> Christopher <kondou@ts.unde.re>
|
||||
Christopher Schäpers <kondou@ts.unde.re> kondou <kondou@ts.unde.re>
|
||||
Christopher Schäpers <kondou@ts.unde.re> root <kondou@ts.unde.re>
|
||||
Christopher T. Johnson <ctjctj@gmail.com>
|
||||
Clark Tomlinson <fallen013@gmail.com>
|
||||
Cloud Dumper <clouddumper@gmail.com>
|
||||
cmeh <cmeh@users.noreply.github.com>
|
||||
Cornelius Schumacher <schumacher@kde.org>
|
||||
Craig Morrissey <craig@owncloud.com>
|
||||
Côme BERNIGAUD <come.bernigaud@laposte.net>
|
||||
dampfklon <me@dampfklon.de>
|
||||
Dan Bartram <daneybartram@gmail.com>
|
||||
Dan Callahan <dan.callahan@gmail.com>
|
||||
Dan Jones <dan@danneh.org>
|
||||
Daniel <daniel@mars.(none)>
|
||||
Daniel Hansson <enoch85@gmail.com>
|
||||
Daniel Köb <daniel.koeb@peony.at>
|
||||
Daniel Molkentin <daniel@molkentin.de>
|
||||
Daniele E. Domenichelli <daniele.domenichelli@gmail.com>
|
||||
David <davidventura>
|
||||
David Iwanowitsch <david+git@unclouded.de> David Iwanowitsch <diw@gmx.de>
|
||||
David Prévot <taffit@debian.org>
|
||||
David Reagan <reagand@lanecc.edu>
|
||||
davidak <davidak@gmx.de>
|
||||
davidgumberg <davidnoizgumberg@gmail.com>
|
||||
Dawid Opis <ncore@ncore.com.pl>
|
||||
Deepak Mittal <dpac.mittal2@gmail.com>
|
||||
DeLtAfOx <edo@ravers.it>
|
||||
denis-b <denis.bonnenfant@diderot.org>
|
||||
Der-Jan <de@r-jan.de>
|
||||
derkostka <sebastian.kostka@gmail.com>
|
||||
Diederik de Haas <diederik@cknow.org>
|
||||
Dominik Schmidt <dev@dominik-schmidt.de>
|
||||
Donald Buczek <buczek@molgen.mpg.de>
|
||||
Donquixote <marjunebatac@gmail.com> Donquixote <marjunebatac@gmailcom>
|
||||
Doug Neiner <doug@pixelgraphics.us>
|
||||
drarko <drarko@users.noreply.github.com>
|
||||
dratini0 <dratini0@gmail.com>
|
||||
Duane Johnson <duane.johnson@gmail.com>
|
||||
eduardo <eduardo@vnexu.net>
|
||||
elchi <niklas1b@yahoo.de>
|
||||
Elias Probst <mail@eliasprobst.eu>
|
||||
Florian <ente@baer.rwth-aachen.de> ente <ente@baer.rwth-aachen.de>
|
||||
Erik Sargent <esthepiking@gmail.com>
|
||||
Evgeni Golov <evgeni@golov.de>
|
||||
fabian <fabian@web2.0-apps.de>
|
||||
Fabian Henze <flyser42@gmx.de>
|
||||
Felix Böhm <felixboehm@gmx.de> felixboehm <felixboehm@gmx.de>
|
||||
Felix Eckhofer <felix@eckhofer.com>
|
||||
Felix Moeller <mail@felixmoeller.de>
|
||||
Felix Niklas <mrflix@gmail.com>
|
||||
Fernando Rodriguez Sela <frsela@tid.es>
|
||||
fibsifan <fi@volans.uberspace.de>
|
||||
Florian Hülsmann <fh@cbix.de>
|
||||
Florian Jacob <fjacob@lavabit.com>
|
||||
Florian Preinstorfer <nblock@archlinux.us>
|
||||
Florian Pritz <bluewind@xinu.at>
|
||||
Florian Scholz <FlorianScholz@bgstyle.de> Florian Scholz <work@bgstyle.de>
|
||||
Florian Vichot <florian.vichot@gmail.com>
|
||||
Florin Peter <github@florin-peter.de> Florin Peter <fp@datawerk.de>
|
||||
Florin Peter <github@florin-peter.de> FlorinPeter <github@florin-peter.de>
|
||||
Francesco Piraneo G. <fpiraneo@iface.ch>
|
||||
Frank Karlitschek <frank@karlitschek.de> Frank Karlitschek <frank@dev.(none)>
|
||||
Frank Karlitschek <frank@karlitschek.de> Frank Karlitschek <frank@devel.(none)>
|
||||
Frank Karlitschek <frank@karlitschek.de> Frank Karlitschek <frank@oc.(none)>
|
||||
Frank Karlitschek <frank@karlitschek.de> Frank Karlitschek <frank@owncloud.org>
|
||||
Frank Karlitschek <frank@karlitschek.de> Frank Karlitschek <karlitschek@kde.org>
|
||||
François Kubler <francois@kubler.org>
|
||||
Frédéric Fortier <frederic.fortier@oronospolytechnique.com> Frédéric Fortier <frederic.fortier@polymtl.ca>
|
||||
Frederik Gladhorn <gladhorn@kde.org>
|
||||
Gadzy <dev@gadzy.fr>
|
||||
ganomi <ganomi@gmail.com>
|
||||
Gaël Beaudoin <gaboo@home.gaboo.org>
|
||||
geez0x1 <geez0x1@users.noreply.github.com>
|
||||
gekmihesg <markus@gekmihesg.de>
|
||||
Georg Ehrke <oc.list@georgehrke.com> Georg Ehrke <dev@georgswebsite.de>
|
||||
Georg Ehrke <oc.list@georgehrke.com> Georg Ehrke <developer@georgehrke.com>
|
||||
Georg Ehrke <oc.list@georgehrke.com> Georg Ehrke <georg.stefan.germany@googlemail.com>
|
||||
Georg Ehrke <oc.list@georgehrke.com> Georg Ehrke <ownclouddev@georgswebsite.de>
|
||||
Georg Ehrke <oc.list@georgehrke.com> Georg Ehrke <devgeorg@ownCloud.com>
|
||||
Georg Ehrke <oc.list@georgehrke.com> Georg Ehrke <georg@ownCloud.com>
|
||||
Georg Ehrke <oc.list@georgehrke.com> Georg Ehrke <georg@owncloud.com>
|
||||
Golnaz Nilieh <g382nilieh@gmail.com>
|
||||
Grundik <grundik@ololo.cc>
|
||||
Guillaume AMAT <guillaume.amat@informatique-libre.com>
|
||||
Hans Bakker <hansmbakker@gmail.com>
|
||||
helix84 <helix84@centrum.sk>
|
||||
Hendrik Langer <hendrik.langer@gmx.de>
|
||||
Henning Becker <h.becker@oedenstockach.de>
|
||||
Henning Oschwald <h.oschwald@gmx.de>
|
||||
Henrik Kjölhede <hkjolhede@gmail.com>
|
||||
herbrechtsmeier <stefan@herbrechtsmeier.net>
|
||||
hkjolhede <hkjolhede@gmail.com>
|
||||
IchEben <andreas@reichster.de>
|
||||
ideaship <ideaship@users.noreply.github.com>
|
||||
Ignacio Daniel Rostagno <ignaciorostagno@vijona.com.ar>
|
||||
infoneo <infoneo@yahoo.pl>
|
||||
Insanemal <insanemal@gmail.com>
|
||||
Tobias Perschon <tobias@perschon.at> Tobias Perschon <tofuSCHNITZEL@users.noreply.github.com>
|
||||
Tobias Ramforth <tobias@ramforth.com> Tobias Ramforth <tobias.ramforth@udo.edu>
|
||||
Tobias Ramforth <tobias@ramforth.com> irgsmirx <tobias.ramforth@udo.edu>
|
||||
Isaac Rosenberg <irosenb7@gmail.com>
|
||||
itheiss <ingo.theiss@i-matrixx.de>
|
||||
j-ed <juergen@eisfair.org>
|
||||
Jake Wilson <jakew@huebnerpetersen.com>
|
||||
Jakob Sack <mail@jakobsack.de> Jakob Sack <kde@jakobsack.de>
|
||||
jamesryanbell <james@james-bell.co.uk>
|
||||
Jamie McClelland <jm@mayfirst.org>
|
||||
Jan-Christoph Borchardt <hey@jancborchardt.net> Jan-Christoph Borchardt <jan@unhosted.org>
|
||||
Jan-Christoph Borchardt <hey@jancborchardt.net> Jan-Christoph Borchardt <JanCBorchardt@fsfe.org>
|
||||
jbtbnl <jbtbnl@users.noreply.github.com>
|
||||
Jean-Louis Dupond <jean-louis@dupond.be>
|
||||
Jenkins for ownCloud <owncloud-bot@tmit.eu> Jenkins for ownCloud <thomas.mueller@tmit.eu>
|
||||
Jens-Christian Fischer <jens-christian.fischer@switch.ch>
|
||||
Jernej Virag <jernej.virag@gmail.com>
|
||||
Jesus Macias Portela <jesus.macias.portela@gmail.com>
|
||||
Jesús Macias <jmacias@solidgear.es> Jesus Macias <jmacias@full-on-net.com>
|
||||
jknockaert <jasper@knockaert.nl>
|
||||
Joan <aseques@gmail.com>
|
||||
Joar Wandborg <git@wandborg.com>
|
||||
Joas Schilling <coding@schilljs.com> Joas Schilling <213943+nickvergessen@users.noreply.github.com>
|
||||
Joas Schilling <coding@schilljs.com> Joas Schilling <nickvergessen@gmx.de>
|
||||
Joas Schilling <coding@schilljs.com> Joas Schilling <nickvergessen@owncloud.com>
|
||||
joel hansson <joel.hansson@gmail.com>
|
||||
Johan Björk <johanimon@gmail.com>
|
||||
Johannes Twittmann <github.com@deryo.de>
|
||||
Johannes Willnecker <johannes@willnecker.com>
|
||||
John Kristensen <John.Kristensen@dpipwe.tas.gov.au>
|
||||
Jonathan Riddell <jriddell@ubuntu.com>
|
||||
Jonny007-MKD <1-23-4-5@web.de>
|
||||
josh4trunks <joshruehlig@gmail.com>
|
||||
Joshua Medeiros <Jammerx2@gmail.com>
|
||||
Juan Carlos Cornejo <jc2@paintblack.com>
|
||||
Julian Müller <julian.mueller.ffb@kabelmail.de>
|
||||
Jörn Friedrich Dreyer <jfd@butonic.de> jfd <jfd@lance>
|
||||
Jörn Friedrich Dreyer <jfd@butonic.de> jfd <jfd@underverse>
|
||||
Kamil Domanski <kdomanski@kdemail.net>
|
||||
Kees Huiberts <snowy@derideal.com>
|
||||
Klaas Freitag <freitag@owncloud.com> Klaas Freitag <freitag@suse.de>
|
||||
Konstantin Popov <konstantin.popov@globalpointagency.comv> Konstantin.Popov <konstantin.popov@globalpointagency.comv>
|
||||
krzaczek <pawel@freshmind.pl>
|
||||
Kshitij Parajuli <kshitijparajuli@gmail.com>
|
||||
Kunal Ghosh <kunal.t2@gmail.com>
|
||||
Tobia De Koninck <tobia@ledfan.be> LEDfan <tobia@ledfan.be>
|
||||
Lennart Rosam <lennart.rosam@medien-systempartner.de>
|
||||
Sebastian Döll <sebastian.doell@libasys.de> libasys <sebastian.doell@libasys.de>
|
||||
Lode Hoste <zillode@zillode.be>
|
||||
lolozere <laurent@chedanne.pro>
|
||||
Lorenzo M. Catucci <lorenzo@sancho.ccd.uniroma2.it>
|
||||
Lukas Reschke <lukas@statuscode.ch> Lukas Reschke <lukas@owncloud.com>
|
||||
Lukas Reschke <lukas@statuscode.ch> Lukas Reschke <lukas@owncloud.org>
|
||||
Luke Policinski <lpolicinski@gmail.com>
|
||||
Lyonel Vincent <lyonel@ezix.org>
|
||||
macjohnny <estebanmarin@gmx.ch>
|
||||
maelzx <maelzx@gmail.com>
|
||||
marc0s <marcos@tenak.net>
|
||||
Marco B <beinbrech@solutica.de>
|
||||
Marco Michelino <michelinux@gmail.com>
|
||||
Markus Goetz <markus@woboq.com>
|
||||
Markus Kalkbrenner <markus.kalkbrenner@bio.logis.de>
|
||||
Martial Saunois <saunois.martial@gmail.com>
|
||||
Martin Mattel <martin.mattel@diemattels.at> Martin <martin.mattel@diemattels.at>
|
||||
Martin Mattel <martin.mattel@diemattels.at> root <martin.mattel@diemattels.at>
|
||||
Martin Grohmann <martin@medi-inf.org>
|
||||
# TODO: the same person
|
||||
Martin Konrad <info@martin-konrad.net>
|
||||
Martin Konrad <konrad@frib.msu.edu>
|
||||
Martin Sandsmark <martin.sandsmark@kde.org> Martin T. H. Sandsmark <sandsmark@samfundet.no>
|
||||
Marvin Thomas Rabe <mrabe@marvinrabe.de> Marvin Thomas Rabe <m.rabe@echtzeitraum.de>
|
||||
Masaki Kawabata Neto <masaki.kawabata@gmail.com> Masaki <masaki.kawabata@gmail.com>
|
||||
Mat Lipe <mat@lipeimagination.info>
|
||||
Matthew Caron <matt@mattcaron.net>
|
||||
Matthew Dawson <matthew@mjdsystems.ca>
|
||||
Matthias Rieber <matthias@zu-con.org>
|
||||
Maximilian Ruta <mr@xtain.net>
|
||||
mh <mh@immerda.ch>
|
||||
Michael Gapczynski <GapczynskiM@gmail.com> Michael Gapczynski <mtgap@owncloud.com>
|
||||
Michael Göhler <somebody.here@gmx.de>
|
||||
Michael Kent <mike@draftx.net>
|
||||
Michael Kuhn <suraia@ikkoku.de>
|
||||
Michael Monreal <michael.monreal@gmail.com>
|
||||
Michael Roitzsch <reactorcontrol@icloud.com>
|
||||
michag86 <micha_g@arcor.de>
|
||||
Michiel de Jong <michiel@unhosted.org> Michiel@unhosted <michiel@unhosted.org>
|
||||
Miguel Prokop <miguel.prokop@vtu.com>
|
||||
miicha <pfitzner@physik.hu-berlin.de>
|
||||
Miquel Rodríguez Telep / Michael Rodríguez-Torrent <miquel@designunbound.co.uk>
|
||||
Morris Jobke <hey@morrisjobke.de> Morris Jobke <morris.jobke@gmail.com>
|
||||
MTRichards <matt@owncloud.com>
|
||||
mvn23 <schopdiedwaas@gmail.com>
|
||||
Myles McNamara <myles@hostt.net> Myles McNamara <myles@smyl.es>
|
||||
NARUKAWA Hiroki <nhirokinet@nhiroki.net>
|
||||
Nathan Dauber <nathan@radialogica.com>
|
||||
Nazar Mokrynskyi <nazar@mokrynskyi.com>
|
||||
nhirokinet <nhirokinet@nhiroki.net>
|
||||
Nico Kaiser <nico.kaiser@boerse-go.de>
|
||||
Nicolai Ehemann <en@enlightened.de>
|
||||
Nicolas Stamm <nicolas.stamm@gmail.com>
|
||||
NIEK Antoine <antoineniek@gmail.com>
|
||||
Niklas Sombert <niklas1b@yahoo.de>
|
||||
Nils Jansen <nilsjansen@gmail.com>
|
||||
nishiki <nishiki@yaegashi.fr>
|
||||
Nmz <nemesiz@nmz.lt>
|
||||
Normal Ra <normalraw@gmail.com> Normal Ra <NormalRa@users.noreply.github.com>
|
||||
Oliver Gasser <oliver.gasser@gmail.com> Oliver Gasser <oliver@flowriver.net>
|
||||
Oliver Kohl D.Sc. <oliver@kohl.bz>
|
||||
Olivier Paroz <github@oparoz.com> Olivier Paroz <oparoz@users.noreply.github.com>
|
||||
Olivier Tétard <olivier.tetard@miskin.fr>
|
||||
Aaron Larisch <aaron.larisch@gmx.de> OpenLarry <aaron.larisch@gmx.de>
|
||||
opensaucesystems <ashley@opensaucesystems.com>
|
||||
Oskar Hollmann <oskarhollmann@gmail.com>
|
||||
Otto Sabart <ottosabart@seberm.com>
|
||||
Owen Winkler <a_github@midnightcircus.com> Owen Winkler <epithet@gmail.com>
|
||||
Owen Winkler <a_github@midnightcircus.com> ringmaster <epithet@gmail.com>
|
||||
Pascal de Bruijn <pmjdebruijn@pcode.nl>
|
||||
Patrick Paysant <ppaysant@linagora.com>
|
||||
Patrick Stricker <stricker@hera.dev.iks-hagen.de>
|
||||
Paul Brown <paul90brown@gmail.com>
|
||||
pdessauw <pdessauw@gmail.com>
|
||||
Pellaeon Lin <nfsmwlin@gmail.com>
|
||||
Pete McFarlane <peterjohnmcfarlane@gmail.com> petemcfarlane <peterjohnmcfarlane@gmail.com>
|
||||
Philipp Kapfer <philipp.kapfer@gmx.at>
|
||||
Philipp Knechtges <philipp-dev@knechtges.com>
|
||||
Philipp Roggan <philipp.roggan@newsletter4free.de>
|
||||
Philipp Schmitt <philipp@schmitt.co>
|
||||
Philippe Jung <phil.jung@free.fr>
|
||||
Philippe Kueck <pk@plusline.de>
|
||||
prcrst <prcrst@hush.com>
|
||||
pzy <pzy@d1sturbed.org>
|
||||
Qingping Hou <dave2008713@gmail.com>
|
||||
Raghu Nayyar <me@iraghu.com> Raghu Nayyar <raghu.nayyar.007@gmail.com>
|
||||
Raghu Nayyar <me@iraghu.com> raghunayyar <me@iraghu.com>
|
||||
Raimund Schlüßler <raimund.schluessler@googlemail.com>
|
||||
Ramiro Aparicio <rapariciog@gmail.com>
|
||||
Randolph Carter <RandolphCarter@fantasymail.de>
|
||||
RealRancor <Fisch.666@gmx.de>
|
||||
Remco Brenninkmeijer <requist1@starmail.nl>
|
||||
Riccardo Iaconelli <riccardo@kde.org>
|
||||
Richard Clarkson <robert@trash-mail.com>
|
||||
rnveach <rveach02@gmail.com>
|
||||
Robert Jäckel <rjaeckel@users.noreply.github.com>
|
||||
Robin Appelman <robin@icewind.nl> icewind1991 <icewind1991@gmail.com>
|
||||
Robin Appelman <robin@icewind.nl> icewind1991 <robin@icewind.nl>
|
||||
Robin Appelman <robin@icewind.nl> Robin <Robin Appelman icewind1991@gmail.com>
|
||||
Robin Appelman <robin@icewind.nl> Robin <robin@Amaya.(none)>
|
||||
Robin Appelman <robin@icewind.nl> Robin Appelman <icewind1991@gmail.com>
|
||||
Robin Appelman <robin@icewind.nl> Robin Appelman <icewind1991@gmail>
|
||||
Robin Appelman <robin@icewind.nl> Robin Appelman <icewind@owncloud.com>
|
||||
Robin McCorkell <robin@mccorkell.me.uk> Robin McCorkell <rmccorkell@karoshi.org.uk>
|
||||
Robin McCorkell <robin@mccorkell.me.uk> Robin McCorkell <rmccorkell@owncloud.com>
|
||||
Rodrigo Hjort <rodrigo.hjort@gmail.com>
|
||||
Roeland Jago Douma <roeland@famdouma.nl> Roeland Jago Douma <rullzer@owncloud.com>
|
||||
Roeland Jago Douma <roeland@famdouma.nl> Roeland Douma <rullzer@users.noreply.github.com>
|
||||
Roeland Jago Douma <roeland@famdouma.nl> Roeland Jago Douma <rullzer@users.noreply.github.com>
|
||||
Roger Szabo <roger.szabo@web.de> root <roger.szabo@web.de>
|
||||
rok <brejktru@gmail.com>
|
||||
Roland Hager <roland.hager@tu-berlin.de>
|
||||
Roland van Laar <roland@micite.net>
|
||||
rolandgeider <roland@geider.net>
|
||||
Roman Geber <rgeber@owncloudapps.com>
|
||||
root <root@asterisk03.ceschia.de>
|
||||
root <root@dev.(none)>
|
||||
root <root@oc.(none)>
|
||||
root <root@plug.(none)>
|
||||
Ross Nicoll <jrn@jrn.me.uk>
|
||||
runky <philipp.boersteken@googlemail.com>
|
||||
Sam Tuke <mail@samtuke.com> Sam Tuke <sam@donttravelempty.com>
|
||||
Sam Tuke <mail@samtuke.com> Sam Tuke <samtuke@jack-laptop.(none)>
|
||||
Sam Tuke <mail@samtuke.com> Sam Tuke <samtuke@owncloud.com>
|
||||
Sander <brantje@gmail.com>
|
||||
Sandro Knauß <bugs@sandroknauss.de> Sandro <hefee@taurin.(none)>
|
||||
Sascha Schmidt <realriot@realriot.de>
|
||||
Sascha Schneider <development@suntsu.org>
|
||||
Sascha Wiswedel <sascha.wiswedel@nextcloud.com> Sascha Wiswedel <wiswedel@users.noreply.github.com>
|
||||
scambra <sergio@entrecables.com>
|
||||
scolebrook <scolebrook@mac.com>
|
||||
Scott Arciszewski <scott@arciszewski.me>
|
||||
Scott Barnett <scott.n.barnett@gmail.com>
|
||||
Scott Shambarger <gitorious@shambarger.net>
|
||||
Scrutinizer Auto-Fixer <auto-fixer@scrutinizer-ci.com>
|
||||
Sean Comeau <sean@ftlnetworks.ca>
|
||||
Sean Leonard <meanderingcode@silverleafstudios.net>
|
||||
Sebastian Bolt <sebastian.bolt@gmx.de>
|
||||
Serge Martin <edb@sigluy.net>
|
||||
Sergei Shuykov <n1nj4p0w3r@gmail.com>
|
||||
Sergi Almacellas Abellana <sergi@koolpi.com>
|
||||
sherbrecher <oss@herbrecher.de>
|
||||
shkdee <louis.traynard@m4x.org>
|
||||
Simon Birnbach <simon@simon-birnbach.de>
|
||||
Simon Könnecke <simonkoennecke@gmail.com>
|
||||
Simon Whittaker <simon@swbh.net>
|
||||
Sjors van der Pluijm <sjors@desjors.nl> Sjors van der Pluijm <sjors@youngguns.nl>
|
||||
John Molakvoæ <skjnldsv@protonmail.com> John Molakvoæ <skjnldsv@users.noreply.github.com>
|
||||
John Molakvoæ <skjnldsv@protonmail.com> John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
|
||||
st3so <st3so@server.fake>
|
||||
Stefan <mu.stefan@googlemail.com>
|
||||
Stefan Göckeritz <admin@s-goecker.de>
|
||||
Stefan Herbrechtsmeier <stefan@herbrechtsmeier.net>
|
||||
Stefan Rado <owncloud@sradonia.net>
|
||||
Stefan Seidel <android@stefanseidel.info>
|
||||
Steffen Lindner <mail@steffen-lindner.de> Steffen Lindner <gomez@flexiabel.de>
|
||||
Stephan Arts <stephan@xfce.org>
|
||||
Stephan Bergemann <st.bergemann@htw-berlin.de>
|
||||
Stephan Peijnik <speijnik@anexia-it.com>
|
||||
Stephane Martin <stef.martin@gmail.com> Stephane Martin <stephane.martin@vesperal.eu>
|
||||
Stephane V <stephane@vergeylen.eu>
|
||||
Stephen Rees-Carter <stephen@rees-carter.net>
|
||||
Steven <wokste@gmail.com>
|
||||
Steven <wokste@Komkommer.(none)>
|
||||
Steven <wwjd2@web.de>
|
||||
Sugaroverdose <n1nj4p0w3r@gmail.com>
|
||||
Susinthiran Sithamparanathan <chesusin@gmail.com>
|
||||
tbelau666 <thomas.belau@gmx.de>
|
||||
TheSFReader <TheSFReader@gmail.com>
|
||||
Thibaut GRIDEL <tgridel@free.fr>
|
||||
thomas <thomas@thomas-VirtualBox.(none)>
|
||||
Thomas Citharel <nextcloud@tcit.fr> Thomas Citharel <tcit@tcit.fr>
|
||||
Thomas Citharel <nextcloud@tcit.fr> Thomas Citharel <github@tcit.fr>
|
||||
Thomas Müller <thomas.mueller@tmit.eu> Thomas Mueller <thomas.mueller@tmit.eu>
|
||||
Thomas Müller <thomas.mueller@tmit.eu> Thomas Müller <DeepDiver1975@users.noreply.github.com>
|
||||
Thomas Olsen <tol@tanghus>
|
||||
Thomas Schmidt <tschmidt@suse.de>
|
||||
Thomas Tanghus <thomas@tanghus.net>
|
||||
Thomas Zander <zander@kde.org>
|
||||
tiezdne <oswald.84@t-online.de>
|
||||
Tigran Mkrtchyan <tigran.mkrtchyan@desy.de>
|
||||
Tobias Kaminsky <tobias@kaminsky.me> tobiasKaminsky <tobias@kaminsky.me>
|
||||
Tom Needham <tom@owncloud.com> Tom Needham <needham.thomas@gmail.com>
|
||||
Tom Needham <tom@owncloud.com> Tom Needham <tom@tre.tomneedham.com>
|
||||
Tom Needham <tom@owncloud.com> tomneedham <needham.thomas@gmail.com>
|
||||
Tom Needham <tom@owncloud.com> tomneedham <tom@owncloud.com>
|
||||
Tony Zelenoff <antonz@parallels.com>
|
||||
tsumi <mail@tsumi.it>
|
||||
twood8 <ted.wood@gtri.gatech.edu>
|
||||
Türker Sezer <turkersezer@tsdesign.info>
|
||||
unclejamal3000 <andreas.pramhaas@posteo.de>
|
||||
unknown <Alain@Alain-PC.(none)>
|
||||
unknown <pnd@.nist.gov>
|
||||
Valerio Ponte <valerio.ponte@gmail.com>
|
||||
Victor Dubiniuk <dubiniuk@owncloud.com> Victor Dubiniuk <victor.dubiniuk@gmail.com>
|
||||
Victor Dubiniuk <dubiniuk@owncloud.com> VicDeo <dubiniuk@owncloud.com>
|
||||
Victor Dubiniuk <dubiniuk@owncloud.com> VicDeo <victor.dubiniuk@gmail.com>
|
||||
Vincent Cloutier <vincent1cloutier@gmail.com>
|
||||
Vincent Petry <vincent@nextcloud.com> Vincent Petry <PVince81@yahoo.fr>
|
||||
Vincent Petry <vincent@nextcloud.com> Vincent Petry <vincent@vvortex.site>
|
||||
Vincent Petry <vincent@nextcloud.com> Vincent Petry <pvince81@owncloud.com>
|
||||
Vinicius Cubas Brand <vinicius@eita.org.br> Vinicius Cubas Brand <viniciuscb@gmail.com>
|
||||
Vitaly Kuznetsov <vitty@altlinux.ru>
|
||||
Vladimir Sapronov <vladimir.sapronov@gmail.com>
|
||||
Volkan Gezer <volkangezer@gmail.com> Volkan Gezer <wakeup@users.noreply.github.com>
|
||||
Volker E. <open@temporaer.net>
|
||||
voxsim <Simon Vocella>
|
||||
vsapronov <vladimir.sapronov@gmail.com>
|
||||
Vsevolod Kukol <v.kukol@rubologic.de>
|
||||
Weng Xuetian <wengxt@gmail.com>
|
||||
Wikinaut <mail@tgries.de>
|
||||
Willi Ballenthin <willi.ballenthin@gmail.com>
|
||||
windaishi <manuel.strider@web.de>
|
||||
Witali Rott <info@hlop.eu>
|
||||
Yann VERRY <yann@verry.org>
|
||||
yannickoo <github@yannickoo.de>
|
||||
zafi <zafirakis.daniel@gmail.com>
|
||||
zombiehugs <gerdsen@gmail.com>
|
||||
@@ -1 +0,0 @@
|
||||
**/*.spec.js
|
||||
@@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once './vendor-bin/cs-fixer/vendor/autoload.php';
|
||||
|
||||
use Nextcloud\CodingStandard\Config;
|
||||
|
||||
$config = new Config();
|
||||
$config
|
||||
->getFinder()
|
||||
->ignoreVCSIgnored(true)
|
||||
->exclude('config')
|
||||
->exclude('data')
|
||||
->notPath('3rdparty')
|
||||
->notPath('build/integration/vendor')
|
||||
->notPath('build/lib')
|
||||
->notPath('build/node_modules')
|
||||
->notPath('build/stubs')
|
||||
->notPath('composer')
|
||||
->notPath('node_modules')
|
||||
->notPath('vendor')
|
||||
->in(__DIR__);
|
||||
return $config;
|
||||
@@ -1,39 +0,0 @@
|
||||
before_commands:
|
||||
- 'git submodule update --init --recursive'
|
||||
|
||||
build:
|
||||
nodes:
|
||||
analysis:
|
||||
tests:
|
||||
override:
|
||||
- php-scrutinizer-run
|
||||
|
||||
checks:
|
||||
php:
|
||||
excluded_dependencies:
|
||||
- etsy/phan
|
||||
|
||||
filter:
|
||||
excluded_paths:
|
||||
- '3rdparty/*'
|
||||
- 'apps/*/3rdparty/*'
|
||||
- 'apps/*/vendor/*'
|
||||
- 'l10n/*'
|
||||
- 'core/l10n/*'
|
||||
- 'apps/*/l10n/*'
|
||||
- 'apps/*/tests/*'
|
||||
- 'lib/l10n/*'
|
||||
- 'core/vendor/*'
|
||||
- 'core/js/tests/lib/*.js'
|
||||
- 'core/js/tests/specs/*.js'
|
||||
- 'core/js/jquery-showpassword.js'
|
||||
- 'core/js/jquery-tipsy.js'
|
||||
- 'core/js/placeholders.js'
|
||||
- 'settings/l10n/*'
|
||||
- 'tests/*'
|
||||
- 'build/*'
|
||||
- 'lib/composer/*'
|
||||
|
||||
imports:
|
||||
- javascript
|
||||
- php
|
||||
+169
-170
@@ -1,183 +1,182 @@
|
||||
[main]
|
||||
host = https://www.transifex.com
|
||||
lang_map = bg_BG: bg, cs_CZ: cs, fi_FI: fi, hu_HU: hu, nb_NO: nb, sk_SK: sk, th_TH: th, ja_JP: ja
|
||||
host = https://www.transifex.net
|
||||
|
||||
[nextcloud.core]
|
||||
file_filter = translationfiles/<lang>/core.po
|
||||
source_file = translationfiles/templates/core.pot
|
||||
[owncloud.core]
|
||||
file_filter = l10n/<lang>/core.po
|
||||
host = http://www.transifex.net
|
||||
source_file = l10n/templates/core.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
trans.bg_BG = l10n/bg_BG/core.po
|
||||
trans.ca = l10n/ca/core.po
|
||||
trans.cs_CZ = l10n/cs_CZ/core.po
|
||||
trans.da = l10n/da/core.po
|
||||
trans.de = l10n/de/core.po
|
||||
trans.el = l10n/el/core.po
|
||||
trans.es = l10n/es/core.po
|
||||
trans.et_EE = l10n/et_EE/core.po
|
||||
trans.fr = l10n/fr/core.po
|
||||
trans.id = l10n/id/core.po
|
||||
trans.it = l10n/it/core.po
|
||||
trans.lb = l10n/lb/core.po
|
||||
trans.ms_MY = l10n/ms_MY/core.po
|
||||
trans.nb_NO = l10n/nb_NO/core.po
|
||||
trans.nl = l10n/nl/core.po
|
||||
trans.pl = l10n/pl/core.po
|
||||
trans.pt_BR = l10n/pt_BR/core.po
|
||||
trans.pt_PT = l10n/pt_PT/core.po
|
||||
trans.ro = l10n/ro/core.po
|
||||
trans.ru = l10n/ru/core.po
|
||||
trans.sr = l10n/sr/core.po
|
||||
trans.sr@latin = l10n/sr@latin/core.po
|
||||
trans.sv = l10n/sv/core.po
|
||||
trans.zh_CN = l10n/zh_CN/core.po
|
||||
|
||||
[nextcloud.files]
|
||||
file_filter = translationfiles/<lang>/files.po
|
||||
source_file = translationfiles/templates/files.pot
|
||||
[owncloud.settings]
|
||||
file_filter = l10n/<lang>/settings.po
|
||||
host = http://www.transifex.net
|
||||
source_file = l10n/templates/settings.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
trans.bg_BG = l10n/bg_BG/settings.po
|
||||
trans.ca = l10n/ca/settings.po
|
||||
trans.cs_CZ = l10n/cs_CZ/settings.po
|
||||
trans.da = l10n/da/settings.po
|
||||
trans.de = l10n/de/settings.po
|
||||
trans.el = l10n/el/settings.po
|
||||
trans.es = l10n/es/settings.po
|
||||
trans.et_EE = l10n/et_EE/settings.po
|
||||
trans.fr = l10n/fr/settings.po
|
||||
trans.id = l10n/id/settings.po
|
||||
trans.it = l10n/it/settings.po
|
||||
trans.lb = l10n/lb/settings.po
|
||||
trans.ms_MY = l10n/ms_MY/settings.po
|
||||
trans.nb_NO = l10n/nb_NO/settings.po
|
||||
trans.nl = l10n/nl/settings.po
|
||||
trans.pl = l10n/pl/settings.po
|
||||
trans.pt_BR = l10n/pt_BR/settings.po
|
||||
trans.pt_PT = l10n/pt_PT/settings.po
|
||||
trans.ro = l10n/ro/settings.po
|
||||
trans.ru = l10n/ru/settings.po
|
||||
trans.sr = l10n/sr/settings.po
|
||||
trans.sr@latin = l10n/sr@latin/settings.po
|
||||
trans.sv = l10n/sv/settings.po
|
||||
trans.zh_CN = l10n/zh_CN/settings.po
|
||||
|
||||
[nextcloud.settings-1]
|
||||
file_filter = translationfiles/<lang>/settings.po
|
||||
source_file = translationfiles/templates/settings.pot
|
||||
[owncloud.files]
|
||||
file_filter = translations/owncloud.files/<lang>.po
|
||||
host = http://www.transifex.net
|
||||
source_file = l10n/templates/files.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
trans.bg_BG = l10n/bg_BG/files.po
|
||||
trans.ca = l10n/ca/files.po
|
||||
trans.cs_CZ = l10n/cs_CZ/files.po
|
||||
trans.da = l10n/da/files.po
|
||||
trans.de = l10n/de/files.po
|
||||
trans.el = l10n/el/files.po
|
||||
trans.es = l10n/es/files.po
|
||||
trans.et_EE = l10n/et_EE/files.po
|
||||
trans.fr = l10n/fr/files.po
|
||||
trans.id = l10n/id/files.po
|
||||
trans.it = l10n/it/files.po
|
||||
trans.lb = l10n/lb/files.po
|
||||
trans.ms_MY = l10n/ms_MY/files.po
|
||||
trans.nb_NO = l10n/nb_NO/files.po
|
||||
trans.nl = l10n/nl/files.po
|
||||
trans.pl = l10n/pl/files.po
|
||||
trans.pt_BR = l10n/pt_BR/files.po
|
||||
trans.pt_PT = l10n/pt_PT/files.po
|
||||
trans.ro = l10n/ro/files.po
|
||||
trans.ru = l10n/ru/files.po
|
||||
trans.sr = l10n/sr/files.po
|
||||
trans.sr@latin = l10n/sr@latin/files.po
|
||||
trans.sv = l10n/sv/files.po
|
||||
trans.zh_CN = l10n/zh_CN/files.po
|
||||
|
||||
[nextcloud.lib]
|
||||
file_filter = translationfiles/<lang>/lib.po
|
||||
source_file = translationfiles/templates/lib.pot
|
||||
[owncloud.media]
|
||||
file_filter = translations/owncloud.media/<lang>.po
|
||||
host = http://www.transifex.net
|
||||
source_file = l10n/templates/media.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
trans.bg_BG = l10n/bg_BG/media.po
|
||||
trans.ca = l10n/ca/media.po
|
||||
trans.cs_CZ = l10n/cs_CZ/media.po
|
||||
trans.da = l10n/da/media.po
|
||||
trans.de = l10n/de/media.po
|
||||
trans.el = l10n/el/media.po
|
||||
trans.es = l10n/es/media.po
|
||||
trans.et_EE = l10n/et_EE/media.po
|
||||
trans.fr = l10n/fr/media.po
|
||||
trans.id = l10n/id/media.po
|
||||
trans.it = l10n/it/media.po
|
||||
trans.lb = l10n/lb/media.po
|
||||
trans.ms_MY = l10n/ms_MY/media.po
|
||||
trans.nb_NO = l10n/nb_NO/media.po
|
||||
trans.nl = l10n/nl/media.po
|
||||
trans.pl = l10n/pl/media.po
|
||||
trans.pt_BR = l10n/pt_BR/media.po
|
||||
trans.pt_PT = l10n/pt_PT/media.po
|
||||
trans.ro = l10n/ro/media.po
|
||||
trans.ru = l10n/ru/media.po
|
||||
trans.sr = l10n/sr/media.po
|
||||
trans.sr@latin = l10n/sr@latin/media.po
|
||||
trans.sv = l10n/sv/media.po
|
||||
trans.zh_CN = l10n/zh_CN/media.po
|
||||
|
||||
[nextcloud.dav]
|
||||
file_filter = translationfiles/<lang>/dav.po
|
||||
source_file = translationfiles/templates/dav.pot
|
||||
[owncloud.calendar]
|
||||
file_filter = l10n/<lang>/calendar.po
|
||||
host = http://www.transifex.net
|
||||
source_file = l10n/templates/calendar.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
trans.bg_BG = l10n/bg_BG/calendar.po
|
||||
trans.ca = l10n/ca/calendar.po
|
||||
trans.cs_CZ = l10n/cs_CZ/calendar.po
|
||||
trans.da = l10n/da/calendar.po
|
||||
trans.de = l10n/de/calendar.po
|
||||
trans.el = l10n/el/calendar.po
|
||||
trans.es = l10n/es/calendar.po
|
||||
trans.et_EE = l10n/et_EE/calendar.po
|
||||
trans.fr = l10n/fr/calendar.po
|
||||
trans.id = l10n/id/calendar.po
|
||||
trans.it = l10n/it/calendar.po
|
||||
trans.lb = l10n/lb/calendar.po
|
||||
trans.ms_MY = l10n/ms_MY/calendar.po
|
||||
trans.nb_NO = l10n/nb_NO/calendar.po
|
||||
trans.nl = l10n/nl/calendar.po
|
||||
trans.pl = l10n/pl/calendar.po
|
||||
trans.pt_BR = l10n/pt_BR/calendar.po
|
||||
trans.pt_PT = l10n/pt_PT/calendar.po
|
||||
trans.ro = l10n/ro/calendar.po
|
||||
trans.ru = l10n/ru/calendar.po
|
||||
trans.sr = l10n/sr/calendar.po
|
||||
trans.sr@latin = l10n/sr@latin/calendar.po
|
||||
trans.sv = l10n/sv/calendar.po
|
||||
trans.zh_CN = l10n/zh_CN/calendar.po
|
||||
|
||||
[nextcloud.files_encryption]
|
||||
file_filter = translationfiles/<lang>/encryption.po
|
||||
source_file = translationfiles/templates/encryption.pot
|
||||
[owncloud.contacts]
|
||||
file_filter = translations/owncloud.contacts/<lang>.po
|
||||
host = http://www.transifex.net
|
||||
source_file = l10n/templates/contacts.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.files_external]
|
||||
file_filter = translationfiles/<lang>/files_external.po
|
||||
source_file = translationfiles/templates/files_external.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.files_sharing]
|
||||
file_filter = translationfiles/<lang>/files_sharing.po
|
||||
source_file = translationfiles/templates/files_sharing.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.files_trashbin]
|
||||
file_filter = translationfiles/<lang>/files_trashbin.po
|
||||
source_file = translationfiles/templates/files_trashbin.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.files_versions]
|
||||
file_filter = translationfiles/<lang>/files_versions.po
|
||||
source_file = translationfiles/templates/files_versions.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.user_ldap]
|
||||
file_filter = translationfiles/<lang>/user_ldap.po
|
||||
source_file = translationfiles/templates/user_ldap.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.comments]
|
||||
file_filter = translationfiles/<lang>/comments.po
|
||||
source_file = translationfiles/templates/comments.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.federatedfilesharing]
|
||||
file_filter = translationfiles/<lang>/federatedfilesharing.po
|
||||
source_file = translationfiles/templates/federatedfilesharing.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.federation]
|
||||
file_filter = translationfiles/<lang>/federation.po
|
||||
source_file = translationfiles/templates/federation.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.oauth2]
|
||||
file_filter = translationfiles/<lang>/oauth2.po
|
||||
source_file = translationfiles/templates/oauth2.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.sharebymail]
|
||||
file_filter = translationfiles/<lang>/sharebymail.po
|
||||
source_file = translationfiles/templates/sharebymail.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.systemtags]
|
||||
file_filter = translationfiles/<lang>/systemtags.po
|
||||
source_file = translationfiles/templates/systemtags.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.updatenotification]
|
||||
file_filter = translationfiles/<lang>/updatenotification.po
|
||||
source_file = translationfiles/templates/updatenotification.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.theming]
|
||||
file_filter = translationfiles/<lang>/theming.po
|
||||
source_file = translationfiles/templates/theming.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.twofactor_backupcodes]
|
||||
file_filter = translationfiles/<lang>/twofactor_backupcodes.po
|
||||
source_file = translationfiles/templates/twofactor_backupcodes.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.workflowengine]
|
||||
file_filter = translationfiles/<lang>/workflowengine.po
|
||||
source_file = translationfiles/templates/workflowengine.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.accessibility]
|
||||
file_filter = translationfiles/<lang>/accessibility.po
|
||||
source_file = translationfiles/templates/accessibility.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.provisioning_api]
|
||||
file_filter = translationfiles/<lang>/provisioning_api.po
|
||||
source_file = translationfiles/templates/provisioning_api.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.lookup_server_connector]
|
||||
file_filter = translationfiles/<lang>/lookup_server_connector.po
|
||||
source_file = translationfiles/templates/lookup_server_connector.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.dashboard-shipped-with-server]
|
||||
file_filter = translationfiles/<lang>/dashboard.po
|
||||
source_file = translationfiles/templates/dashboard.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.contactsinteraction]
|
||||
file_filter = translationfiles/<lang>/contactsinteraction.po
|
||||
source_file = translationfiles/templates/contactsinteraction.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.cloud_federation_api]
|
||||
file_filter = translationfiles/<lang>/cloud_federation_api.po
|
||||
source_file = translationfiles/templates/cloud_federation_api.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.admin_audit]
|
||||
file_filter = translationfiles/<lang>/admin_audit.po
|
||||
source_file = translationfiles/templates/admin_audit.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.user_status]
|
||||
file_filter = translationfiles/<lang>/user_status.po
|
||||
source_file = translationfiles/templates/user_status.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[nextcloud.weather_status]
|
||||
file_filter = translationfiles/<lang>/weather_status.po
|
||||
source_file = translationfiles/templates/weather_status.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
trans.bg_BG = l10n/bg_BG/contacts.po
|
||||
trans.ca = l10n/ca/contacts.po
|
||||
trans.cs_CZ = l10n/cs_CZ/contacts.po
|
||||
trans.da = l10n/da/contacts.po
|
||||
trans.de = l10n/de/contacts.po
|
||||
trans.el = l10n/el/contacts.po
|
||||
trans.es = l10n/es/contacts.po
|
||||
trans.et_EE = l10n/et_EE/contacts.po
|
||||
trans.fr = l10n/fr/contacts.po
|
||||
trans.id = l10n/id/contacts.po
|
||||
trans.it = l10n/it/contacts.po
|
||||
trans.lb = l10n/lb/contacts.po
|
||||
trans.ms_MY = l10n/ms_MY/contacts.po
|
||||
trans.nb_NO = l10n/nb_NO/contacts.po
|
||||
trans.nl = l10n/nl/contacts.po
|
||||
trans.pl = l10n/pl/contacts.po
|
||||
trans.pt_BR = l10n/pt_BR/contacts.po
|
||||
trans.pt_PT = l10n/pt_PT/contacts.po
|
||||
trans.ro = l10n/ro/contacts.po
|
||||
trans.ru = l10n/ru/contacts.po
|
||||
trans.sr = l10n/sr/contacts.po
|
||||
trans.sr@latin = l10n/sr@latin/contacts.po
|
||||
trans.sv = l10n/sv/contacts.po
|
||||
trans.zh_CN = l10n/zh_CN/contacts.po
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
mbstring.func_overload=0
|
||||
always_populate_raw_post_data=-1
|
||||
default_charset='UTF-8'
|
||||
output_buffering=0
|
||||
-1
Submodule 3rdparty deleted from f6c6c8efb7
Vendored
+1954
File diff suppressed because it is too large
Load Diff
Vendored
+251
@@ -0,0 +1,251 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 3.0 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available through the world-wide-web at the following url: |
|
||||
// | http://www.php.net/license/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Andrei Zmievski <andrei@php.net> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Getopt.php,v 1.21.4.7 2003/12/05 21:57:01 andrei Exp $
|
||||
|
||||
require_once( 'PEAR.php');
|
||||
|
||||
/**
|
||||
* Command-line options parsing class.
|
||||
*
|
||||
* @author Andrei Zmievski <andrei@php.net>
|
||||
*
|
||||
*/
|
||||
class Console_Getopt {
|
||||
/**
|
||||
* Parses the command-line options.
|
||||
*
|
||||
* The first parameter to this function should be the list of command-line
|
||||
* arguments without the leading reference to the running program.
|
||||
*
|
||||
* The second parameter is a string of allowed short options. Each of the
|
||||
* option letters can be followed by a colon ':' to specify that the option
|
||||
* requires an argument, or a double colon '::' to specify that the option
|
||||
* takes an optional argument.
|
||||
*
|
||||
* The third argument is an optional array of allowed long options. The
|
||||
* leading '--' should not be included in the option name. Options that
|
||||
* require an argument should be followed by '=', and options that take an
|
||||
* option argument should be followed by '=='.
|
||||
*
|
||||
* The return value is an array of two elements: the list of parsed
|
||||
* options and the list of non-option command-line arguments. Each entry in
|
||||
* the list of parsed options is a pair of elements - the first one
|
||||
* specifies the option, and the second one specifies the option argument,
|
||||
* if there was one.
|
||||
*
|
||||
* Long and short options can be mixed.
|
||||
*
|
||||
* Most of the semantics of this function are based on GNU getopt_long().
|
||||
*
|
||||
* @param array $args an array of command-line arguments
|
||||
* @param string $short_options specifies the list of allowed short options
|
||||
* @param array $long_options specifies the list of allowed long options
|
||||
*
|
||||
* @return array two-element array containing the list of parsed options and
|
||||
* the non-option arguments
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
function getopt2($args, $short_options, $long_options = null)
|
||||
{
|
||||
return Console_Getopt::doGetopt(2, $args, $short_options, $long_options);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function expects $args to start with the script name (POSIX-style).
|
||||
* Preserved for backwards compatibility.
|
||||
* @see getopt2()
|
||||
*/
|
||||
function getopt($args, $short_options, $long_options = null)
|
||||
{
|
||||
return Console_Getopt::doGetopt(1, $args, $short_options, $long_options);
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual implementation of the argument parsing code.
|
||||
*/
|
||||
function doGetopt($version, $args, $short_options, $long_options = null)
|
||||
{
|
||||
// in case you pass directly readPHPArgv() as the first arg
|
||||
if (PEAR::isError($args)) {
|
||||
return $args;
|
||||
}
|
||||
if (empty($args)) {
|
||||
return array(array(), array());
|
||||
}
|
||||
$opts = array();
|
||||
$non_opts = array();
|
||||
|
||||
settype($args, 'array');
|
||||
|
||||
if ($long_options) {
|
||||
sort($long_options);
|
||||
}
|
||||
|
||||
/*
|
||||
* Preserve backwards compatibility with callers that relied on
|
||||
* erroneous POSIX fix.
|
||||
*/
|
||||
if ($version < 2) {
|
||||
if (isset($args[0]{0}) && $args[0]{0} != '-') {
|
||||
array_shift($args);
|
||||
}
|
||||
}
|
||||
|
||||
reset($args);
|
||||
while (list($i, $arg) = each($args)) {
|
||||
|
||||
/* The special element '--' means explicit end of
|
||||
options. Treat the rest of the arguments as non-options
|
||||
and end the loop. */
|
||||
if ($arg == '--') {
|
||||
$non_opts = array_merge($non_opts, array_slice($args, $i + 1));
|
||||
break;
|
||||
}
|
||||
|
||||
if ($arg{0} != '-' || (strlen($arg) > 1 && $arg{1} == '-' && !$long_options)) {
|
||||
$non_opts = array_merge($non_opts, array_slice($args, $i));
|
||||
break;
|
||||
} elseif (strlen($arg) > 1 && $arg{1} == '-') {
|
||||
$error = Console_Getopt::_parseLongOption(substr($arg, 2), $long_options, $opts, $args);
|
||||
if (PEAR::isError($error))
|
||||
return $error;
|
||||
} else {
|
||||
$error = Console_Getopt::_parseShortOption(substr($arg, 1), $short_options, $opts, $args);
|
||||
if (PEAR::isError($error))
|
||||
return $error;
|
||||
}
|
||||
}
|
||||
|
||||
return array($opts, $non_opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*
|
||||
*/
|
||||
function _parseShortOption($arg, $short_options, &$opts, &$args)
|
||||
{
|
||||
for ($i = 0; $i < strlen($arg); $i++) {
|
||||
$opt = $arg{$i};
|
||||
$opt_arg = null;
|
||||
|
||||
/* Try to find the short option in the specifier string. */
|
||||
if (($spec = strstr($short_options, $opt)) === false || $arg{$i} == ':')
|
||||
{
|
||||
return PEAR::raiseError("Console_Getopt: unrecognized option -- $opt");
|
||||
}
|
||||
|
||||
if (strlen($spec) > 1 && $spec{1} == ':') {
|
||||
if (strlen($spec) > 2 && $spec{2} == ':') {
|
||||
if ($i + 1 < strlen($arg)) {
|
||||
/* Option takes an optional argument. Use the remainder of
|
||||
the arg string if there is anything left. */
|
||||
$opts[] = array($opt, substr($arg, $i + 1));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Option requires an argument. Use the remainder of the arg
|
||||
string if there is anything left. */
|
||||
if ($i + 1 < strlen($arg)) {
|
||||
$opts[] = array($opt, substr($arg, $i + 1));
|
||||
break;
|
||||
} else if (list(, $opt_arg) = each($args))
|
||||
/* Else use the next argument. */;
|
||||
else
|
||||
return PEAR::raiseError("Console_Getopt: option requires an argument -- $opt");
|
||||
}
|
||||
}
|
||||
|
||||
$opts[] = array($opt, $opt_arg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*
|
||||
*/
|
||||
function _parseLongOption($arg, $long_options, &$opts, &$args)
|
||||
{
|
||||
@list($opt, $opt_arg) = explode('=', $arg);
|
||||
$opt_len = strlen($opt);
|
||||
|
||||
for ($i = 0; $i < count($long_options); $i++) {
|
||||
$long_opt = $long_options[$i];
|
||||
$opt_start = substr($long_opt, 0, $opt_len);
|
||||
|
||||
/* Option doesn't match. Go on to the next one. */
|
||||
if ($opt_start != $opt)
|
||||
continue;
|
||||
|
||||
$opt_rest = substr($long_opt, $opt_len);
|
||||
|
||||
/* Check that the options uniquely matches one of the allowed
|
||||
options. */
|
||||
if ($opt_rest != '' && $opt{0} != '=' &&
|
||||
$i + 1 < count($long_options) &&
|
||||
$opt == substr($long_options[$i+1], 0, $opt_len)) {
|
||||
return PEAR::raiseError("Console_Getopt: option --$opt is ambiguous");
|
||||
}
|
||||
|
||||
if (substr($long_opt, -1) == '=') {
|
||||
if (substr($long_opt, -2) != '==') {
|
||||
/* Long option requires an argument.
|
||||
Take the next argument if one wasn't specified. */;
|
||||
if (!strlen($opt_arg) && !(list(, $opt_arg) = each($args))) {
|
||||
return PEAR::raiseError("Console_Getopt: option --$opt requires an argument");
|
||||
}
|
||||
}
|
||||
} else if ($opt_arg) {
|
||||
return PEAR::raiseError("Console_Getopt: option --$opt doesn't allow an argument");
|
||||
}
|
||||
|
||||
$opts[] = array('--' . $opt, $opt_arg);
|
||||
return;
|
||||
}
|
||||
|
||||
return PEAR::raiseError("Console_Getopt: unrecognized option --$opt");
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely read the $argv PHP array across different PHP configurations.
|
||||
* Will take care on register_globals and register_argc_argv ini directives
|
||||
*
|
||||
* @access public
|
||||
* @return mixed the $argv PHP array or PEAR error if not registered
|
||||
*/
|
||||
function readPHPArgv()
|
||||
{
|
||||
global $argv;
|
||||
if (!is_array($argv)) {
|
||||
if (!@is_array($_SERVER['argv'])) {
|
||||
if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) {
|
||||
return PEAR::raiseError("Console_Getopt: Could not read cmd args (register_argc_argv=Off?)");
|
||||
}
|
||||
return $GLOBALS['HTTP_SERVER_VARS']['argv'];
|
||||
}
|
||||
return $_SERVER['argv'];
|
||||
}
|
||||
return $argv;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
Vendored
+317
@@ -0,0 +1,317 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Crypt_Blowfish allows for encryption and decryption on the fly using
|
||||
* the Blowfish algorithm. Crypt_Blowfish does not require the mcrypt
|
||||
* PHP extension, it uses only PHP.
|
||||
* Crypt_Blowfish support encryption/decryption with or without a secret key.
|
||||
*
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE: This source file is subject to version 3.0 of the PHP license
|
||||
* that is available through the world-wide-web at the following URI:
|
||||
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
||||
* the PHP License and are unable to obtain it through the web, please
|
||||
* send a note to license@php.net so we can mail you a copy immediately.
|
||||
*
|
||||
* @category Encryption
|
||||
* @package Crypt_Blowfish
|
||||
* @author Matthew Fonda <mfonda@php.net>
|
||||
* @copyright 2005 Matthew Fonda
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version CVS: $Id: Blowfish.php,v 1.81 2005/05/30 18:40:36 mfonda Exp $
|
||||
* @link http://pear.php.net/package/Crypt_Blowfish
|
||||
*/
|
||||
|
||||
|
||||
require_once 'PEAR.php';
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Example usage:
|
||||
* $bf = new Crypt_Blowfish('some secret key!');
|
||||
* $encrypted = $bf->encrypt('this is some example plain text');
|
||||
* $plaintext = $bf->decrypt($encrypted);
|
||||
* echo "plain text: $plaintext";
|
||||
*
|
||||
*
|
||||
* @category Encryption
|
||||
* @package Crypt_Blowfish
|
||||
* @author Matthew Fonda <mfonda@php.net>
|
||||
* @copyright 2005 Matthew Fonda
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @link http://pear.php.net/package/Crypt_Blowfish
|
||||
* @version @package_version@
|
||||
* @access public
|
||||
*/
|
||||
class Crypt_Blowfish
|
||||
{
|
||||
/**
|
||||
* P-Array contains 18 32-bit subkeys
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $_P = array();
|
||||
|
||||
|
||||
/**
|
||||
* Array of four S-Blocks each containing 256 32-bit entries
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $_S = array();
|
||||
|
||||
/**
|
||||
* Mcrypt td resource
|
||||
*
|
||||
* @var resource
|
||||
* @access private
|
||||
*/
|
||||
var $_td = null;
|
||||
|
||||
/**
|
||||
* Initialization vector
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_iv = null;
|
||||
|
||||
|
||||
/**
|
||||
* Crypt_Blowfish Constructor
|
||||
* Initializes the Crypt_Blowfish object, and gives a sets
|
||||
* the secret key
|
||||
*
|
||||
* @param string $key
|
||||
* @access public
|
||||
*/
|
||||
function Crypt_Blowfish($key)
|
||||
{
|
||||
if (extension_loaded('mcrypt')) {
|
||||
$this->_td = mcrypt_module_open(MCRYPT_BLOWFISH, '', 'ecb', '');
|
||||
$this->_iv = mcrypt_create_iv(8, MCRYPT_RAND);
|
||||
}
|
||||
$this->setKey($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated isReady method
|
||||
*
|
||||
* @return bool
|
||||
* @access public
|
||||
* @deprecated
|
||||
*/
|
||||
function isReady()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated init method - init is now a private
|
||||
* method and has been replaced with _init
|
||||
*
|
||||
* @return bool
|
||||
* @access public
|
||||
* @deprecated
|
||||
* @see Crypt_Blowfish::_init()
|
||||
*/
|
||||
function init()
|
||||
{
|
||||
$this->_init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the Crypt_Blowfish object
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _init()
|
||||
{
|
||||
$defaults = new Crypt_Blowfish_DefaultKey();
|
||||
$this->_P = $defaults->P;
|
||||
$this->_S = $defaults->S;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enciphers a single 64 bit block
|
||||
*
|
||||
* @param int &$Xl
|
||||
* @param int &$Xr
|
||||
* @access private
|
||||
*/
|
||||
function _encipher(&$Xl, &$Xr)
|
||||
{
|
||||
for ($i = 0; $i < 16; $i++) {
|
||||
$temp = $Xl ^ $this->_P[$i];
|
||||
$Xl = ((($this->_S[0][($temp>>24) & 255] +
|
||||
$this->_S[1][($temp>>16) & 255]) ^
|
||||
$this->_S[2][($temp>>8) & 255]) +
|
||||
$this->_S[3][$temp & 255]) ^ $Xr;
|
||||
$Xr = $temp;
|
||||
}
|
||||
$Xr = $Xl ^ $this->_P[16];
|
||||
$Xl = $temp ^ $this->_P[17];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deciphers a single 64 bit block
|
||||
*
|
||||
* @param int &$Xl
|
||||
* @param int &$Xr
|
||||
* @access private
|
||||
*/
|
||||
function _decipher(&$Xl, &$Xr)
|
||||
{
|
||||
for ($i = 17; $i > 1; $i--) {
|
||||
$temp = $Xl ^ $this->_P[$i];
|
||||
$Xl = ((($this->_S[0][($temp>>24) & 255] +
|
||||
$this->_S[1][($temp>>16) & 255]) ^
|
||||
$this->_S[2][($temp>>8) & 255]) +
|
||||
$this->_S[3][$temp & 255]) ^ $Xr;
|
||||
$Xr = $temp;
|
||||
}
|
||||
$Xr = $Xl ^ $this->_P[1];
|
||||
$Xl = $temp ^ $this->_P[0];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Encrypts a string
|
||||
*
|
||||
* @param string $plainText
|
||||
* @return string Returns cipher text on success, PEAR_Error on failure
|
||||
* @access public
|
||||
*/
|
||||
function encrypt($plainText)
|
||||
{
|
||||
if (!is_string($plainText)) {
|
||||
PEAR::raiseError('Plain text must be a string', 0, PEAR_ERROR_DIE);
|
||||
}
|
||||
|
||||
if (extension_loaded('mcrypt')) {
|
||||
return mcrypt_generic($this->_td, $plainText);
|
||||
}
|
||||
|
||||
$cipherText = '';
|
||||
$len = strlen($plainText);
|
||||
$plainText .= str_repeat(chr(0),(8 - ($len%8))%8);
|
||||
for ($i = 0; $i < $len; $i += 8) {
|
||||
list(,$Xl,$Xr) = unpack("N2",substr($plainText,$i,8));
|
||||
$this->_encipher($Xl, $Xr);
|
||||
$cipherText .= pack("N2", $Xl, $Xr);
|
||||
}
|
||||
return $cipherText;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decrypts an encrypted string
|
||||
*
|
||||
* @param string $cipherText
|
||||
* @return string Returns plain text on success, PEAR_Error on failure
|
||||
* @access public
|
||||
*/
|
||||
function decrypt($cipherText)
|
||||
{
|
||||
if (!is_string($cipherText)) {
|
||||
PEAR::raiseError('Chiper text must be a string', 1, PEAR_ERROR_DIE);
|
||||
}
|
||||
|
||||
if (extension_loaded('mcrypt')) {
|
||||
return mdecrypt_generic($this->_td, $cipherText);
|
||||
}
|
||||
|
||||
$plainText = '';
|
||||
$len = strlen($cipherText);
|
||||
$cipherText .= str_repeat(chr(0),(8 - ($len%8))%8);
|
||||
for ($i = 0; $i < $len; $i += 8) {
|
||||
list(,$Xl,$Xr) = unpack("N2",substr($cipherText,$i,8));
|
||||
$this->_decipher($Xl, $Xr);
|
||||
$plainText .= pack("N2", $Xl, $Xr);
|
||||
}
|
||||
return $plainText;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the secret key
|
||||
* The key must be non-zero, and less than or equal to
|
||||
* 56 characters in length.
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool Returns true on success, PEAR_Error on failure
|
||||
* @access public
|
||||
*/
|
||||
function setKey($key)
|
||||
{
|
||||
if (!is_string($key)) {
|
||||
PEAR::raiseError('Key must be a string', 2, PEAR_ERROR_DIE);
|
||||
}
|
||||
|
||||
$len = strlen($key);
|
||||
|
||||
if ($len > 56 || $len == 0) {
|
||||
PEAR::raiseError('Key must be less than 56 characters and non-zero. Supplied key length: ' . $len, 3, PEAR_ERROR_DIE);
|
||||
}
|
||||
|
||||
if (extension_loaded('mcrypt')) {
|
||||
mcrypt_generic_init($this->_td, $key, $this->_iv);
|
||||
return true;
|
||||
}
|
||||
|
||||
require_once 'Blowfish/DefaultKey.php';
|
||||
$this->_init();
|
||||
|
||||
$k = 0;
|
||||
$data = 0;
|
||||
$datal = 0;
|
||||
$datar = 0;
|
||||
|
||||
for ($i = 0; $i < 18; $i++) {
|
||||
$data = 0;
|
||||
for ($j = 4; $j > 0; $j--) {
|
||||
$data = $data << 8 | ord($key{$k});
|
||||
$k = ($k+1) % $len;
|
||||
}
|
||||
$this->_P[$i] ^= $data;
|
||||
}
|
||||
|
||||
for ($i = 0; $i <= 16; $i += 2) {
|
||||
$this->_encipher($datal, $datar);
|
||||
$this->_P[$i] = $datal;
|
||||
$this->_P[$i+1] = $datar;
|
||||
}
|
||||
for ($i = 0; $i < 256; $i += 2) {
|
||||
$this->_encipher($datal, $datar);
|
||||
$this->_S[0][$i] = $datal;
|
||||
$this->_S[0][$i+1] = $datar;
|
||||
}
|
||||
for ($i = 0; $i < 256; $i += 2) {
|
||||
$this->_encipher($datal, $datar);
|
||||
$this->_S[1][$i] = $datal;
|
||||
$this->_S[1][$i+1] = $datar;
|
||||
}
|
||||
for ($i = 0; $i < 256; $i += 2) {
|
||||
$this->_encipher($datal, $datar);
|
||||
$this->_S[2][$i] = $datal;
|
||||
$this->_S[2][$i+1] = $datar;
|
||||
}
|
||||
for ($i = 0; $i < 256; $i += 2) {
|
||||
$this->_encipher($datal, $datar);
|
||||
$this->_S[3][$i] = $datal;
|
||||
$this->_S[3][$i+1] = $datar;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
+327
@@ -0,0 +1,327 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Crypt_Blowfish allows for encryption and decryption on the fly using
|
||||
* the Blowfish algorithm. Crypt_Blowfish does not require the mcrypt
|
||||
* PHP extension, it uses only PHP.
|
||||
* Crypt_Blowfish support encryption/decryption with or without a secret key.
|
||||
*
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE: This source file is subject to version 3.0 of the PHP license
|
||||
* that is available through the world-wide-web at the following URI:
|
||||
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
||||
* the PHP License and are unable to obtain it through the web, please
|
||||
* send a note to license@php.net so we can mail you a copy immediately.
|
||||
*
|
||||
* @category Encryption
|
||||
* @package Crypt_Blowfish
|
||||
* @author Matthew Fonda <mfonda@php.net>
|
||||
* @copyright 2005 Matthew Fonda
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version CVS: $Id: DefaultKey.php,v 1.81 2005/05/30 18:40:37 mfonda Exp $
|
||||
* @link http://pear.php.net/package/Crypt_Blowfish
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Class containing default key
|
||||
*
|
||||
* @category Encryption
|
||||
* @package Crypt_Blowfish
|
||||
* @author Matthew Fonda <mfonda@php.net>
|
||||
* @copyright 2005 Matthew Fonda
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @link http://pear.php.net/package/Crypt_Blowfish
|
||||
* @version @package_version@
|
||||
* @access public
|
||||
*/
|
||||
class Crypt_Blowfish_DefaultKey
|
||||
{
|
||||
var $P = array();
|
||||
|
||||
var $S = array();
|
||||
|
||||
function Crypt_Blowfish_DefaultKey()
|
||||
{
|
||||
$this->P = array(
|
||||
0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344,
|
||||
0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89,
|
||||
0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
|
||||
0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917,
|
||||
0x9216D5D9, 0x8979FB1B
|
||||
);
|
||||
|
||||
$this->S = array(
|
||||
array(
|
||||
0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7,
|
||||
0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99,
|
||||
0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16,
|
||||
0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E,
|
||||
0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE,
|
||||
0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013,
|
||||
0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF,
|
||||
0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E,
|
||||
0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
|
||||
0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440,
|
||||
0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE,
|
||||
0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
|
||||
0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E,
|
||||
0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677,
|
||||
0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193,
|
||||
0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032,
|
||||
0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88,
|
||||
0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
|
||||
0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E,
|
||||
0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0,
|
||||
0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3,
|
||||
0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98,
|
||||
0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88,
|
||||
0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
|
||||
0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6,
|
||||
0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D,
|
||||
0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
|
||||
0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7,
|
||||
0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA,
|
||||
0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463,
|
||||
0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F,
|
||||
0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09,
|
||||
0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3,
|
||||
0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB,
|
||||
0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279,
|
||||
0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
|
||||
0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB,
|
||||
0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82,
|
||||
0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB,
|
||||
0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573,
|
||||
0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0,
|
||||
0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B,
|
||||
0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790,
|
||||
0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8,
|
||||
0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
|
||||
0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0,
|
||||
0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7,
|
||||
0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
|
||||
0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD,
|
||||
0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1,
|
||||
0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299,
|
||||
0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9,
|
||||
0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477,
|
||||
0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
|
||||
0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49,
|
||||
0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF,
|
||||
0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA,
|
||||
0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5,
|
||||
0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41,
|
||||
0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
|
||||
0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400,
|
||||
0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915,
|
||||
0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
|
||||
0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A
|
||||
),
|
||||
array(
|
||||
0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623,
|
||||
0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266,
|
||||
0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1,
|
||||
0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E,
|
||||
0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6,
|
||||
0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
|
||||
0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E,
|
||||
0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1,
|
||||
0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
|
||||
0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8,
|
||||
0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF,
|
||||
0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
|
||||
0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701,
|
||||
0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7,
|
||||
0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41,
|
||||
0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331,
|
||||
0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF,
|
||||
0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
|
||||
0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E,
|
||||
0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87,
|
||||
0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C,
|
||||
0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2,
|
||||
0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16,
|
||||
0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
|
||||
0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B,
|
||||
0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509,
|
||||
0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
|
||||
0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3,
|
||||
0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F,
|
||||
0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
|
||||
0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4,
|
||||
0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960,
|
||||
0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66,
|
||||
0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28,
|
||||
0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802,
|
||||
0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
|
||||
0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510,
|
||||
0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF,
|
||||
0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14,
|
||||
0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E,
|
||||
0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50,
|
||||
0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
|
||||
0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8,
|
||||
0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281,
|
||||
0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
|
||||
0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696,
|
||||
0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128,
|
||||
0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
|
||||
0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0,
|
||||
0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0,
|
||||
0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105,
|
||||
0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250,
|
||||
0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3,
|
||||
0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
|
||||
0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00,
|
||||
0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061,
|
||||
0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB,
|
||||
0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E,
|
||||
0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735,
|
||||
0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
|
||||
0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9,
|
||||
0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340,
|
||||
0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
|
||||
0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7
|
||||
),
|
||||
array(
|
||||
0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934,
|
||||
0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068,
|
||||
0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF,
|
||||
0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840,
|
||||
0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45,
|
||||
0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
|
||||
0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A,
|
||||
0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB,
|
||||
0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
|
||||
0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6,
|
||||
0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42,
|
||||
0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
|
||||
0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2,
|
||||
0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB,
|
||||
0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527,
|
||||
0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B,
|
||||
0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33,
|
||||
0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
|
||||
0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3,
|
||||
0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC,
|
||||
0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17,
|
||||
0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564,
|
||||
0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B,
|
||||
0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
|
||||
0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922,
|
||||
0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728,
|
||||
0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
|
||||
0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E,
|
||||
0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37,
|
||||
0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D,
|
||||
0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804,
|
||||
0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B,
|
||||
0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3,
|
||||
0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB,
|
||||
0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D,
|
||||
0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
|
||||
0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350,
|
||||
0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9,
|
||||
0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A,
|
||||
0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE,
|
||||
0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D,
|
||||
0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC,
|
||||
0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F,
|
||||
0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61,
|
||||
0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
|
||||
0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9,
|
||||
0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2,
|
||||
0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
|
||||
0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E,
|
||||
0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633,
|
||||
0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10,
|
||||
0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169,
|
||||
0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52,
|
||||
0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
|
||||
0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5,
|
||||
0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62,
|
||||
0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634,
|
||||
0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76,
|
||||
0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24,
|
||||
0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
|
||||
0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4,
|
||||
0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C,
|
||||
0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
|
||||
0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0
|
||||
),
|
||||
array(
|
||||
0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B,
|
||||
0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE,
|
||||
0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B,
|
||||
0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4,
|
||||
0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8,
|
||||
0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
|
||||
0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304,
|
||||
0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22,
|
||||
0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
|
||||
0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6,
|
||||
0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9,
|
||||
0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
|
||||
0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593,
|
||||
0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51,
|
||||
0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28,
|
||||
0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C,
|
||||
0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B,
|
||||
0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
|
||||
0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C,
|
||||
0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD,
|
||||
0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A,
|
||||
0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319,
|
||||
0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB,
|
||||
0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
|
||||
0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991,
|
||||
0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32,
|
||||
0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
|
||||
0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166,
|
||||
0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE,
|
||||
0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB,
|
||||
0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5,
|
||||
0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47,
|
||||
0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370,
|
||||
0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D,
|
||||
0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84,
|
||||
0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
|
||||
0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8,
|
||||
0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD,
|
||||
0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9,
|
||||
0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7,
|
||||
0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38,
|
||||
0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
|
||||
0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C,
|
||||
0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525,
|
||||
0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
|
||||
0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442,
|
||||
0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964,
|
||||
0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
|
||||
0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8,
|
||||
0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D,
|
||||
0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F,
|
||||
0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299,
|
||||
0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02,
|
||||
0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
|
||||
0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614,
|
||||
0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A,
|
||||
0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6,
|
||||
0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B,
|
||||
0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0,
|
||||
0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
|
||||
0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E,
|
||||
0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9,
|
||||
0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
|
||||
0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
Vendored
+4587
File diff suppressed because it is too large
Load Diff
Vendored
+183
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2006 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his 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 |
|
||||
// | REGENTS 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
/**
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Several methods to convert the MDB2 native timestamp format (ISO based)
|
||||
* to and from data structures that are convenient to worth with in side of php.
|
||||
* For more complex date arithmetic please take a look at the Date package in PEAR
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Date
|
||||
{
|
||||
// {{{ mdbNow()
|
||||
|
||||
/**
|
||||
* return the current datetime
|
||||
*
|
||||
* @return string current datetime in the MDB2 format
|
||||
* @access public
|
||||
*/
|
||||
function mdbNow()
|
||||
{
|
||||
return date('Y-m-d H:i:s');
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ mdbToday()
|
||||
|
||||
/**
|
||||
* return the current date
|
||||
*
|
||||
* @return string current date in the MDB2 format
|
||||
* @access public
|
||||
*/
|
||||
function mdbToday()
|
||||
{
|
||||
return date('Y-m-d');
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ mdbTime()
|
||||
|
||||
/**
|
||||
* return the current time
|
||||
*
|
||||
* @return string current time in the MDB2 format
|
||||
* @access public
|
||||
*/
|
||||
function mdbTime()
|
||||
{
|
||||
return date('H:i:s');
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ date2Mdbstamp()
|
||||
|
||||
/**
|
||||
* convert a date into a MDB2 timestamp
|
||||
*
|
||||
* @param int hour of the date
|
||||
* @param int minute of the date
|
||||
* @param int second of the date
|
||||
* @param int month of the date
|
||||
* @param int day of the date
|
||||
* @param int year of the date
|
||||
*
|
||||
* @return string a valid MDB2 timestamp
|
||||
* @access public
|
||||
*/
|
||||
function date2Mdbstamp($hour = null, $minute = null, $second = null,
|
||||
$month = null, $day = null, $year = null)
|
||||
{
|
||||
return MDB2_Date::unix2Mdbstamp(mktime($hour, $minute, $second, $month, $day, $year, -1));
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ unix2Mdbstamp()
|
||||
|
||||
/**
|
||||
* convert a unix timestamp into a MDB2 timestamp
|
||||
*
|
||||
* @param int a valid unix timestamp
|
||||
*
|
||||
* @return string a valid MDB2 timestamp
|
||||
* @access public
|
||||
*/
|
||||
function unix2Mdbstamp($unix_timestamp)
|
||||
{
|
||||
return date('Y-m-d H:i:s', $unix_timestamp);
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ mdbstamp2Unix()
|
||||
|
||||
/**
|
||||
* convert a MDB2 timestamp into a unix timestamp
|
||||
*
|
||||
* @param int a valid MDB2 timestamp
|
||||
* @return string unix timestamp with the time stored in the MDB2 format
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function mdbstamp2Unix($mdb_timestamp)
|
||||
{
|
||||
$arr = MDB2_Date::mdbstamp2Date($mdb_timestamp);
|
||||
|
||||
return mktime($arr['hour'], $arr['minute'], $arr['second'], $arr['month'], $arr['day'], $arr['year'], -1);
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ mdbstamp2Date()
|
||||
|
||||
/**
|
||||
* convert a MDB2 timestamp into an array containing all
|
||||
* values necessary to pass to php's date() function
|
||||
*
|
||||
* @param int a valid MDB2 timestamp
|
||||
*
|
||||
* @return array with the time split
|
||||
* @access public
|
||||
*/
|
||||
function mdbstamp2Date($mdb_timestamp)
|
||||
{
|
||||
list($arr['year'], $arr['month'], $arr['day'], $arr['hour'], $arr['minute'], $arr['second']) =
|
||||
sscanf($mdb_timestamp, "%04u-%02u-%02u %02u:%02u:%02u");
|
||||
return $arr;
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
|
||||
?>
|
||||
+1842
File diff suppressed because it is too large
Load Diff
+602
@@ -0,0 +1,602 @@
|
||||
<?php
|
||||
// vim: set et ts=4 sw=4 fdm=marker:
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2008 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his 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 |
|
||||
// | REGENTS 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Datatype/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 MySQL driver
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Datatype_mysql extends MDB2_Driver_Datatype_Common
|
||||
{
|
||||
// {{{ _getCharsetFieldDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to set the CHARACTER SET
|
||||
* of a field declaration to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $charset name of the charset
|
||||
* @return string DBMS specific SQL code portion needed to set the CHARACTER SET
|
||||
* of a field declaration.
|
||||
*/
|
||||
function _getCharsetFieldDeclaration($charset)
|
||||
{
|
||||
return 'CHARACTER SET '.$charset;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getCollationFieldDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to set the COLLATION
|
||||
* of a field declaration to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $collation name of the collation
|
||||
* @return string DBMS specific SQL code portion needed to set the COLLATION
|
||||
* of a field declaration.
|
||||
*/
|
||||
function _getCollationFieldDeclaration($collation)
|
||||
{
|
||||
return 'COLLATE '.$collation;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare
|
||||
* of the given type
|
||||
*
|
||||
* @param string $type type to which the value should be converted to
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field definition of the field
|
||||
*
|
||||
* @return string DBMS-specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access public
|
||||
*/
|
||||
function getDeclaration($type, $name, $field)
|
||||
{
|
||||
// MySQL DDL syntax forbids combining NOT NULL with DEFAULT NULL.
|
||||
// To get a default of NULL for NOT NULL columns, omit it.
|
||||
if ( isset($field['notnull'])
|
||||
&& !empty($field['notnull'])
|
||||
&& array_key_exists('default', $field) // do not use isset() here!
|
||||
&& null === $field['default']
|
||||
) {
|
||||
unset($field['default']);
|
||||
}
|
||||
return parent::getDeclaration($type, $name, $field);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTypeDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an text type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length of the text
|
||||
* field. If this argument is missing the field should be
|
||||
* declared to have the longest length allowed by the DBMS.
|
||||
*
|
||||
* default
|
||||
* Text value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access public
|
||||
*/
|
||||
function getTypeDeclaration($field)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
switch ($field['type']) {
|
||||
case 'text':
|
||||
if (empty($field['length']) && array_key_exists('default', $field)) {
|
||||
$field['length'] = $db->varchar_max_length;
|
||||
}
|
||||
$length = !empty($field['length']) ? $field['length'] : false;
|
||||
$fixed = !empty($field['fixed']) ? $field['fixed'] : false;
|
||||
return $fixed ? ($length ? 'CHAR('.$length.')' : 'CHAR(255)')
|
||||
: ($length ? 'VARCHAR('.$length.')' : 'TEXT');
|
||||
case 'clob':
|
||||
if (!empty($field['length'])) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 255) {
|
||||
return 'TINYTEXT';
|
||||
} elseif ($length <= 65532) {
|
||||
return 'TEXT';
|
||||
} elseif ($length <= 16777215) {
|
||||
return 'MEDIUMTEXT';
|
||||
}
|
||||
}
|
||||
return 'LONGTEXT';
|
||||
case 'blob':
|
||||
if (!empty($field['length'])) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 255) {
|
||||
return 'TINYBLOB';
|
||||
} elseif ($length <= 65532) {
|
||||
return 'BLOB';
|
||||
} elseif ($length <= 16777215) {
|
||||
return 'MEDIUMBLOB';
|
||||
}
|
||||
}
|
||||
return 'LONGBLOB';
|
||||
case 'integer':
|
||||
if (!empty($field['length'])) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 1) {
|
||||
return 'TINYINT';
|
||||
} elseif ($length == 2) {
|
||||
return 'SMALLINT';
|
||||
} elseif ($length == 3) {
|
||||
return 'MEDIUMINT';
|
||||
} elseif ($length == 4) {
|
||||
return 'INT';
|
||||
} elseif ($length > 4) {
|
||||
return 'BIGINT';
|
||||
}
|
||||
}
|
||||
return 'INT';
|
||||
case 'boolean':
|
||||
return 'TINYINT(1)';
|
||||
case 'date':
|
||||
return 'DATE';
|
||||
case 'time':
|
||||
return 'TIME';
|
||||
case 'timestamp':
|
||||
return 'DATETIME';
|
||||
case 'float':
|
||||
$l = '';
|
||||
if (!empty($field['length'])) {
|
||||
$l = '(' . $field['length'];
|
||||
if (!empty($field['scale'])) {
|
||||
$l .= ',' . $field['scale'];
|
||||
}
|
||||
$l .= ')';
|
||||
}
|
||||
return 'DOUBLE' . $l;
|
||||
case 'decimal':
|
||||
$length = !empty($field['length']) ? $field['length'] : 18;
|
||||
$scale = !empty($field['scale']) ? $field['scale'] : $db->options['decimal_places'];
|
||||
return 'DECIMAL('.$length.','.$scale.')';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getIntegerDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an integer type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* unsigned
|
||||
* Boolean flag that indicates whether the field
|
||||
* should be declared as unsigned integer if
|
||||
* possible.
|
||||
*
|
||||
* default
|
||||
* Integer value to be used as default for this
|
||||
* field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getIntegerDeclaration($name, $field)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$default = $autoinc = '';
|
||||
if (!empty($field['autoincrement'])) {
|
||||
$autoinc = ' AUTO_INCREMENT PRIMARY KEY';
|
||||
} elseif (array_key_exists('default', $field)) {
|
||||
if ($field['default'] === '') {
|
||||
$field['default'] = empty($field['notnull']) ? null : 0;
|
||||
}
|
||||
$default = ' DEFAULT '.$this->quote($field['default'], 'integer');
|
||||
}
|
||||
|
||||
$notnull = empty($field['notnull']) ? '' : ' NOT NULL';
|
||||
$unsigned = empty($field['unsigned']) ? '' : ' UNSIGNED';
|
||||
if (empty($default) && empty($notnull)) {
|
||||
$default = ' DEFAULT NULL';
|
||||
}
|
||||
$name = $db->quoteIdentifier($name, true);
|
||||
return $name.' '.$this->getTypeDeclaration($field).$unsigned.$default.$notnull.$autoinc;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getFloatDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an float type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* unsigned
|
||||
* Boolean flag that indicates whether the field
|
||||
* should be declared as unsigned float if
|
||||
* possible.
|
||||
*
|
||||
* default
|
||||
* float value to be used as default for this
|
||||
* field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getFloatDeclaration($name, $field)
|
||||
{
|
||||
// Since AUTO_INCREMENT can be used for integer or floating-point types,
|
||||
// reuse the INTEGER declaration
|
||||
// @see http://bugs.mysql.com/bug.php?id=31032
|
||||
return $this->_getIntegerDeclaration($name, $field);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getDecimalDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an decimal type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* unsigned
|
||||
* Boolean flag that indicates whether the field
|
||||
* should be declared as unsigned integer if
|
||||
* possible.
|
||||
*
|
||||
* default
|
||||
* Decimal value to be used as default for this
|
||||
* field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getDecimalDeclaration($name, $field)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$default = '';
|
||||
if (array_key_exists('default', $field)) {
|
||||
if ($field['default'] === '') {
|
||||
$field['default'] = empty($field['notnull']) ? null : 0;
|
||||
}
|
||||
$default = ' DEFAULT '.$this->quote($field['default'], 'integer');
|
||||
} elseif (empty($field['notnull'])) {
|
||||
$default = ' DEFAULT NULL';
|
||||
}
|
||||
|
||||
$notnull = empty($field['notnull']) ? '' : ' NOT NULL';
|
||||
$unsigned = empty($field['unsigned']) ? '' : ' UNSIGNED';
|
||||
$name = $db->quoteIdentifier($name, true);
|
||||
return $name.' '.$this->getTypeDeclaration($field).$unsigned.$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ matchPattern()
|
||||
|
||||
/**
|
||||
* build a pattern matching string
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param array $pattern even keys are strings, odd are patterns (% and _)
|
||||
* @param string $operator optional pattern operator (LIKE, ILIKE and maybe others in the future)
|
||||
* @param string $field optional field name that is being matched against
|
||||
* (might be required when emulating ILIKE)
|
||||
*
|
||||
* @return string SQL pattern
|
||||
*/
|
||||
function matchPattern($pattern, $operator = null, $field = null)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$match = '';
|
||||
if (null !== $operator) {
|
||||
$field = (null === $field) ? '' : $field.' ';
|
||||
$operator = strtoupper($operator);
|
||||
switch ($operator) {
|
||||
// case insensitive
|
||||
case 'ILIKE':
|
||||
$match = $field.'LIKE ';
|
||||
break;
|
||||
case 'NOT ILIKE':
|
||||
$match = $field.'NOT LIKE ';
|
||||
break;
|
||||
// case sensitive
|
||||
case 'LIKE':
|
||||
$match = $field.'LIKE BINARY ';
|
||||
break;
|
||||
case 'NOT LIKE':
|
||||
$match = $field.'NOT LIKE BINARY ';
|
||||
break;
|
||||
default:
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'not a supported operator type:'. $operator, __FUNCTION__);
|
||||
}
|
||||
}
|
||||
$match.= "'";
|
||||
foreach ($pattern as $key => $value) {
|
||||
if ($key % 2) {
|
||||
$match.= $value;
|
||||
} else {
|
||||
$match.= $db->escapePattern($db->escape($value));
|
||||
}
|
||||
}
|
||||
$match.= "'";
|
||||
$match.= $this->patternEscapeString();
|
||||
return $match;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _mapNativeDatatype()
|
||||
|
||||
/**
|
||||
* Maps a native array description of a field to a MDB2 datatype and length
|
||||
*
|
||||
* @param array $field native field description
|
||||
* @return array containing the various possible types, length, sign, fixed
|
||||
* @access public
|
||||
*/
|
||||
function _mapNativeDatatype($field)
|
||||
{
|
||||
$db_type = strtolower($field['type']);
|
||||
$db_type = strtok($db_type, '(), ');
|
||||
if ($db_type == 'national') {
|
||||
$db_type = strtok('(), ');
|
||||
}
|
||||
if (!empty($field['length'])) {
|
||||
$length = strtok($field['length'], ', ');
|
||||
$decimal = strtok(', ');
|
||||
} else {
|
||||
$length = strtok('(), ');
|
||||
$decimal = strtok('(), ');
|
||||
}
|
||||
$type = array();
|
||||
$unsigned = $fixed = null;
|
||||
switch ($db_type) {
|
||||
case 'tinyint':
|
||||
$type[] = 'integer';
|
||||
$type[] = 'boolean';
|
||||
if (preg_match('/^(is|has)/', $field['name'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
$length = 1;
|
||||
break;
|
||||
case 'smallint':
|
||||
$type[] = 'integer';
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
$length = 2;
|
||||
break;
|
||||
case 'mediumint':
|
||||
$type[] = 'integer';
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
$length = 3;
|
||||
break;
|
||||
case 'int':
|
||||
case 'integer':
|
||||
$type[] = 'integer';
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
$length = 4;
|
||||
break;
|
||||
case 'bigint':
|
||||
$type[] = 'integer';
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
$length = 8;
|
||||
break;
|
||||
case 'tinytext':
|
||||
case 'mediumtext':
|
||||
case 'longtext':
|
||||
case 'text':
|
||||
case 'varchar':
|
||||
$fixed = false;
|
||||
case 'string':
|
||||
case 'char':
|
||||
$type[] = 'text';
|
||||
if ($length == '1') {
|
||||
$type[] = 'boolean';
|
||||
if (preg_match('/^(is|has)/', $field['name'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
} elseif (strstr($db_type, 'text')) {
|
||||
$type[] = 'clob';
|
||||
if ($decimal == 'binary') {
|
||||
$type[] = 'blob';
|
||||
}
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
if ($fixed !== false) {
|
||||
$fixed = true;
|
||||
}
|
||||
break;
|
||||
case 'enum':
|
||||
$type[] = 'text';
|
||||
preg_match_all('/\'.+\'/U', $field['type'], $matches);
|
||||
$length = 0;
|
||||
$fixed = false;
|
||||
if (is_array($matches)) {
|
||||
foreach ($matches[0] as $value) {
|
||||
$length = max($length, strlen($value)-2);
|
||||
}
|
||||
if ($length == '1' && count($matches[0]) == 2) {
|
||||
$type[] = 'boolean';
|
||||
if (preg_match('/^(is|has)/', $field['name'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
}
|
||||
}
|
||||
$type[] = 'integer';
|
||||
case 'set':
|
||||
$fixed = false;
|
||||
$type[] = 'text';
|
||||
$type[] = 'integer';
|
||||
break;
|
||||
case 'date':
|
||||
$type[] = 'date';
|
||||
$length = null;
|
||||
break;
|
||||
case 'datetime':
|
||||
case 'timestamp':
|
||||
$type[] = 'timestamp';
|
||||
$length = null;
|
||||
break;
|
||||
case 'time':
|
||||
$type[] = 'time';
|
||||
$length = null;
|
||||
break;
|
||||
case 'float':
|
||||
case 'double':
|
||||
case 'real':
|
||||
$type[] = 'float';
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
if ($decimal !== false) {
|
||||
$length = $length.','.$decimal;
|
||||
}
|
||||
break;
|
||||
case 'unknown':
|
||||
case 'decimal':
|
||||
case 'numeric':
|
||||
$type[] = 'decimal';
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
if ($decimal !== false) {
|
||||
$length = $length.','.$decimal;
|
||||
}
|
||||
break;
|
||||
case 'tinyblob':
|
||||
case 'mediumblob':
|
||||
case 'longblob':
|
||||
case 'blob':
|
||||
$type[] = 'blob';
|
||||
$length = null;
|
||||
break;
|
||||
case 'binary':
|
||||
case 'varbinary':
|
||||
$type[] = 'blob';
|
||||
break;
|
||||
case 'year':
|
||||
$type[] = 'integer';
|
||||
$type[] = 'date';
|
||||
$length = null;
|
||||
break;
|
||||
default:
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'unknown database attribute type: '.$db_type, __FUNCTION__);
|
||||
}
|
||||
|
||||
if ((int)$length <= 0) {
|
||||
$length = null;
|
||||
}
|
||||
|
||||
return array($type, $length, $unsigned, $fixed);
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
?>
|
||||
+579
@@ -0,0 +1,579 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2007 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his 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 |
|
||||
// | REGENTS 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Paul Cooper <pgc@ucecom.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
|
||||
require_once 'MDB2/Driver/Datatype/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 PostGreSQL driver
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Paul Cooper <pgc@ucecom.com>
|
||||
*/
|
||||
class MDB2_Driver_Datatype_pgsql extends MDB2_Driver_Datatype_Common
|
||||
{
|
||||
// {{{ _baseConvertResult()
|
||||
|
||||
/**
|
||||
* General type conversion method
|
||||
*
|
||||
* @param mixed $value refernce to a value to be converted
|
||||
* @param string $type specifies which type to convert to
|
||||
* @param boolean $rtrim [optional] when TRUE [default], apply rtrim() to text
|
||||
* @return object a MDB2 error on failure
|
||||
* @access protected
|
||||
*/
|
||||
function _baseConvertResult($value, $type, $rtrim = true)
|
||||
{
|
||||
if (null === $value) {
|
||||
return null;
|
||||
}
|
||||
switch ($type) {
|
||||
case 'boolean':
|
||||
return $value == 't';
|
||||
case 'float':
|
||||
return doubleval($value);
|
||||
case 'date':
|
||||
return $value;
|
||||
case 'time':
|
||||
return substr($value, 0, strlen('HH:MM:SS'));
|
||||
case 'timestamp':
|
||||
return substr($value, 0, strlen('YYYY-MM-DD HH:MM:SS'));
|
||||
case 'blob':
|
||||
$value = pg_unescape_bytea($value);
|
||||
return parent::_baseConvertResult($value, $type, $rtrim);
|
||||
}
|
||||
return parent::_baseConvertResult($value, $type, $rtrim);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTypeDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an text type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length of the text
|
||||
* field. If this argument is missing the field should be
|
||||
* declared to have the longest length allowed by the DBMS.
|
||||
*
|
||||
* default
|
||||
* Text value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access public
|
||||
*/
|
||||
function getTypeDeclaration($field)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
switch ($field['type']) {
|
||||
case 'text':
|
||||
$length = !empty($field['length']) ? $field['length'] : false;
|
||||
$fixed = !empty($field['fixed']) ? $field['fixed'] : false;
|
||||
return $fixed ? ($length ? 'CHAR('.$length.')' : 'CHAR('.$db->options['default_text_field_length'].')')
|
||||
: ($length ? 'VARCHAR('.$length.')' : 'TEXT');
|
||||
case 'clob':
|
||||
return 'TEXT';
|
||||
case 'blob':
|
||||
return 'BYTEA';
|
||||
case 'integer':
|
||||
if (!empty($field['autoincrement'])) {
|
||||
if (!empty($field['length'])) {
|
||||
$length = $field['length'];
|
||||
if ($length > 4) {
|
||||
return 'BIGSERIAL PRIMARY KEY';
|
||||
}
|
||||
}
|
||||
return 'SERIAL PRIMARY KEY';
|
||||
}
|
||||
if (!empty($field['length'])) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 2) {
|
||||
return 'SMALLINT';
|
||||
} elseif ($length == 3 || $length == 4) {
|
||||
return 'INT';
|
||||
} elseif ($length > 4) {
|
||||
return 'BIGINT';
|
||||
}
|
||||
}
|
||||
return 'INT';
|
||||
case 'boolean':
|
||||
return 'BOOLEAN';
|
||||
case 'date':
|
||||
return 'DATE';
|
||||
case 'time':
|
||||
return 'TIME without time zone';
|
||||
case 'timestamp':
|
||||
return 'TIMESTAMP without time zone';
|
||||
case 'float':
|
||||
return 'FLOAT8';
|
||||
case 'decimal':
|
||||
$length = !empty($field['length']) ? $field['length'] : 18;
|
||||
$scale = !empty($field['scale']) ? $field['scale'] : $db->options['decimal_places'];
|
||||
return 'NUMERIC('.$length.','.$scale.')';
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getIntegerDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an integer type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* unsigned
|
||||
* Boolean flag that indicates whether the field should be
|
||||
* declared as unsigned integer if possible.
|
||||
*
|
||||
* default
|
||||
* Integer value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getIntegerDeclaration($name, $field)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (!empty($field['unsigned'])) {
|
||||
$db->warnings[] = "unsigned integer field \"$name\" is being declared as signed integer";
|
||||
}
|
||||
if (!empty($field['autoincrement'])) {
|
||||
$name = $db->quoteIdentifier($name, true);
|
||||
return $name.' '.$this->getTypeDeclaration($field);
|
||||
}
|
||||
$default = '';
|
||||
if (array_key_exists('default', $field)) {
|
||||
if ($field['default'] === '') {
|
||||
$field['default'] = empty($field['notnull']) ? null : 0;
|
||||
}
|
||||
$default = ' DEFAULT '.$this->quote($field['default'], 'integer');
|
||||
}
|
||||
|
||||
$notnull = empty($field['notnull']) ? '' : ' NOT NULL';
|
||||
if (empty($default) && empty($notnull)) {
|
||||
$default = ' DEFAULT NULL';
|
||||
}
|
||||
$name = $db->quoteIdentifier($name, true);
|
||||
return $name.' '.$this->getTypeDeclaration($field).$default.$notnull;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteCLOB()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @param bool $quote determines if the value should be quoted and escaped
|
||||
* @param bool $escape_wildcards if to escape escape wildcards
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteCLOB($value, $quote, $escape_wildcards)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
if ($db->options['lob_allow_url_include']) {
|
||||
$value = $this->_readFile($value);
|
||||
if (PEAR::isError($value)) {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
return $this->_quoteText($value, $quote, $escape_wildcards);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteBLOB()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @param bool $quote determines if the value should be quoted and escaped
|
||||
* @param bool $escape_wildcards if to escape escape wildcards
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteBLOB($value, $quote, $escape_wildcards)
|
||||
{
|
||||
if (!$quote) {
|
||||
return $value;
|
||||
}
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
if ($db->options['lob_allow_url_include']) {
|
||||
$value = $this->_readFile($value);
|
||||
if (PEAR::isError($value)) {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
if (version_compare(PHP_VERSION, '5.2.0RC6', '>=')) {
|
||||
$connection = $db->getConnection();
|
||||
if (PEAR::isError($connection)) {
|
||||
return $connection;
|
||||
}
|
||||
$value = @pg_escape_bytea($connection, $value);
|
||||
} else {
|
||||
$value = @pg_escape_bytea($value);
|
||||
}
|
||||
return "'".$value."'";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _quoteBoolean()
|
||||
|
||||
/**
|
||||
* Convert a text value into a DBMS specific format that is suitable to
|
||||
* compose query statements.
|
||||
*
|
||||
* @param string $value text string value that is intended to be converted.
|
||||
* @param bool $quote determines if the value should be quoted and escaped
|
||||
* @param bool $escape_wildcards if to escape escape wildcards
|
||||
* @return string text string that represents the given argument value in
|
||||
* a DBMS specific format.
|
||||
* @access protected
|
||||
*/
|
||||
function _quoteBoolean($value, $quote, $escape_wildcards)
|
||||
{
|
||||
$value = $value ? 't' : 'f';
|
||||
if (!$quote) {
|
||||
return $value;
|
||||
}
|
||||
return "'".$value."'";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ matchPattern()
|
||||
|
||||
/**
|
||||
* build a pattern matching string
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param array $pattern even keys are strings, odd are patterns (% and _)
|
||||
* @param string $operator optional pattern operator (LIKE, ILIKE and maybe others in the future)
|
||||
* @param string $field optional field name that is being matched against
|
||||
* (might be required when emulating ILIKE)
|
||||
*
|
||||
* @return string SQL pattern
|
||||
*/
|
||||
function matchPattern($pattern, $operator = null, $field = null)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$match = '';
|
||||
if (null !== $operator) {
|
||||
$field = (null === $field) ? '' : $field.' ';
|
||||
$operator = strtoupper($operator);
|
||||
switch ($operator) {
|
||||
// case insensitive
|
||||
case 'ILIKE':
|
||||
$match = $field.'ILIKE ';
|
||||
break;
|
||||
case 'NOT ILIKE':
|
||||
$match = $field.'NOT ILIKE ';
|
||||
break;
|
||||
// case sensitive
|
||||
case 'LIKE':
|
||||
$match = $field.'LIKE ';
|
||||
break;
|
||||
case 'NOT LIKE':
|
||||
$match = $field.'NOT LIKE ';
|
||||
break;
|
||||
default:
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'not a supported operator type:'. $operator, __FUNCTION__);
|
||||
}
|
||||
}
|
||||
$match.= "'";
|
||||
foreach ($pattern as $key => $value) {
|
||||
if ($key % 2) {
|
||||
$match.= $value;
|
||||
} else {
|
||||
$match.= $db->escapePattern($db->escape($value));
|
||||
}
|
||||
}
|
||||
$match.= "'";
|
||||
$match.= $this->patternEscapeString();
|
||||
return $match;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ patternEscapeString()
|
||||
|
||||
/**
|
||||
* build string to define escape pattern string
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
*
|
||||
* @return string define escape pattern
|
||||
*/
|
||||
function patternEscapeString()
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
return ' ESCAPE '.$this->quote($db->string_quoting['escape_pattern']);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _mapNativeDatatype()
|
||||
|
||||
/**
|
||||
* Maps a native array description of a field to a MDB2 datatype and length
|
||||
*
|
||||
* @param array $field native field description
|
||||
* @return array containing the various possible types, length, sign, fixed
|
||||
* @access public
|
||||
*/
|
||||
function _mapNativeDatatype($field)
|
||||
{
|
||||
$db_type = strtolower($field['type']);
|
||||
$length = $field['length'];
|
||||
$type = array();
|
||||
$unsigned = $fixed = null;
|
||||
switch ($db_type) {
|
||||
case 'smallint':
|
||||
case 'int2':
|
||||
$type[] = 'integer';
|
||||
$unsigned = false;
|
||||
$length = 2;
|
||||
if ($length == '2') {
|
||||
$type[] = 'boolean';
|
||||
if (preg_match('/^(is|has)/', $field['name'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'int':
|
||||
case 'int4':
|
||||
case 'integer':
|
||||
case 'serial':
|
||||
case 'serial4':
|
||||
$type[] = 'integer';
|
||||
$unsigned = false;
|
||||
$length = 4;
|
||||
break;
|
||||
case 'bigint':
|
||||
case 'int8':
|
||||
case 'bigserial':
|
||||
case 'serial8':
|
||||
$type[] = 'integer';
|
||||
$unsigned = false;
|
||||
$length = 8;
|
||||
break;
|
||||
case 'bool':
|
||||
case 'boolean':
|
||||
$type[] = 'boolean';
|
||||
$length = null;
|
||||
break;
|
||||
case 'text':
|
||||
case 'varchar':
|
||||
$fixed = false;
|
||||
case 'unknown':
|
||||
case 'char':
|
||||
case 'bpchar':
|
||||
$type[] = 'text';
|
||||
if ($length == '1') {
|
||||
$type[] = 'boolean';
|
||||
if (preg_match('/^(is|has)/', $field['name'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
} elseif (strstr($db_type, 'text')) {
|
||||
$type[] = 'clob';
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
if ($fixed !== false) {
|
||||
$fixed = true;
|
||||
}
|
||||
break;
|
||||
case 'date':
|
||||
$type[] = 'date';
|
||||
$length = null;
|
||||
break;
|
||||
case 'datetime':
|
||||
case 'timestamp':
|
||||
case 'timestamptz':
|
||||
$type[] = 'timestamp';
|
||||
$length = null;
|
||||
break;
|
||||
case 'time':
|
||||
$type[] = 'time';
|
||||
$length = null;
|
||||
break;
|
||||
case 'float':
|
||||
case 'float4':
|
||||
case 'float8':
|
||||
case 'double':
|
||||
case 'real':
|
||||
$type[] = 'float';
|
||||
break;
|
||||
case 'decimal':
|
||||
case 'money':
|
||||
case 'numeric':
|
||||
$type[] = 'decimal';
|
||||
if (isset($field['scale'])) {
|
||||
$length = $length.','.$field['scale'];
|
||||
}
|
||||
break;
|
||||
case 'tinyblob':
|
||||
case 'mediumblob':
|
||||
case 'longblob':
|
||||
case 'blob':
|
||||
case 'bytea':
|
||||
$type[] = 'blob';
|
||||
$length = null;
|
||||
break;
|
||||
case 'oid':
|
||||
$type[] = 'blob';
|
||||
$type[] = 'clob';
|
||||
$length = null;
|
||||
break;
|
||||
case 'year':
|
||||
$type[] = 'integer';
|
||||
$type[] = 'date';
|
||||
$length = null;
|
||||
break;
|
||||
default:
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'unknown database attribute type: '.$db_type, __FUNCTION__);
|
||||
}
|
||||
|
||||
if ((int)$length <= 0) {
|
||||
$length = null;
|
||||
}
|
||||
|
||||
return array($type, $length, $unsigned, $fixed);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ mapPrepareDatatype()
|
||||
|
||||
/**
|
||||
* Maps an mdb2 datatype to native prepare type
|
||||
*
|
||||
* @param string $type
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function mapPrepareDatatype($type)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (!empty($db->options['datatype_map'][$type])) {
|
||||
$type = $db->options['datatype_map'][$type];
|
||||
if (!empty($db->options['datatype_map_callback'][$type])) {
|
||||
$parameter = array('type' => $type);
|
||||
return call_user_func_array($db->options['datatype_map_callback'][$type], array(&$db, __FUNCTION__, $parameter));
|
||||
}
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'integer':
|
||||
return 'int';
|
||||
case 'boolean':
|
||||
return 'bool';
|
||||
case 'decimal':
|
||||
case 'float':
|
||||
return 'numeric';
|
||||
case 'clob':
|
||||
return 'text';
|
||||
case 'blob':
|
||||
return 'bytea';
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return $type;
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
?>
|
||||
+418
@@ -0,0 +1,418 @@
|
||||
<?php
|
||||
// vim: set et ts=4 sw=4 fdm=marker:
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2007 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his 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 |
|
||||
// | REGENTS 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Datatype/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 SQLite driver
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Datatype_sqlite extends MDB2_Driver_Datatype_Common
|
||||
{
|
||||
// {{{ _getCollationFieldDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to set the COLLATION
|
||||
* of a field declaration to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $collation name of the collation
|
||||
*
|
||||
* @return string DBMS specific SQL code portion needed to set the COLLATION
|
||||
* of a field declaration.
|
||||
*/
|
||||
function _getCollationFieldDeclaration($collation)
|
||||
{
|
||||
return 'COLLATE '.$collation;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTypeDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an text type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param array $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes. Currently, the types
|
||||
* of supported field properties are as follows:
|
||||
*
|
||||
* length
|
||||
* Integer value that determines the maximum length of the text
|
||||
* field. If this argument is missing the field should be
|
||||
* declared to have the longest length allowed by the DBMS.
|
||||
*
|
||||
* default
|
||||
* Text value to be used as default for this field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is constrained
|
||||
* to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access public
|
||||
*/
|
||||
function getTypeDeclaration($field)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
switch ($field['type']) {
|
||||
case 'text':
|
||||
$length = !empty($field['length'])
|
||||
? $field['length'] : false;
|
||||
$fixed = !empty($field['fixed']) ? $field['fixed'] : false;
|
||||
return $fixed ? ($length ? 'CHAR('.$length.')' : 'CHAR('.$db->options['default_text_field_length'].')')
|
||||
: ($length ? 'VARCHAR('.$length.')' : 'TEXT');
|
||||
case 'clob':
|
||||
if (!empty($field['length'])) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 255) {
|
||||
return 'TINYTEXT';
|
||||
} elseif ($length <= 65532) {
|
||||
return 'TEXT';
|
||||
} elseif ($length <= 16777215) {
|
||||
return 'MEDIUMTEXT';
|
||||
}
|
||||
}
|
||||
return 'LONGTEXT';
|
||||
case 'blob':
|
||||
if (!empty($field['length'])) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 255) {
|
||||
return 'TINYBLOB';
|
||||
} elseif ($length <= 65532) {
|
||||
return 'BLOB';
|
||||
} elseif ($length <= 16777215) {
|
||||
return 'MEDIUMBLOB';
|
||||
}
|
||||
}
|
||||
return 'LONGBLOB';
|
||||
case 'integer':
|
||||
if (!empty($field['length'])) {
|
||||
$length = $field['length'];
|
||||
if ($length <= 2) {
|
||||
return 'SMALLINT';
|
||||
} elseif ($length == 3 || $length == 4) {
|
||||
return 'INTEGER';
|
||||
} elseif ($length > 4) {
|
||||
return 'BIGINT';
|
||||
}
|
||||
}
|
||||
return 'INTEGER';
|
||||
case 'boolean':
|
||||
return 'BOOLEAN';
|
||||
case 'date':
|
||||
return 'DATE';
|
||||
case 'time':
|
||||
return 'TIME';
|
||||
case 'timestamp':
|
||||
return 'DATETIME';
|
||||
case 'float':
|
||||
return 'DOUBLE'.($db->options['fixed_float'] ? '('.
|
||||
($db->options['fixed_float']+2).','.$db->options['fixed_float'].')' : '');
|
||||
case 'decimal':
|
||||
$length = !empty($field['length']) ? $field['length'] : 18;
|
||||
$scale = !empty($field['scale']) ? $field['scale'] : $db->options['decimal_places'];
|
||||
return 'DECIMAL('.$length.','.$scale.')';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getIntegerDeclaration()
|
||||
|
||||
/**
|
||||
* Obtain DBMS specific SQL code portion needed to declare an integer type
|
||||
* field to be used in statements like CREATE TABLE.
|
||||
*
|
||||
* @param string $name name the field to be declared.
|
||||
* @param string $field associative array with the name of the properties
|
||||
* of the field being declared as array indexes.
|
||||
* Currently, the types of supported field
|
||||
* properties are as follows:
|
||||
*
|
||||
* unsigned
|
||||
* Boolean flag that indicates whether the field
|
||||
* should be declared as unsigned integer if
|
||||
* possible.
|
||||
*
|
||||
* default
|
||||
* Integer value to be used as default for this
|
||||
* field.
|
||||
*
|
||||
* notnull
|
||||
* Boolean flag that indicates whether this field is
|
||||
* constrained to not be set to null.
|
||||
* @return string DBMS specific SQL code portion that should be used to
|
||||
* declare the specified field.
|
||||
* @access protected
|
||||
*/
|
||||
function _getIntegerDeclaration($name, $field)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$default = $autoinc = '';
|
||||
if (!empty($field['autoincrement'])) {
|
||||
$autoinc = ' PRIMARY KEY';
|
||||
} elseif (array_key_exists('default', $field)) {
|
||||
if ($field['default'] === '') {
|
||||
$field['default'] = empty($field['notnull']) ? null : 0;
|
||||
}
|
||||
$default = ' DEFAULT '.$this->quote($field['default'], 'integer');
|
||||
}
|
||||
|
||||
$notnull = empty($field['notnull']) ? '' : ' NOT NULL';
|
||||
$unsigned = empty($field['unsigned']) ? '' : ' UNSIGNED';
|
||||
if (empty($default) && empty($notnull)) {
|
||||
$default = ' DEFAULT NULL';
|
||||
}
|
||||
$name = $db->quoteIdentifier($name, true);
|
||||
return $name.' '.$this->getTypeDeclaration($field).$unsigned.$default.$notnull.$autoinc;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ matchPattern()
|
||||
|
||||
/**
|
||||
* build a pattern matching string
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param array $pattern even keys are strings, odd are patterns (% and _)
|
||||
* @param string $operator optional pattern operator (LIKE, ILIKE and maybe others in the future)
|
||||
* @param string $field optional field name that is being matched against
|
||||
* (might be required when emulating ILIKE)
|
||||
*
|
||||
* @return string SQL pattern
|
||||
*/
|
||||
function matchPattern($pattern, $operator = null, $field = null)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$match = '';
|
||||
if (null !== $operator) {
|
||||
$field = (null === $field) ? '' : $field.' ';
|
||||
$operator = strtoupper($operator);
|
||||
switch ($operator) {
|
||||
// case insensitive
|
||||
case 'ILIKE':
|
||||
$match = $field.'LIKE ';
|
||||
break;
|
||||
case 'NOT ILIKE':
|
||||
$match = $field.'NOT LIKE ';
|
||||
break;
|
||||
// case sensitive
|
||||
case 'LIKE':
|
||||
$match = $field.'LIKE ';
|
||||
break;
|
||||
case 'NOT LIKE':
|
||||
$match = $field.'NOT LIKE ';
|
||||
break;
|
||||
default:
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'not a supported operator type:'. $operator, __FUNCTION__);
|
||||
}
|
||||
}
|
||||
$match.= "'";
|
||||
foreach ($pattern as $key => $value) {
|
||||
if ($key % 2) {
|
||||
$match.= $value;
|
||||
} else {
|
||||
$match.= $db->escapePattern($db->escape($value));
|
||||
}
|
||||
}
|
||||
$match.= "'";
|
||||
$match.= $this->patternEscapeString();
|
||||
return $match;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _mapNativeDatatype()
|
||||
|
||||
/**
|
||||
* Maps a native array description of a field to a MDB2 datatype and length
|
||||
*
|
||||
* @param array $field native field description
|
||||
* @return array containing the various possible types, length, sign, fixed
|
||||
* @access public
|
||||
*/
|
||||
function _mapNativeDatatype($field)
|
||||
{
|
||||
$db_type = strtolower($field['type']);
|
||||
$length = !empty($field['length']) ? $field['length'] : null;
|
||||
$unsigned = !empty($field['unsigned']) ? $field['unsigned'] : null;
|
||||
$fixed = null;
|
||||
$type = array();
|
||||
switch ($db_type) {
|
||||
case 'boolean':
|
||||
$type[] = 'boolean';
|
||||
break;
|
||||
case 'tinyint':
|
||||
$type[] = 'integer';
|
||||
$type[] = 'boolean';
|
||||
if (preg_match('/^(is|has)/', $field['name'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
$length = 1;
|
||||
break;
|
||||
case 'smallint':
|
||||
$type[] = 'integer';
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
$length = 2;
|
||||
break;
|
||||
case 'mediumint':
|
||||
$type[] = 'integer';
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
$length = 3;
|
||||
break;
|
||||
case 'int':
|
||||
case 'integer':
|
||||
case 'serial':
|
||||
$type[] = 'integer';
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
$length = 4;
|
||||
break;
|
||||
case 'bigint':
|
||||
case 'bigserial':
|
||||
$type[] = 'integer';
|
||||
$unsigned = preg_match('/ unsigned/i', $field['type']);
|
||||
$length = 8;
|
||||
break;
|
||||
case 'clob':
|
||||
$type[] = 'clob';
|
||||
$fixed = false;
|
||||
break;
|
||||
case 'tinytext':
|
||||
case 'mediumtext':
|
||||
case 'longtext':
|
||||
case 'text':
|
||||
case 'varchar':
|
||||
case 'varchar2':
|
||||
$fixed = false;
|
||||
case 'char':
|
||||
$type[] = 'text';
|
||||
if ($length == '1') {
|
||||
$type[] = 'boolean';
|
||||
if (preg_match('/^(is|has)/', $field['name'])) {
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
} elseif (strstr($db_type, 'text')) {
|
||||
$type[] = 'clob';
|
||||
$type = array_reverse($type);
|
||||
}
|
||||
if ($fixed !== false) {
|
||||
$fixed = true;
|
||||
}
|
||||
break;
|
||||
case 'date':
|
||||
$type[] = 'date';
|
||||
$length = null;
|
||||
break;
|
||||
case 'datetime':
|
||||
case 'timestamp':
|
||||
$type[] = 'timestamp';
|
||||
$length = null;
|
||||
break;
|
||||
case 'time':
|
||||
$type[] = 'time';
|
||||
$length = null;
|
||||
break;
|
||||
case 'float':
|
||||
case 'double':
|
||||
case 'real':
|
||||
$type[] = 'float';
|
||||
break;
|
||||
case 'decimal':
|
||||
case 'numeric':
|
||||
$type[] = 'decimal';
|
||||
$length = $length.','.$field['decimal'];
|
||||
break;
|
||||
case 'tinyblob':
|
||||
case 'mediumblob':
|
||||
case 'longblob':
|
||||
case 'blob':
|
||||
$type[] = 'blob';
|
||||
$length = null;
|
||||
break;
|
||||
case 'year':
|
||||
$type[] = 'integer';
|
||||
$type[] = 'date';
|
||||
$length = null;
|
||||
break;
|
||||
default:
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'unknown database attribute type: '.$db_type, __FUNCTION__);
|
||||
}
|
||||
|
||||
if ((int)$length <= 0) {
|
||||
$length = null;
|
||||
}
|
||||
|
||||
return array($type, $length, $unsigned, $fixed);
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
?>
|
||||
+293
@@ -0,0 +1,293 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2006 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his 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 |
|
||||
// | REGENTS 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
/**
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for the function modules that is extended by each MDB2 driver
|
||||
*
|
||||
* To load this module in the MDB2 object:
|
||||
* $mdb->loadModule('Function');
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Function_Common extends MDB2_Module_Common
|
||||
{
|
||||
// {{{ executeStoredProc()
|
||||
|
||||
/**
|
||||
* Execute a stored procedure and return any results
|
||||
*
|
||||
* @param string $name string that identifies the function to execute
|
||||
* @param mixed $params array that contains the paramaters to pass the stored proc
|
||||
* @param mixed $types array that contains the types of the columns in
|
||||
* the result set
|
||||
* @param mixed $result_class string which specifies which result class to use
|
||||
* @param mixed $result_wrap_class string which specifies which class to wrap results in
|
||||
*
|
||||
* @return mixed a result handle or MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function executeStoredProc($name, $params = null, $types = null, $result_class = true, $result_wrap_class = false)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$error = $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'method not implemented', __FUNCTION__);
|
||||
return $error;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ functionTable()
|
||||
|
||||
/**
|
||||
* return string for internal table used when calling only a function
|
||||
*
|
||||
* @return string for internal table used when calling only a function
|
||||
* @access public
|
||||
*/
|
||||
function functionTable()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ now()
|
||||
|
||||
/**
|
||||
* Return string to call a variable with the current timestamp inside an SQL statement
|
||||
* There are three special variables for current date and time:
|
||||
* - CURRENT_TIMESTAMP (date and time, TIMESTAMP type)
|
||||
* - CURRENT_DATE (date, DATE type)
|
||||
* - CURRENT_TIME (time, TIME type)
|
||||
*
|
||||
* @param string $type 'timestamp' | 'time' | 'date'
|
||||
*
|
||||
* @return string to call a variable with the current timestamp
|
||||
* @access public
|
||||
*/
|
||||
function now($type = 'timestamp')
|
||||
{
|
||||
switch ($type) {
|
||||
case 'time':
|
||||
return 'CURRENT_TIME';
|
||||
case 'date':
|
||||
return 'CURRENT_DATE';
|
||||
case 'timestamp':
|
||||
default:
|
||||
return 'CURRENT_TIMESTAMP';
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ unixtimestamp()
|
||||
|
||||
/**
|
||||
* return string to call a function to get the unix timestamp from a iso timestamp
|
||||
*
|
||||
* @param string $expression
|
||||
*
|
||||
* @return string to call a variable with the timestamp
|
||||
* @access public
|
||||
*/
|
||||
function unixtimestamp($expression)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$error = $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'method not implemented', __FUNCTION__);
|
||||
return $error;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ substring()
|
||||
|
||||
/**
|
||||
* return string to call a function to get a substring inside an SQL statement
|
||||
*
|
||||
* @return string to call a function to get a substring
|
||||
* @access public
|
||||
*/
|
||||
function substring($value, $position = 1, $length = null)
|
||||
{
|
||||
if (null !== $length) {
|
||||
return "SUBSTRING($value FROM $position FOR $length)";
|
||||
}
|
||||
return "SUBSTRING($value FROM $position)";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ replace()
|
||||
|
||||
/**
|
||||
* return string to call a function to get replace inside an SQL statement.
|
||||
*
|
||||
* @return string to call a function to get a replace
|
||||
* @access public
|
||||
*/
|
||||
function replace($str, $from_str, $to_str)
|
||||
{
|
||||
return "REPLACE($str, $from_str , $to_str)";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ concat()
|
||||
|
||||
/**
|
||||
* Returns string to concatenate two or more string parameters
|
||||
*
|
||||
* @param string $value1
|
||||
* @param string $value2
|
||||
* @param string $values...
|
||||
*
|
||||
* @return string to concatenate two strings
|
||||
* @access public
|
||||
*/
|
||||
function concat($value1, $value2)
|
||||
{
|
||||
$args = func_get_args();
|
||||
return "(".implode(' || ', $args).")";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ random()
|
||||
|
||||
/**
|
||||
* return string to call a function to get random value inside an SQL statement
|
||||
*
|
||||
* @return return string to generate float between 0 and 1
|
||||
* @access public
|
||||
*/
|
||||
function random()
|
||||
{
|
||||
return 'RAND()';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ lower()
|
||||
|
||||
/**
|
||||
* return string to call a function to lower the case of an expression
|
||||
*
|
||||
* @param string $expression
|
||||
*
|
||||
* @return return string to lower case of an expression
|
||||
* @access public
|
||||
*/
|
||||
function lower($expression)
|
||||
{
|
||||
return "LOWER($expression)";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ upper()
|
||||
|
||||
/**
|
||||
* return string to call a function to upper the case of an expression
|
||||
*
|
||||
* @param string $expression
|
||||
*
|
||||
* @return return string to upper case of an expression
|
||||
* @access public
|
||||
*/
|
||||
function upper($expression)
|
||||
{
|
||||
return "UPPER($expression)";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ length()
|
||||
|
||||
/**
|
||||
* return string to call a function to get the length of a string expression
|
||||
*
|
||||
* @param string $expression
|
||||
*
|
||||
* @return return string to get the string expression length
|
||||
* @access public
|
||||
*/
|
||||
function length($expression)
|
||||
{
|
||||
return "LENGTH($expression)";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ guid()
|
||||
|
||||
/**
|
||||
* Returns global unique identifier
|
||||
*
|
||||
* @return string to get global unique identifier
|
||||
* @access public
|
||||
*/
|
||||
function guid()
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$error = $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'method not implemented', __FUNCTION__);
|
||||
return $error;
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
?>
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2008 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his 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 |
|
||||
// | REGENTS 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Function/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 MySQL driver for the function modules
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Function_mysql extends MDB2_Driver_Function_Common
|
||||
{
|
||||
// }}}
|
||||
// {{{ executeStoredProc()
|
||||
|
||||
/**
|
||||
* Execute a stored procedure and return any results
|
||||
*
|
||||
* @param string $name string that identifies the function to execute
|
||||
* @param mixed $params array that contains the paramaters to pass the stored proc
|
||||
* @param mixed $types array that contains the types of the columns in
|
||||
* the result set
|
||||
* @param mixed $result_class string which specifies which result class to use
|
||||
* @param mixed $result_wrap_class string which specifies which class to wrap results in
|
||||
* @return mixed a result handle or MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function executeStoredProc($name, $params = null, $types = null, $result_class = true, $result_wrap_class = false)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'CALL '.$name;
|
||||
$query .= $params ? '('.implode(', ', $params).')' : '()';
|
||||
return $db->query($query, $types, $result_class, $result_wrap_class);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ unixtimestamp()
|
||||
|
||||
/**
|
||||
* return string to call a function to get the unix timestamp from a iso timestamp
|
||||
*
|
||||
* @param string $expression
|
||||
*
|
||||
* @return string to call a variable with the timestamp
|
||||
* @access public
|
||||
*/
|
||||
function unixtimestamp($expression)
|
||||
{
|
||||
return 'UNIX_TIMESTAMP('. $expression.')';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ concat()
|
||||
|
||||
/**
|
||||
* Returns string to concatenate two or more string parameters
|
||||
*
|
||||
* @param string $value1
|
||||
* @param string $value2
|
||||
* @param string $values...
|
||||
* @return string to concatenate two strings
|
||||
* @access public
|
||||
**/
|
||||
function concat($value1, $value2)
|
||||
{
|
||||
$args = func_get_args();
|
||||
return "CONCAT(".implode(', ', $args).")";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ guid()
|
||||
|
||||
/**
|
||||
* Returns global unique identifier
|
||||
*
|
||||
* @return string to get global unique identifier
|
||||
* @access public
|
||||
*/
|
||||
function guid()
|
||||
{
|
||||
return 'UUID()';
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
?>
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2008 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his 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 |
|
||||
// | REGENTS 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Paul Cooper <pgc@ucecom.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
|
||||
require_once 'MDB2/Driver/Function/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 MySQL driver for the function modules
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Function_pgsql extends MDB2_Driver_Function_Common
|
||||
{
|
||||
// {{{ executeStoredProc()
|
||||
|
||||
/**
|
||||
* Execute a stored procedure and return any results
|
||||
*
|
||||
* @param string $name string that identifies the function to execute
|
||||
* @param mixed $params array that contains the paramaters to pass the stored proc
|
||||
* @param mixed $types array that contains the types of the columns in
|
||||
* the result set
|
||||
* @param mixed $result_class string which specifies which result class to use
|
||||
* @param mixed $result_wrap_class string which specifies which class to wrap results in
|
||||
* @return mixed a result handle or MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function executeStoredProc($name, $params = null, $types = null, $result_class = true, $result_wrap_class = false)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'SELECT * FROM '.$name;
|
||||
$query .= $params ? '('.implode(', ', $params).')' : '()';
|
||||
return $db->query($query, $types, $result_class, $result_wrap_class);
|
||||
}
|
||||
// }}}
|
||||
// {{{ unixtimestamp()
|
||||
|
||||
/**
|
||||
* return string to call a function to get the unix timestamp from a iso timestamp
|
||||
*
|
||||
* @param string $expression
|
||||
*
|
||||
* @return string to call a variable with the timestamp
|
||||
* @access public
|
||||
*/
|
||||
function unixtimestamp($expression)
|
||||
{
|
||||
return 'EXTRACT(EPOCH FROM DATE_TRUNC(\'seconds\', CAST ((' . $expression . ') AS TIMESTAMP)))';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ substring()
|
||||
|
||||
/**
|
||||
* return string to call a function to get a substring inside an SQL statement
|
||||
*
|
||||
* @return string to call a function to get a substring
|
||||
* @access public
|
||||
*/
|
||||
function substring($value, $position = 1, $length = null)
|
||||
{
|
||||
if (null !== $length) {
|
||||
return "SUBSTRING(CAST($value AS VARCHAR) FROM $position FOR $length)";
|
||||
}
|
||||
return "SUBSTRING(CAST($value AS VARCHAR) FROM $position)";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ random()
|
||||
|
||||
/**
|
||||
* return string to call a function to get random value inside an SQL statement
|
||||
*
|
||||
* @return return string to generate float between 0 and 1
|
||||
* @access public
|
||||
*/
|
||||
function random()
|
||||
{
|
||||
return 'RANDOM()';
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
?>
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2008 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his 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 |
|
||||
// | REGENTS 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Function/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 SQLite driver for the function modules
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Function_sqlite extends MDB2_Driver_Function_Common
|
||||
{
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function __construct($db_index)
|
||||
{
|
||||
parent::__construct($db_index);
|
||||
// create all sorts of UDFs
|
||||
}
|
||||
|
||||
// {{{ now()
|
||||
|
||||
/**
|
||||
* Return string to call a variable with the current timestamp inside an SQL statement
|
||||
* There are three special variables for current date and time.
|
||||
*
|
||||
* @return string to call a variable with the current timestamp
|
||||
* @access public
|
||||
*/
|
||||
function now($type = 'timestamp')
|
||||
{
|
||||
switch ($type) {
|
||||
case 'time':
|
||||
return 'time(\'now\')';
|
||||
case 'date':
|
||||
return 'date(\'now\')';
|
||||
case 'timestamp':
|
||||
default:
|
||||
return 'datetime(\'now\')';
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ unixtimestamp()
|
||||
|
||||
/**
|
||||
* return string to call a function to get the unix timestamp from a iso timestamp
|
||||
*
|
||||
* @param string $expression
|
||||
*
|
||||
* @return string to call a variable with the timestamp
|
||||
* @access public
|
||||
*/
|
||||
function unixtimestamp($expression)
|
||||
{
|
||||
return 'strftime("%s",'. $expression.', "utc")';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ substring()
|
||||
|
||||
/**
|
||||
* return string to call a function to get a substring inside an SQL statement
|
||||
*
|
||||
* @return string to call a function to get a substring
|
||||
* @access public
|
||||
*/
|
||||
function substring($value, $position = 1, $length = null)
|
||||
{
|
||||
if (null !== $length) {
|
||||
return "substr($value, $position, $length)";
|
||||
}
|
||||
return "substr($value, $position, length($value))";
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ random()
|
||||
|
||||
/**
|
||||
* return string to call a function to get random value inside an SQL statement
|
||||
*
|
||||
* @return return string to generate float between 0 and 1
|
||||
* @access public
|
||||
*/
|
||||
function random()
|
||||
{
|
||||
return '((RANDOM()+2147483648)/4294967296)';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ replace()
|
||||
|
||||
/**
|
||||
* return string to call a function to get a replacement inside an SQL statement.
|
||||
*
|
||||
* @return string to call a function to get a replace
|
||||
* @access public
|
||||
*/
|
||||
function replace($str, $from_str, $to_str)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$error = $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'method not implemented', __FUNCTION__);
|
||||
return $error;
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
?>
|
||||
+1038
File diff suppressed because it is too large
Load Diff
+1471
File diff suppressed because it is too large
Load Diff
+981
@@ -0,0 +1,981 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2008 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his 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 |
|
||||
// | REGENTS 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Paul Cooper <pgc@ucecom.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
|
||||
require_once 'MDB2/Driver/Manager/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 MySQL driver for the management modules
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Paul Cooper <pgc@ucecom.com>
|
||||
*/
|
||||
class MDB2_Driver_Manager_pgsql extends MDB2_Driver_Manager_Common
|
||||
{
|
||||
// {{{ createDatabase()
|
||||
|
||||
/**
|
||||
* create a new database
|
||||
*
|
||||
* @param string $name name of the database that should be created
|
||||
* @param array $options array with charset info
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createDatabase($name, $options = array())
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$name = $db->quoteIdentifier($name, true);
|
||||
$query = 'CREATE DATABASE ' . $name;
|
||||
if (!empty($options['charset'])) {
|
||||
$query .= ' WITH ENCODING ' . $db->quote($options['charset'], 'text');
|
||||
}
|
||||
return $db->standaloneQuery($query, null, true);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ alterDatabase()
|
||||
|
||||
/**
|
||||
* alter an existing database
|
||||
*
|
||||
* @param string $name name of the database that is intended to be changed
|
||||
* @param array $options array with name, owner info
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function alterDatabase($name, $options = array())
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = '';
|
||||
if (!empty($options['name'])) {
|
||||
$query .= ' RENAME TO ' . $options['name'];
|
||||
}
|
||||
if (!empty($options['owner'])) {
|
||||
$query .= ' OWNER TO ' . $options['owner'];
|
||||
}
|
||||
|
||||
if (empty($query)) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
$query = 'ALTER DATABASE '. $db->quoteIdentifier($name, true) . $query;
|
||||
return $db->standaloneQuery($query, null, true);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropDatabase()
|
||||
|
||||
/**
|
||||
* drop an existing database
|
||||
*
|
||||
* @param string $name name of the database that should be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropDatabase($name)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$name = $db->quoteIdentifier($name, true);
|
||||
$query = "DROP DATABASE $name";
|
||||
return $db->standaloneQuery($query, null, true);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getAdvancedFKOptions()
|
||||
|
||||
/**
|
||||
* Return the FOREIGN KEY query section dealing with non-standard options
|
||||
* as MATCH, INITIALLY DEFERRED, ON UPDATE, ...
|
||||
*
|
||||
* @param array $definition
|
||||
* @return string
|
||||
* @access protected
|
||||
*/
|
||||
function _getAdvancedFKOptions($definition)
|
||||
{
|
||||
$query = '';
|
||||
if (!empty($definition['match'])) {
|
||||
$query .= ' MATCH '.$definition['match'];
|
||||
}
|
||||
if (!empty($definition['onupdate'])) {
|
||||
$query .= ' ON UPDATE '.$definition['onupdate'];
|
||||
}
|
||||
if (!empty($definition['ondelete'])) {
|
||||
$query .= ' ON DELETE '.$definition['ondelete'];
|
||||
}
|
||||
if (!empty($definition['deferrable'])) {
|
||||
$query .= ' DEFERRABLE';
|
||||
} else {
|
||||
$query .= ' NOT DEFERRABLE';
|
||||
}
|
||||
if (!empty($definition['initiallydeferred'])) {
|
||||
$query .= ' INITIALLY DEFERRED';
|
||||
} else {
|
||||
$query .= ' INITIALLY IMMEDIATE';
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ truncateTable()
|
||||
|
||||
/**
|
||||
* Truncate an existing table (if the TRUNCATE TABLE syntax is not supported,
|
||||
* it falls back to a DELETE FROM TABLE query)
|
||||
*
|
||||
* @param string $name name of the table that should be truncated
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function truncateTable($name)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$name = $db->quoteIdentifier($name, true);
|
||||
$result = $db->exec("TRUNCATE TABLE $name");
|
||||
if (MDB2::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ vacuum()
|
||||
|
||||
/**
|
||||
* Optimize (vacuum) all the tables in the db (or only the specified table)
|
||||
* and optionally run ANALYZE.
|
||||
*
|
||||
* @param string $table table name (all the tables if empty)
|
||||
* @param array $options an array with driver-specific options:
|
||||
* - timeout [int] (in seconds) [mssql-only]
|
||||
* - analyze [boolean] [pgsql and mysql]
|
||||
* - full [boolean] [pgsql-only]
|
||||
* - freeze [boolean] [pgsql-only]
|
||||
*
|
||||
* @return mixed MDB2_OK success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function vacuum($table = null, $options = array())
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
$query = 'VACUUM';
|
||||
|
||||
if (!empty($options['full'])) {
|
||||
$query .= ' FULL';
|
||||
}
|
||||
if (!empty($options['freeze'])) {
|
||||
$query .= ' FREEZE';
|
||||
}
|
||||
if (!empty($options['analyze'])) {
|
||||
$query .= ' ANALYZE';
|
||||
}
|
||||
|
||||
if (!empty($table)) {
|
||||
$query .= ' '.$db->quoteIdentifier($table, true);
|
||||
}
|
||||
$result = $db->exec($query);
|
||||
if (MDB2::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ alterTable()
|
||||
|
||||
/**
|
||||
* alter an existing table
|
||||
*
|
||||
* @param string $name name of the table that is intended to be changed.
|
||||
* @param array $changes associative array that contains the details of each type
|
||||
* of change that is intended to be performed. The types of
|
||||
* changes that are currently supported are defined as follows:
|
||||
*
|
||||
* name
|
||||
*
|
||||
* New name for the table.
|
||||
*
|
||||
* add
|
||||
*
|
||||
* Associative array with the names of fields to be added as
|
||||
* indexes of the array. The value of each entry of the array
|
||||
* should be set to another associative array with the properties
|
||||
* of the fields to be added. The properties of the fields should
|
||||
* be the same as defined by the MDB2 parser.
|
||||
*
|
||||
*
|
||||
* remove
|
||||
*
|
||||
* Associative array with the names of fields to be removed as indexes
|
||||
* of the array. Currently the values assigned to each entry are ignored.
|
||||
* An empty array should be used for future compatibility.
|
||||
*
|
||||
* rename
|
||||
*
|
||||
* Associative array with the names of fields to be renamed as indexes
|
||||
* of the array. The value of each entry of the array should be set to
|
||||
* another associative array with the entry named name with the new
|
||||
* field name and the entry named Declaration that is expected to contain
|
||||
* the portion of the field declaration already in DBMS specific SQL code
|
||||
* as it is used in the CREATE TABLE statement.
|
||||
*
|
||||
* change
|
||||
*
|
||||
* Associative array with the names of the fields to be changed as indexes
|
||||
* of the array. Keep in mind that if it is intended to change either the
|
||||
* name of a field and any other properties, the change array entries
|
||||
* should have the new names of the fields as array indexes.
|
||||
*
|
||||
* The value of each entry of the array should be set to another associative
|
||||
* array with the properties of the fields to that are meant to be changed as
|
||||
* array entries. These entries should be assigned to the new values of the
|
||||
* respective properties. The properties of the fields should be the same
|
||||
* as defined by the MDB2 parser.
|
||||
*
|
||||
* Example
|
||||
* array(
|
||||
* 'name' => 'userlist',
|
||||
* 'add' => array(
|
||||
* 'quota' => array(
|
||||
* 'type' => 'integer',
|
||||
* 'unsigned' => 1
|
||||
* )
|
||||
* ),
|
||||
* 'remove' => array(
|
||||
* 'file_limit' => array(),
|
||||
* 'time_limit' => array()
|
||||
* ),
|
||||
* 'change' => array(
|
||||
* 'name' => array(
|
||||
* 'length' => '20',
|
||||
* 'definition' => array(
|
||||
* 'type' => 'text',
|
||||
* 'length' => 20,
|
||||
* ),
|
||||
* )
|
||||
* ),
|
||||
* 'rename' => array(
|
||||
* 'sex' => array(
|
||||
* 'name' => 'gender',
|
||||
* 'definition' => array(
|
||||
* 'type' => 'text',
|
||||
* 'length' => 1,
|
||||
* 'default' => 'M',
|
||||
* ),
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
*
|
||||
* @param boolean $check indicates whether the function should just check if the DBMS driver
|
||||
* can perform the requested table alterations if the value is true or
|
||||
* actually perform them otherwise.
|
||||
* @access public
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
*/
|
||||
function alterTable($name, $changes, $check)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
foreach ($changes as $change_name => $change) {
|
||||
switch ($change_name) {
|
||||
case 'add':
|
||||
case 'remove':
|
||||
case 'change':
|
||||
case 'name':
|
||||
case 'rename':
|
||||
break;
|
||||
default:
|
||||
return $db->raiseError(MDB2_ERROR_CANNOT_ALTER, null, null,
|
||||
'change type "'.$change_name.'\" not yet supported', __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
if ($check) {
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
$name = $db->quoteIdentifier($name, true);
|
||||
|
||||
if (!empty($changes['remove']) && is_array($changes['remove'])) {
|
||||
foreach ($changes['remove'] as $field_name => $field) {
|
||||
$field_name = $db->quoteIdentifier($field_name, true);
|
||||
$query = 'DROP ' . $field_name;
|
||||
$result = $db->exec("ALTER TABLE $name $query");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($changes['rename']) && is_array($changes['rename'])) {
|
||||
foreach ($changes['rename'] as $field_name => $field) {
|
||||
$field_name = $db->quoteIdentifier($field_name, true);
|
||||
$result = $db->exec("ALTER TABLE $name RENAME COLUMN $field_name TO ".$db->quoteIdentifier($field['name'], true));
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($changes['add']) && is_array($changes['add'])) {
|
||||
foreach ($changes['add'] as $field_name => $field) {
|
||||
$query = 'ADD ' . $db->getDeclaration($field['type'], $field_name, $field);
|
||||
$result = $db->exec("ALTER TABLE $name $query");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($changes['change']) && is_array($changes['change'])) {
|
||||
foreach ($changes['change'] as $field_name => $field) {
|
||||
$field_name = $db->quoteIdentifier($field_name, true);
|
||||
if (!empty($field['definition']['type'])) {
|
||||
$server_info = $db->getServerVersion();
|
||||
if (PEAR::isError($server_info)) {
|
||||
return $server_info;
|
||||
}
|
||||
if (is_array($server_info) && $server_info['major'] < 8) {
|
||||
return $db->raiseError(MDB2_ERROR_CANNOT_ALTER, null, null,
|
||||
'changing column type for "'.$change_name.'\" requires PostgreSQL 8.0 or above', __FUNCTION__);
|
||||
}
|
||||
$db->loadModule('Datatype', null, true);
|
||||
$type = $db->datatype->getTypeDeclaration($field['definition']);
|
||||
if($type=='SERIAL PRIMARY KEY'){//not correct when altering a table, since serials arent a real type
|
||||
$type='INTEGER';//use integer instead
|
||||
}
|
||||
$query = "ALTER $field_name TYPE $type USING CAST($field_name AS $type)";
|
||||
$result = $db->exec("ALTER TABLE $name $query");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
if (array_key_exists('default', $field['definition'])) {
|
||||
$query = "ALTER $field_name SET DEFAULT ".$db->quote($field['definition']['default'], $field['definition']['type']);
|
||||
$result = $db->exec("ALTER TABLE $name $query");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
if (array_key_exists('notnull', $field['definition'])) {
|
||||
$query = "ALTER $field_name ".($field['definition']['notnull'] ? 'SET' : 'DROP').' NOT NULL';
|
||||
$result = $db->exec("ALTER TABLE $name $query");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($changes['name'])) {
|
||||
$change_name = $db->quoteIdentifier($changes['name'], true);
|
||||
$result = $db->exec("ALTER TABLE $name RENAME TO ".$change_name);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listDatabases()
|
||||
|
||||
/**
|
||||
* list all databases
|
||||
*
|
||||
* @return mixed array of database names on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listDatabases()
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'SELECT datname FROM pg_database';
|
||||
$result2 = $db->standaloneQuery($query, array('text'), false);
|
||||
if (!MDB2::isResultCommon($result2)) {
|
||||
return $result2;
|
||||
}
|
||||
|
||||
$result = $result2->fetchCol();
|
||||
$result2->free();
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listUsers()
|
||||
|
||||
/**
|
||||
* list all users
|
||||
*
|
||||
* @return mixed array of user names on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listUsers()
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'SELECT usename FROM pg_user';
|
||||
$result2 = $db->standaloneQuery($query, array('text'), false);
|
||||
if (!MDB2::isResultCommon($result2)) {
|
||||
return $result2;
|
||||
}
|
||||
|
||||
$result = $result2->fetchCol();
|
||||
$result2->free();
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listViews()
|
||||
|
||||
/**
|
||||
* list all views in the current database
|
||||
*
|
||||
* @return mixed array of view names on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listViews($database = null)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = "SELECT viewname
|
||||
FROM pg_views
|
||||
WHERE schemaname NOT IN ('pg_catalog', 'information_schema')
|
||||
AND viewname !~ '^pg_'";
|
||||
$result = $db->queryCol($query);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableViews()
|
||||
|
||||
/**
|
||||
* list the views in the database that reference a given table
|
||||
*
|
||||
* @param string table for which all referenced views should be found
|
||||
* @return mixed array of view names on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableViews($table)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'SELECT viewname FROM pg_views NATURAL JOIN pg_tables';
|
||||
$query.= ' WHERE tablename ='.$db->quote($table, 'text');
|
||||
$result = $db->queryCol($query);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listFunctions()
|
||||
|
||||
/**
|
||||
* list all functions in the current database
|
||||
*
|
||||
* @return mixed array of function names on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listFunctions()
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = "
|
||||
SELECT
|
||||
proname
|
||||
FROM
|
||||
pg_proc pr,
|
||||
pg_type tp
|
||||
WHERE
|
||||
tp.oid = pr.prorettype
|
||||
AND pr.proisagg = FALSE
|
||||
AND tp.typname <> 'trigger'
|
||||
AND pr.pronamespace IN
|
||||
(SELECT oid FROM pg_namespace WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema')";
|
||||
$result = $db->queryCol($query);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableTriggers()
|
||||
|
||||
/**
|
||||
* list all triggers in the database that reference a given table
|
||||
*
|
||||
* @param string table for which all referenced triggers should be found
|
||||
* @return mixed array of trigger names on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableTriggers($table = null)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'SELECT trg.tgname AS trigger_name
|
||||
FROM pg_trigger trg,
|
||||
pg_class tbl
|
||||
WHERE trg.tgrelid = tbl.oid';
|
||||
if (null !== $table) {
|
||||
$table = $db->quote(strtoupper($table), 'text');
|
||||
$query .= " AND UPPER(tbl.relname) = $table";
|
||||
}
|
||||
$result = $db->queryCol($query);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTables()
|
||||
|
||||
/**
|
||||
* list all tables in the current database
|
||||
*
|
||||
* @return mixed array of table names on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTables($database = null)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
// gratuitously stolen from PEAR DB _getSpecialQuery in pgsql.php
|
||||
$query = 'SELECT c.relname AS "Name"'
|
||||
. ' FROM pg_class c, pg_user u'
|
||||
. ' WHERE c.relowner = u.usesysid'
|
||||
. " AND c.relkind = 'r'"
|
||||
. ' AND NOT EXISTS'
|
||||
. ' (SELECT 1 FROM pg_views'
|
||||
. ' WHERE viewname = c.relname)'
|
||||
. " AND c.relname !~ '^(pg_|sql_)'"
|
||||
. ' UNION'
|
||||
. ' SELECT c.relname AS "Name"'
|
||||
. ' FROM pg_class c'
|
||||
. " WHERE c.relkind = 'r'"
|
||||
. ' AND NOT EXISTS'
|
||||
. ' (SELECT 1 FROM pg_views'
|
||||
. ' WHERE viewname = c.relname)'
|
||||
. ' AND NOT EXISTS'
|
||||
. ' (SELECT 1 FROM pg_user'
|
||||
. ' WHERE usesysid = c.relowner)'
|
||||
. " AND c.relname !~ '^pg_'";
|
||||
$result = $db->queryCol($query);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableFields()
|
||||
|
||||
/**
|
||||
* list all fields in a table in the current database
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed array of field names on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableFields($table)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table);
|
||||
|
||||
$table = $db->quoteIdentifier($table, true);
|
||||
if (!empty($schema)) {
|
||||
$table = $db->quoteIdentifier($schema, true) . '.' .$table;
|
||||
}
|
||||
$db->setLimit(1);
|
||||
$result2 = $db->query("SELECT * FROM $table");
|
||||
if (PEAR::isError($result2)) {
|
||||
return $result2;
|
||||
}
|
||||
$result = $result2->getColumnNames();
|
||||
$result2->free();
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
return array_flip($result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableIndexes()
|
||||
|
||||
/**
|
||||
* list all indexes in a table
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed array of index names on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableIndexes($table)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table);
|
||||
|
||||
$table = $db->quote($table, 'text');
|
||||
$subquery = "SELECT indexrelid
|
||||
FROM pg_index
|
||||
LEFT JOIN pg_class ON pg_class.oid = pg_index.indrelid
|
||||
LEFT JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid
|
||||
WHERE pg_class.relname = $table
|
||||
AND indisunique != 't'
|
||||
AND indisprimary != 't'";
|
||||
if (!empty($schema)) {
|
||||
$subquery .= ' AND pg_namespace.nspname = '.$db->quote($schema, 'text');
|
||||
}
|
||||
$query = "SELECT relname FROM pg_class WHERE oid IN ($subquery)";
|
||||
$indexes = $db->queryCol($query, 'text');
|
||||
if (PEAR::isError($indexes)) {
|
||||
return $indexes;
|
||||
}
|
||||
|
||||
$result = array();
|
||||
foreach ($indexes as $index) {
|
||||
$index = $this->_fixIndexName($index);
|
||||
if (!empty($index)) {
|
||||
$result[$index] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$result = array_change_key_case($result, $db->options['field_case']);
|
||||
}
|
||||
return array_keys($result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropConstraint()
|
||||
|
||||
/**
|
||||
* drop existing constraint
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $name name of the constraint to be dropped
|
||||
* @param string $primary hint if the constraint is primary
|
||||
*
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropConstraint($table, $name, $primary = false)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
// is it an UNIQUE index?
|
||||
$query = 'SELECT relname
|
||||
FROM pg_class
|
||||
WHERE oid IN (
|
||||
SELECT indexrelid
|
||||
FROM pg_index, pg_class
|
||||
WHERE pg_class.relname = '.$db->quote($table, 'text').'
|
||||
AND pg_class.oid = pg_index.indrelid
|
||||
AND indisunique = \'t\')
|
||||
EXCEPT
|
||||
SELECT conname
|
||||
FROM pg_constraint, pg_class
|
||||
WHERE pg_constraint.conrelid = pg_class.oid
|
||||
AND relname = '. $db->quote($table, 'text');
|
||||
$unique = $db->queryCol($query, 'text');
|
||||
if (PEAR::isError($unique) || empty($unique)) {
|
||||
// not an UNIQUE index, maybe a CONSTRAINT
|
||||
return parent::dropConstraint($table, $name, $primary);
|
||||
}
|
||||
|
||||
if (in_array($name, $unique)) {
|
||||
$result = $db->exec('DROP INDEX '.$db->quoteIdentifier($name, true));
|
||||
if (MDB2::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
$idxname = $db->getIndexName($name);
|
||||
if (in_array($idxname, $unique)) {
|
||||
$result = $db->exec('DROP INDEX '.$db->quoteIdentifier($idxname, true));
|
||||
if (MDB2::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
$name . ' is not an existing constraint for table ' . $table, __FUNCTION__);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listTableConstraints()
|
||||
|
||||
/**
|
||||
* list all constraints in a table
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @return mixed array of constraint names on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listTableConstraints($table)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table);
|
||||
|
||||
$table = $db->quote($table, 'text');
|
||||
$query = 'SELECT conname
|
||||
FROM pg_constraint
|
||||
LEFT JOIN pg_class ON pg_constraint.conrelid = pg_class.oid
|
||||
LEFT JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid
|
||||
WHERE relname = ' .$table;
|
||||
if (!empty($schema)) {
|
||||
$query .= ' AND pg_namespace.nspname = ' . $db->quote($schema, 'text');
|
||||
}
|
||||
$query .= '
|
||||
UNION DISTINCT
|
||||
SELECT relname
|
||||
FROM pg_class
|
||||
WHERE oid IN (
|
||||
SELECT indexrelid
|
||||
FROM pg_index
|
||||
LEFT JOIN pg_class ON pg_class.oid = pg_index.indrelid
|
||||
LEFT JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid
|
||||
WHERE pg_class.relname = '.$table.'
|
||||
AND indisunique = \'t\'';
|
||||
if (!empty($schema)) {
|
||||
$query .= ' AND pg_namespace.nspname = ' . $db->quote($schema, 'text');
|
||||
}
|
||||
$query .= ')';
|
||||
$constraints = $db->queryCol($query);
|
||||
if (PEAR::isError($constraints)) {
|
||||
return $constraints;
|
||||
}
|
||||
|
||||
$result = array();
|
||||
foreach ($constraints as $constraint) {
|
||||
$constraint = $this->_fixIndexName($constraint);
|
||||
if (!empty($constraint)) {
|
||||
$result[$constraint] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE
|
||||
&& $db->options['field_case'] == CASE_LOWER
|
||||
) {
|
||||
$result = array_change_key_case($result, $db->options['field_case']);
|
||||
}
|
||||
return array_keys($result);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ createSequence()
|
||||
|
||||
/**
|
||||
* create sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be created
|
||||
* @param string $start start value of the sequence; default is 1
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function createSequence($seq_name, $start = 1)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$sequence_name = $db->quoteIdentifier($db->getSequenceName($seq_name), true);
|
||||
$result = $db->exec("CREATE SEQUENCE $sequence_name INCREMENT 1".
|
||||
($start < 1 ? " MINVALUE $start" : '')." START $start");
|
||||
if (MDB2::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dropSequence()
|
||||
|
||||
/**
|
||||
* drop existing sequence
|
||||
*
|
||||
* @param string $seq_name name of the sequence to be dropped
|
||||
* @return mixed MDB2_OK on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function dropSequence($seq_name)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$sequence_name = $db->quoteIdentifier($db->getSequenceName($seq_name), true);
|
||||
$result = $db->exec("DROP SEQUENCE $sequence_name");
|
||||
if (MDB2::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listSequences()
|
||||
|
||||
/**
|
||||
* list all sequences in the current database
|
||||
*
|
||||
* @return mixed array of sequence names on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function listSequences($database = null)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = "SELECT relname FROM pg_class WHERE relkind = 'S' AND relnamespace IN";
|
||||
$query.= "(SELECT oid FROM pg_namespace WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema')";
|
||||
$table_names = $db->queryCol($query);
|
||||
if (PEAR::isError($table_names)) {
|
||||
return $table_names;
|
||||
}
|
||||
$result = array();
|
||||
foreach ($table_names as $table_name) {
|
||||
$result[] = $this->_fixSequenceName($table_name);
|
||||
}
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
?>
|
||||
+1390
File diff suppressed because it is too large
Load Diff
+61
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2006 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his 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 |
|
||||
// | REGENTS 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
/**
|
||||
* Base class for the natuve modules that is extended by each MDB2 driver
|
||||
*
|
||||
* To load this module in the MDB2 object:
|
||||
* $mdb->loadModule('Native');
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Native_Common extends MDB2_Module_Common
|
||||
{
|
||||
}
|
||||
?>
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2006 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his 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 |
|
||||
// | REGENTS 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Native/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 MySQL driver for the native module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Native_mysql extends MDB2_Driver_Native_Common
|
||||
{
|
||||
}
|
||||
?>
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2006 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his 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 |
|
||||
// | REGENTS 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Paul Cooper <pgc@ucecom.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
|
||||
require_once 'MDB2/Driver/Native/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 PostGreSQL driver for the native module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Paul Cooper <pgc@ucecom.com>
|
||||
*/
|
||||
class MDB2_Driver_Native_pgsql extends MDB2_Driver_Native_Common
|
||||
{
|
||||
// }}}
|
||||
// {{{ deleteOID()
|
||||
|
||||
/**
|
||||
* delete an OID
|
||||
*
|
||||
* @param integer $OID
|
||||
* @return mixed MDB2_OK on success or MDB2 Error Object on failure
|
||||
* @access public
|
||||
*/
|
||||
function deleteOID($OID)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$connection = $db->getConnection();
|
||||
if (PEAR::isError($connection)) {
|
||||
return $connection;
|
||||
}
|
||||
|
||||
if (!@pg_lo_unlink($connection, $OID)) {
|
||||
return $db->raiseError(null, null, null,
|
||||
'Unable to unlink OID: '.$OID, __FUNCTION__);
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2006 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his 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 |
|
||||
// | REGENTS 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Native/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 SQLite driver for the native module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Native_sqlite extends MDB2_Driver_Native_Common
|
||||
{
|
||||
}
|
||||
?>
|
||||
+517
@@ -0,0 +1,517 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2007 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his 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 |
|
||||
// | REGENTS 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
/**
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
*/
|
||||
|
||||
/**
|
||||
* These are constants for the tableInfo-function
|
||||
* they are bitwised or'ed. so if there are more constants to be defined
|
||||
* in the future, adjust MDB2_TABLEINFO_FULL accordingly
|
||||
*/
|
||||
|
||||
define('MDB2_TABLEINFO_ORDER', 1);
|
||||
define('MDB2_TABLEINFO_ORDERTABLE', 2);
|
||||
define('MDB2_TABLEINFO_FULL', 3);
|
||||
|
||||
/**
|
||||
* Base class for the schema reverse engineering module that is extended by each MDB2 driver
|
||||
*
|
||||
* To load this module in the MDB2 object:
|
||||
* $mdb->loadModule('Reverse');
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Reverse_Common extends MDB2_Module_Common
|
||||
{
|
||||
// {{{ splitTableSchema()
|
||||
|
||||
/**
|
||||
* Split the "[owner|schema].table" notation into an array
|
||||
*
|
||||
* @param string $table [schema and] table name
|
||||
*
|
||||
* @return array array(schema, table)
|
||||
* @access private
|
||||
*/
|
||||
function splitTableSchema($table)
|
||||
{
|
||||
$ret = array();
|
||||
if (strpos($table, '.') !== false) {
|
||||
return explode('.', $table);
|
||||
}
|
||||
return array(null, $table);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableFieldDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a field into an array
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $field name of field that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure.
|
||||
* The returned array contains an array for each field definition,
|
||||
* with all or some of these indices, depending on the field data type:
|
||||
* [notnull] [nativetype] [length] [fixed] [default] [type] [mdb2type]
|
||||
* @access public
|
||||
*/
|
||||
function getTableFieldDefinition($table, $field)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'method not implemented', __FUNCTION__);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableIndexDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of an index into an array
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $index name of index that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* The returned array has this structure:
|
||||
* </pre>
|
||||
* array (
|
||||
* [fields] => array (
|
||||
* [field1name] => array() // one entry per each field covered
|
||||
* [field2name] => array() // by the index
|
||||
* [field3name] => array(
|
||||
* [sorting] => ascending
|
||||
* )
|
||||
* )
|
||||
* );
|
||||
* </pre>
|
||||
* @access public
|
||||
*/
|
||||
function getTableIndexDefinition($table, $index)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'method not implemented', __FUNCTION__);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableConstraintDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of an constraints into an array
|
||||
*
|
||||
* @param string $table name of table that should be used in method
|
||||
* @param string $index name of index that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* The returned array has this structure:
|
||||
* <pre>
|
||||
* array (
|
||||
* [primary] => 0
|
||||
* [unique] => 0
|
||||
* [foreign] => 1
|
||||
* [check] => 0
|
||||
* [fields] => array (
|
||||
* [field1name] => array() // one entry per each field covered
|
||||
* [field2name] => array() // by the index
|
||||
* [field3name] => array(
|
||||
* [sorting] => ascending
|
||||
* [position] => 3
|
||||
* )
|
||||
* )
|
||||
* [references] => array(
|
||||
* [table] => name
|
||||
* [fields] => array(
|
||||
* [field1name] => array( //one entry per each referenced field
|
||||
* [position] => 1
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* [deferrable] => 0
|
||||
* [initiallydeferred] => 0
|
||||
* [onupdate] => CASCADE|RESTRICT|SET NULL|SET DEFAULT|NO ACTION
|
||||
* [ondelete] => CASCADE|RESTRICT|SET NULL|SET DEFAULT|NO ACTION
|
||||
* [match] => SIMPLE|PARTIAL|FULL
|
||||
* );
|
||||
* </pre>
|
||||
* @access public
|
||||
*/
|
||||
function getTableConstraintDefinition($table, $index)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'method not implemented', __FUNCTION__);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getSequenceDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a sequence into an array
|
||||
*
|
||||
* @param string $sequence name of sequence that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* The returned array has this structure:
|
||||
* <pre>
|
||||
* array (
|
||||
* [start] => n
|
||||
* );
|
||||
* </pre>
|
||||
* @access public
|
||||
*/
|
||||
function getSequenceDefinition($sequence)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$start = $db->currId($sequence);
|
||||
if (PEAR::isError($start)) {
|
||||
return $start;
|
||||
}
|
||||
if ($db->supports('current_id')) {
|
||||
$start++;
|
||||
} else {
|
||||
$db->warnings[] = 'database does not support getting current
|
||||
sequence value, the sequence value was incremented';
|
||||
}
|
||||
$definition = array();
|
||||
if ($start != 1) {
|
||||
$definition = array('start' => $start);
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTriggerDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a trigger into an array
|
||||
*
|
||||
* EXPERIMENTAL
|
||||
*
|
||||
* WARNING: this function is experimental and may change the returned value
|
||||
* at any time until labelled as non-experimental
|
||||
*
|
||||
* @param string $trigger name of trigger that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* The returned array has this structure:
|
||||
* <pre>
|
||||
* array (
|
||||
* [trigger_name] => 'trigger name',
|
||||
* [table_name] => 'table name',
|
||||
* [trigger_body] => 'trigger body definition',
|
||||
* [trigger_type] => 'BEFORE' | 'AFTER',
|
||||
* [trigger_event] => 'INSERT' | 'UPDATE' | 'DELETE'
|
||||
* //or comma separated list of multiple events, when supported
|
||||
* [trigger_enabled] => true|false
|
||||
* [trigger_comment] => 'trigger comment',
|
||||
* );
|
||||
* </pre>
|
||||
* The oci8 driver also returns a [when_clause] index.
|
||||
* @access public
|
||||
*/
|
||||
function getTriggerDefinition($trigger)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'method not implemented', __FUNCTION__);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* The format of the resulting array depends on which <var>$mode</var>
|
||||
* you select. The sample output below is based on this query:
|
||||
* <pre>
|
||||
* SELECT tblFoo.fldID, tblFoo.fldPhone, tblBar.fldId
|
||||
* FROM tblFoo
|
||||
* JOIN tblBar ON tblFoo.fldId = tblBar.fldId
|
||||
* </pre>
|
||||
*
|
||||
* <ul>
|
||||
* <li>
|
||||
*
|
||||
* <kbd>null</kbd> (default)
|
||||
* <pre>
|
||||
* [0] => Array (
|
||||
* [table] => tblFoo
|
||||
* [name] => fldId
|
||||
* [type] => int
|
||||
* [len] => 11
|
||||
* [flags] => primary_key not_null
|
||||
* )
|
||||
* [1] => Array (
|
||||
* [table] => tblFoo
|
||||
* [name] => fldPhone
|
||||
* [type] => string
|
||||
* [len] => 20
|
||||
* [flags] =>
|
||||
* )
|
||||
* [2] => Array (
|
||||
* [table] => tblBar
|
||||
* [name] => fldId
|
||||
* [type] => int
|
||||
* [len] => 11
|
||||
* [flags] => primary_key not_null
|
||||
* )
|
||||
* </pre>
|
||||
*
|
||||
* </li><li>
|
||||
*
|
||||
* <kbd>MDB2_TABLEINFO_ORDER</kbd>
|
||||
*
|
||||
* <p>In addition to the information found in the default output,
|
||||
* a notation of the number of columns is provided by the
|
||||
* <samp>num_fields</samp> element while the <samp>order</samp>
|
||||
* element provides an array with the column names as the keys and
|
||||
* their location index number (corresponding to the keys in the
|
||||
* the default output) as the values.</p>
|
||||
*
|
||||
* <p>If a result set has identical field names, the last one is
|
||||
* used.</p>
|
||||
*
|
||||
* <pre>
|
||||
* [num_fields] => 3
|
||||
* [order] => Array (
|
||||
* [fldId] => 2
|
||||
* [fldTrans] => 1
|
||||
* )
|
||||
* </pre>
|
||||
*
|
||||
* </li><li>
|
||||
*
|
||||
* <kbd>MDB2_TABLEINFO_ORDERTABLE</kbd>
|
||||
*
|
||||
* <p>Similar to <kbd>MDB2_TABLEINFO_ORDER</kbd> but adds more
|
||||
* dimensions to the array in which the table names are keys and
|
||||
* the field names are sub-keys. This is helpful for queries that
|
||||
* join tables which have identical field names.</p>
|
||||
*
|
||||
* <pre>
|
||||
* [num_fields] => 3
|
||||
* [ordertable] => Array (
|
||||
* [tblFoo] => Array (
|
||||
* [fldId] => 0
|
||||
* [fldPhone] => 1
|
||||
* )
|
||||
* [tblBar] => Array (
|
||||
* [fldId] => 2
|
||||
* )
|
||||
* )
|
||||
* </pre>
|
||||
*
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* The <samp>flags</samp> element contains a space separated list
|
||||
* of extra information about the field. This data is inconsistent
|
||||
* between DBMS's due to the way each DBMS works.
|
||||
* + <samp>primary_key</samp>
|
||||
* + <samp>unique_key</samp>
|
||||
* + <samp>multiple_key</samp>
|
||||
* + <samp>not_null</samp>
|
||||
*
|
||||
* Most DBMS's only provide the <samp>table</samp> and <samp>flags</samp>
|
||||
* elements if <var>$result</var> is a table name. The following DBMS's
|
||||
* provide full information from queries:
|
||||
* + fbsql
|
||||
* + mysql
|
||||
*
|
||||
* If the 'portability' option has <samp>MDB2_PORTABILITY_FIX_CASE</samp>
|
||||
* turned on, the names of tables and fields will be lower or upper cased.
|
||||
*
|
||||
* @param object|string $result MDB2_result object from a query or a
|
||||
* string containing the name of a table.
|
||||
* While this also accepts a query result
|
||||
* resource identifier, this behavior is
|
||||
* deprecated.
|
||||
* @param int $mode either unused or one of the tableInfo modes:
|
||||
* <kbd>MDB2_TABLEINFO_ORDERTABLE</kbd>,
|
||||
* <kbd>MDB2_TABLEINFO_ORDER</kbd> or
|
||||
* <kbd>MDB2_TABLEINFO_FULL</kbd> (which does both).
|
||||
* These are bitwise, so the first two can be
|
||||
* combined using <kbd>|</kbd>.
|
||||
*
|
||||
* @return array an associative array with the information requested.
|
||||
* A MDB2_Error object on failure.
|
||||
*
|
||||
* @see MDB2_Driver_Common::setOption()
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if (!is_string($result)) {
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'method not implemented', __FUNCTION__);
|
||||
}
|
||||
|
||||
$db->loadModule('Manager', null, true);
|
||||
$fields = $db->manager->listTableFields($result);
|
||||
if (PEAR::isError($fields)) {
|
||||
return $fields;
|
||||
}
|
||||
|
||||
$flags = array();
|
||||
|
||||
$idxname_format = $db->getOption('idxname_format');
|
||||
$db->setOption('idxname_format', '%s');
|
||||
|
||||
$indexes = $db->manager->listTableIndexes($result);
|
||||
if (PEAR::isError($indexes)) {
|
||||
$db->setOption('idxname_format', $idxname_format);
|
||||
return $indexes;
|
||||
}
|
||||
|
||||
foreach ($indexes as $index) {
|
||||
$definition = $this->getTableIndexDefinition($result, $index);
|
||||
if (PEAR::isError($definition)) {
|
||||
$db->setOption('idxname_format', $idxname_format);
|
||||
return $definition;
|
||||
}
|
||||
if (count($definition['fields']) > 1) {
|
||||
foreach ($definition['fields'] as $field => $sort) {
|
||||
$flags[$field] = 'multiple_key';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$constraints = $db->manager->listTableConstraints($result);
|
||||
if (PEAR::isError($constraints)) {
|
||||
return $constraints;
|
||||
}
|
||||
|
||||
foreach ($constraints as $constraint) {
|
||||
$definition = $this->getTableConstraintDefinition($result, $constraint);
|
||||
if (PEAR::isError($definition)) {
|
||||
$db->setOption('idxname_format', $idxname_format);
|
||||
return $definition;
|
||||
}
|
||||
$flag = !empty($definition['primary'])
|
||||
? 'primary_key' : (!empty($definition['unique'])
|
||||
? 'unique_key' : false);
|
||||
if ($flag) {
|
||||
foreach ($definition['fields'] as $field => $sort) {
|
||||
if (empty($flags[$field]) || $flags[$field] != 'primary_key') {
|
||||
$flags[$field] = $flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$res = array();
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = count($fields);
|
||||
}
|
||||
|
||||
foreach ($fields as $i => $field) {
|
||||
$definition = $this->getTableFieldDefinition($result, $field);
|
||||
if (PEAR::isError($definition)) {
|
||||
$db->setOption('idxname_format', $idxname_format);
|
||||
return $definition;
|
||||
}
|
||||
$res[$i] = $definition[0];
|
||||
$res[$i]['name'] = $field;
|
||||
$res[$i]['table'] = $result;
|
||||
$res[$i]['type'] = preg_replace('/^([a-z]+).*$/i', '\\1', trim($definition[0]['nativetype']));
|
||||
// 'primary_key', 'unique_key', 'multiple_key'
|
||||
$res[$i]['flags'] = empty($flags[$field]) ? '' : $flags[$field];
|
||||
// not_null', 'unsigned', 'auto_increment', 'default_[rawencodedvalue]'
|
||||
if (!empty($res[$i]['notnull'])) {
|
||||
$res[$i]['flags'].= ' not_null';
|
||||
}
|
||||
if (!empty($res[$i]['unsigned'])) {
|
||||
$res[$i]['flags'].= ' unsigned';
|
||||
}
|
||||
if (!empty($res[$i]['auto_increment'])) {
|
||||
$res[$i]['flags'].= ' autoincrement';
|
||||
}
|
||||
if (!empty($res[$i]['default'])) {
|
||||
$res[$i]['flags'].= ' default_'.rawurlencode($res[$i]['default']);
|
||||
}
|
||||
|
||||
if ($mode & MDB2_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & MDB2_TABLEINFO_ORDERTABLE) {
|
||||
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
$db->setOption('idxname_format', $idxname_format);
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
?>
|
||||
+546
@@ -0,0 +1,546 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2007 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his 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 |
|
||||
// | REGENTS 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Reverse/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 MySQL driver for the schema reverse engineering module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
* @author Lorenzo Alberton <l.alberton@quipo.it>
|
||||
*/
|
||||
class MDB2_Driver_Reverse_mysql extends MDB2_Driver_Reverse_Common
|
||||
{
|
||||
// {{{ getTableFieldDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a field into an array
|
||||
*
|
||||
* @param string $table_name name of table that should be used in method
|
||||
* @param string $field_name name of field that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableFieldDefinition($table_name, $field_name)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$result = $db->loadModule('Datatype', null, true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table_name);
|
||||
|
||||
$table = $db->quoteIdentifier($table, true);
|
||||
$query = "SHOW FULL COLUMNS FROM $table LIKE ".$db->quote($field_name);
|
||||
$columns = $db->queryAll($query, null, MDB2_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($columns)) {
|
||||
return $columns;
|
||||
}
|
||||
foreach ($columns as $column) {
|
||||
$column = array_change_key_case($column, CASE_LOWER);
|
||||
$column['name'] = $column['field'];
|
||||
unset($column['field']);
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$column['name'] = strtolower($column['name']);
|
||||
} else {
|
||||
$column['name'] = strtoupper($column['name']);
|
||||
}
|
||||
} else {
|
||||
$column = array_change_key_case($column, $db->options['field_case']);
|
||||
}
|
||||
if ($field_name == $column['name']) {
|
||||
$mapped_datatype = $db->datatype->mapNativeDatatype($column);
|
||||
if (PEAR::isError($mapped_datatype)) {
|
||||
return $mapped_datatype;
|
||||
}
|
||||
list($types, $length, $unsigned, $fixed) = $mapped_datatype;
|
||||
$notnull = false;
|
||||
if (empty($column['null']) || $column['null'] !== 'YES') {
|
||||
$notnull = true;
|
||||
}
|
||||
$default = false;
|
||||
if (array_key_exists('default', $column)) {
|
||||
$default = $column['default'];
|
||||
if ((null === $default) && $notnull) {
|
||||
$default = '';
|
||||
}
|
||||
}
|
||||
$definition[0] = array(
|
||||
'notnull' => $notnull,
|
||||
'nativetype' => preg_replace('/^([a-z]+)[^a-z].*/i', '\\1', $column['type'])
|
||||
);
|
||||
$autoincrement = false;
|
||||
if (!empty($column['extra'])) {
|
||||
if ($column['extra'] == 'auto_increment') {
|
||||
$autoincrement = true;
|
||||
} else {
|
||||
$definition[0]['extra'] = $column['extra'];
|
||||
}
|
||||
}
|
||||
$collate = null;
|
||||
if (!empty($column['collation'])) {
|
||||
$collate = $column['collation'];
|
||||
$charset = preg_replace('/(.+?)(_.+)?/', '$1', $collate);
|
||||
}
|
||||
|
||||
if (null !== $length) {
|
||||
$definition[0]['length'] = $length;
|
||||
}
|
||||
if (null !== $unsigned) {
|
||||
$definition[0]['unsigned'] = $unsigned;
|
||||
}
|
||||
if (null !== $fixed) {
|
||||
$definition[0]['fixed'] = $fixed;
|
||||
}
|
||||
if ($default !== false) {
|
||||
$definition[0]['default'] = $default;
|
||||
}
|
||||
if ($autoincrement !== false) {
|
||||
$definition[0]['autoincrement'] = $autoincrement;
|
||||
}
|
||||
if (null !== $collate) {
|
||||
$definition[0]['collate'] = $collate;
|
||||
$definition[0]['charset'] = $charset;
|
||||
}
|
||||
foreach ($types as $key => $type) {
|
||||
$definition[$key] = $definition[0];
|
||||
if ($type == 'clob' || $type == 'blob') {
|
||||
unset($definition[$key]['default']);
|
||||
} elseif ($type == 'timestamp' && $notnull && empty($definition[$key]['default'])) {
|
||||
$definition[$key]['default'] = '0000-00-00 00:00:00';
|
||||
}
|
||||
$definition[$key]['type'] = $type;
|
||||
$definition[$key]['mdb2type'] = $type;
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'it was not specified an existing table column', __FUNCTION__);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableIndexDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of an index into an array
|
||||
*
|
||||
* @param string $table_name name of table that should be used in method
|
||||
* @param string $index_name name of index that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableIndexDefinition($table_name, $index_name)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table_name);
|
||||
|
||||
$table = $db->quoteIdentifier($table, true);
|
||||
$query = "SHOW INDEX FROM $table /*!50002 WHERE Key_name = %s */";
|
||||
$index_name_mdb2 = $db->getIndexName($index_name);
|
||||
$result = $db->queryRow(sprintf($query, $db->quote($index_name_mdb2)));
|
||||
if (!PEAR::isError($result) && (null !== $result)) {
|
||||
// apply 'idxname_format' only if the query succeeded, otherwise
|
||||
// fallback to the given $index_name, without transformation
|
||||
$index_name = $index_name_mdb2;
|
||||
}
|
||||
$result = $db->query(sprintf($query, $db->quote($index_name)));
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$colpos = 1;
|
||||
$definition = array();
|
||||
while (is_array($row = $result->fetchRow(MDB2_FETCHMODE_ASSOC))) {
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
$key_name = $row['key_name'];
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$key_name = strtolower($key_name);
|
||||
} else {
|
||||
$key_name = strtoupper($key_name);
|
||||
}
|
||||
}
|
||||
if ($index_name == $key_name) {
|
||||
if (!$row['non_unique']) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
$index_name . ' is not an existing table index', __FUNCTION__);
|
||||
}
|
||||
$column_name = $row['column_name'];
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$column_name = strtolower($column_name);
|
||||
} else {
|
||||
$column_name = strtoupper($column_name);
|
||||
}
|
||||
}
|
||||
$definition['fields'][$column_name] = array(
|
||||
'position' => $colpos++
|
||||
);
|
||||
if (!empty($row['collation'])) {
|
||||
$definition['fields'][$column_name]['sorting'] = ($row['collation'] == 'A'
|
||||
? 'ascending' : 'descending');
|
||||
}
|
||||
}
|
||||
}
|
||||
$result->free();
|
||||
if (empty($definition['fields'])) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
$index_name . ' is not an existing table index', __FUNCTION__);
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableConstraintDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a constraint into an array
|
||||
*
|
||||
* @param string $table_name name of table that should be used in method
|
||||
* @param string $constraint_name name of constraint that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableConstraintDefinition($table_name, $constraint_name)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table_name);
|
||||
$constraint_name_original = $constraint_name;
|
||||
|
||||
$table = $db->quoteIdentifier($table, true);
|
||||
$query = "SHOW INDEX FROM $table /*!50002 WHERE Key_name = %s */";
|
||||
if (strtolower($constraint_name) != 'primary') {
|
||||
$constraint_name_mdb2 = $db->getIndexName($constraint_name);
|
||||
$result = $db->queryRow(sprintf($query, $db->quote($constraint_name_mdb2)));
|
||||
if (!PEAR::isError($result) && (null !== $result)) {
|
||||
// apply 'idxname_format' only if the query succeeded, otherwise
|
||||
// fallback to the given $index_name, without transformation
|
||||
$constraint_name = $constraint_name_mdb2;
|
||||
}
|
||||
}
|
||||
$result = $db->query(sprintf($query, $db->quote($constraint_name)));
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$colpos = 1;
|
||||
//default values, eventually overridden
|
||||
$definition = array(
|
||||
'primary' => false,
|
||||
'unique' => false,
|
||||
'foreign' => false,
|
||||
'check' => false,
|
||||
'fields' => array(),
|
||||
'references' => array(
|
||||
'table' => '',
|
||||
'fields' => array(),
|
||||
),
|
||||
'onupdate' => '',
|
||||
'ondelete' => '',
|
||||
'match' => '',
|
||||
'deferrable' => false,
|
||||
'initiallydeferred' => false,
|
||||
);
|
||||
while (is_array($row = $result->fetchRow(MDB2_FETCHMODE_ASSOC))) {
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
$key_name = $row['key_name'];
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$key_name = strtolower($key_name);
|
||||
} else {
|
||||
$key_name = strtoupper($key_name);
|
||||
}
|
||||
}
|
||||
if ($constraint_name == $key_name) {
|
||||
if ($row['non_unique']) {
|
||||
//FOREIGN KEY?
|
||||
return $this->_getTableFKConstraintDefinition($table, $constraint_name_original, $definition);
|
||||
}
|
||||
if ($row['key_name'] == 'PRIMARY') {
|
||||
$definition['primary'] = true;
|
||||
} elseif (!$row['non_unique']) {
|
||||
$definition['unique'] = true;
|
||||
}
|
||||
$column_name = $row['column_name'];
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$column_name = strtolower($column_name);
|
||||
} else {
|
||||
$column_name = strtoupper($column_name);
|
||||
}
|
||||
}
|
||||
$definition['fields'][$column_name] = array(
|
||||
'position' => $colpos++
|
||||
);
|
||||
if (!empty($row['collation'])) {
|
||||
$definition['fields'][$column_name]['sorting'] = ($row['collation'] == 'A'
|
||||
? 'ascending' : 'descending');
|
||||
}
|
||||
}
|
||||
}
|
||||
$result->free();
|
||||
if (empty($definition['fields'])) {
|
||||
return $this->_getTableFKConstraintDefinition($table, $constraint_name_original, $definition);
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _getTableFKConstraintDefinition()
|
||||
|
||||
/**
|
||||
* Get the FK definition from the CREATE TABLE statement
|
||||
*
|
||||
* @param string $table table name
|
||||
* @param string $constraint_name constraint name
|
||||
* @param array $definition default values for constraint definition
|
||||
*
|
||||
* @return array|PEAR_Error
|
||||
* @access private
|
||||
*/
|
||||
function _getTableFKConstraintDefinition($table, $constraint_name, $definition)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
//Use INFORMATION_SCHEMA instead?
|
||||
//SELECT *
|
||||
// FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
|
||||
// WHERE CONSTRAINT_SCHEMA = '$dbname'
|
||||
// AND TABLE_NAME = '$table'
|
||||
// AND CONSTRAINT_NAME = '$constraint_name';
|
||||
$query = 'SHOW CREATE TABLE '. $db->escape($table);
|
||||
$constraint = $db->queryOne($query, 'text', 1);
|
||||
if (!PEAR::isError($constraint) && !empty($constraint)) {
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$constraint = strtolower($constraint);
|
||||
} else {
|
||||
$constraint = strtoupper($constraint);
|
||||
}
|
||||
}
|
||||
$constraint_name_original = $constraint_name;
|
||||
$constraint_name = $db->getIndexName($constraint_name);
|
||||
$pattern = '/\bCONSTRAINT\s+'.$constraint_name.'\s+FOREIGN KEY\s+\(([^\)]+)\) \bREFERENCES\b ([^\s]+) \(([^\)]+)\)(?: ON DELETE ([^\s]+))?(?: ON UPDATE ([^\s]+))?/i';
|
||||
if (!preg_match($pattern, str_replace('`', '', $constraint), $matches)) {
|
||||
//fallback to original constraint name
|
||||
$pattern = '/\bCONSTRAINT\s+'.$constraint_name_original.'\s+FOREIGN KEY\s+\(([^\)]+)\) \bREFERENCES\b ([^\s]+) \(([^\)]+)\)(?: ON DELETE ([^\s]+))?(?: ON UPDATE ([^\s]+))?/i';
|
||||
}
|
||||
if (preg_match($pattern, str_replace('`', '', $constraint), $matches)) {
|
||||
$definition['foreign'] = true;
|
||||
$column_names = explode(',', $matches[1]);
|
||||
$referenced_cols = explode(',', $matches[3]);
|
||||
$definition['references'] = array(
|
||||
'table' => $matches[2],
|
||||
'fields' => array(),
|
||||
);
|
||||
$colpos = 1;
|
||||
foreach ($column_names as $column_name) {
|
||||
$definition['fields'][trim($column_name)] = array(
|
||||
'position' => $colpos++
|
||||
);
|
||||
}
|
||||
$colpos = 1;
|
||||
foreach ($referenced_cols as $column_name) {
|
||||
$definition['references']['fields'][trim($column_name)] = array(
|
||||
'position' => $colpos++
|
||||
);
|
||||
}
|
||||
$definition['ondelete'] = empty($matches[4]) ? 'RESTRICT' : strtoupper($matches[4]);
|
||||
$definition['onupdate'] = empty($matches[5]) ? 'RESTRICT' : strtoupper($matches[5]);
|
||||
$definition['match'] = 'SIMPLE';
|
||||
return $definition;
|
||||
}
|
||||
}
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
$constraint_name . ' is not an existing table constraint', __FUNCTION__);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTriggerDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a trigger into an array
|
||||
*
|
||||
* EXPERIMENTAL
|
||||
*
|
||||
* WARNING: this function is experimental and may change the returned value
|
||||
* at any time until labelled as non-experimental
|
||||
*
|
||||
* @param string $trigger name of trigger that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTriggerDefinition($trigger)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = 'SELECT trigger_name,
|
||||
event_object_table AS table_name,
|
||||
action_statement AS trigger_body,
|
||||
action_timing AS trigger_type,
|
||||
event_manipulation AS trigger_event
|
||||
FROM information_schema.triggers
|
||||
WHERE trigger_name = '. $db->quote($trigger, 'text');
|
||||
$types = array(
|
||||
'trigger_name' => 'text',
|
||||
'table_name' => 'text',
|
||||
'trigger_body' => 'text',
|
||||
'trigger_type' => 'text',
|
||||
'trigger_event' => 'text',
|
||||
);
|
||||
$def = $db->queryRow($query, $types, MDB2_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($def)) {
|
||||
return $def;
|
||||
}
|
||||
$def['trigger_comment'] = '';
|
||||
$def['trigger_enabled'] = true;
|
||||
return $def;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* @param object|string $result MDB2_result object from a query or a
|
||||
* string containing the name of a table.
|
||||
* While this also accepts a query result
|
||||
* resource identifier, this behavior is
|
||||
* deprecated.
|
||||
* @param int $mode a valid tableInfo mode
|
||||
*
|
||||
* @return array an associative array with the information requested.
|
||||
* A MDB2_Error object on failure.
|
||||
*
|
||||
* @see MDB2_Driver_Common::setOption()
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
if (is_string($result)) {
|
||||
return parent::tableInfo($result, $mode);
|
||||
}
|
||||
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$resource = MDB2::isResultCommon($result) ? $result->getResource() : $result;
|
||||
if (!is_resource($resource)) {
|
||||
return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'Could not generate result resource', __FUNCTION__);
|
||||
}
|
||||
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$case_func = 'strtolower';
|
||||
} else {
|
||||
$case_func = 'strtoupper';
|
||||
}
|
||||
} else {
|
||||
$case_func = 'strval';
|
||||
}
|
||||
|
||||
$count = @mysql_num_fields($resource);
|
||||
$res = array();
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
$db->loadModule('Datatype', null, true);
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$res[$i] = array(
|
||||
'table' => $case_func(@mysql_field_table($resource, $i)),
|
||||
'name' => $case_func(@mysql_field_name($resource, $i)),
|
||||
'type' => @mysql_field_type($resource, $i),
|
||||
'length' => @mysql_field_len($resource, $i),
|
||||
'flags' => @mysql_field_flags($resource, $i),
|
||||
);
|
||||
if ($res[$i]['type'] == 'string') {
|
||||
$res[$i]['type'] = 'char';
|
||||
} elseif ($res[$i]['type'] == 'unknown') {
|
||||
$res[$i]['type'] = 'decimal';
|
||||
}
|
||||
$mdb2type_info = $db->datatype->mapNativeDatatype($res[$i]);
|
||||
if (PEAR::isError($mdb2type_info)) {
|
||||
return $mdb2type_info;
|
||||
}
|
||||
$res[$i]['mdb2type'] = $mdb2type_info[0][0];
|
||||
if ($mode & MDB2_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & MDB2_TABLEINFO_ORDERTABLE) {
|
||||
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
?>
|
||||
+574
@@ -0,0 +1,574 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2008 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his 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 |
|
||||
// | REGENTS 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Paul Cooper <pgc@ucecom.com> |
|
||||
// | Lorenzo Alberton <l.alberton@quipo.it> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
|
||||
require_once 'MDB2/Driver/Reverse/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 PostGreSQL driver for the schema reverse engineering module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Paul Cooper <pgc@ucecom.com>
|
||||
* @author Lorenzo Alberton <l.alberton@quipo.it>
|
||||
*/
|
||||
class MDB2_Driver_Reverse_pgsql extends MDB2_Driver_Reverse_Common
|
||||
{
|
||||
// {{{ getTableFieldDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a field into an array
|
||||
*
|
||||
* @param string $table_name name of table that should be used in method
|
||||
* @param string $field_name name of field that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableFieldDefinition($table_name, $field_name)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$result = $db->loadModule('Datatype', null, true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table_name);
|
||||
|
||||
$query = "SELECT a.attname AS name,
|
||||
t.typname AS type,
|
||||
CASE a.attlen
|
||||
WHEN -1 THEN
|
||||
CASE t.typname
|
||||
WHEN 'numeric' THEN (a.atttypmod / 65536)
|
||||
WHEN 'decimal' THEN (a.atttypmod / 65536)
|
||||
WHEN 'money' THEN (a.atttypmod / 65536)
|
||||
ELSE CASE a.atttypmod
|
||||
WHEN -1 THEN NULL
|
||||
ELSE a.atttypmod - 4
|
||||
END
|
||||
END
|
||||
ELSE a.attlen
|
||||
END AS length,
|
||||
CASE t.typname
|
||||
WHEN 'numeric' THEN (a.atttypmod % 65536) - 4
|
||||
WHEN 'decimal' THEN (a.atttypmod % 65536) - 4
|
||||
WHEN 'money' THEN (a.atttypmod % 65536) - 4
|
||||
ELSE 0
|
||||
END AS scale,
|
||||
a.attnotnull,
|
||||
a.atttypmod,
|
||||
a.atthasdef,
|
||||
(SELECT substring(pg_get_expr(d.adbin, d.adrelid) for 128)
|
||||
FROM pg_attrdef d
|
||||
WHERE d.adrelid = a.attrelid
|
||||
AND d.adnum = a.attnum
|
||||
AND a.atthasdef
|
||||
) as default
|
||||
FROM pg_attribute a,
|
||||
pg_class c,
|
||||
pg_type t
|
||||
WHERE c.relname = ".$db->quote($table, 'text')."
|
||||
AND a.atttypid = t.oid
|
||||
AND c.oid = a.attrelid
|
||||
AND NOT a.attisdropped
|
||||
AND a.attnum > 0
|
||||
AND a.attname = ".$db->quote($field_name, 'text')."
|
||||
ORDER BY a.attnum";
|
||||
$column = $db->queryRow($query, null, MDB2_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($column)) {
|
||||
return $column;
|
||||
}
|
||||
|
||||
if (empty($column)) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'it was not specified an existing table column', __FUNCTION__);
|
||||
}
|
||||
|
||||
$column = array_change_key_case($column, CASE_LOWER);
|
||||
$mapped_datatype = $db->datatype->mapNativeDatatype($column);
|
||||
if (PEAR::isError($mapped_datatype)) {
|
||||
return $mapped_datatype;
|
||||
}
|
||||
list($types, $length, $unsigned, $fixed) = $mapped_datatype;
|
||||
$notnull = false;
|
||||
if (!empty($column['attnotnull']) && $column['attnotnull'] == 't') {
|
||||
$notnull = true;
|
||||
}
|
||||
$default = null;
|
||||
if ($column['atthasdef'] === 't'
|
||||
&& strpos($column['default'], 'NULL') !== 0
|
||||
&& !preg_match("/nextval\('([^']+)'/", $column['default'])
|
||||
) {
|
||||
$pattern = '/^\'(.*)\'::[\w ]+$/i';
|
||||
$default = $column['default'];#substr($column['adsrc'], 1, -1);
|
||||
if ((null === $default) && $notnull) {
|
||||
$default = '';
|
||||
} elseif (!empty($default) && preg_match($pattern, $default)) {
|
||||
//remove data type cast
|
||||
$default = preg_replace ($pattern, '\\1', $default);
|
||||
}
|
||||
}
|
||||
$autoincrement = false;
|
||||
if (preg_match("/nextval\('([^']+)'/", $column['default'], $nextvals)) {
|
||||
$autoincrement = true;
|
||||
}
|
||||
$definition[0] = array('notnull' => $notnull, 'nativetype' => $column['type']);
|
||||
if (null !== $length) {
|
||||
$definition[0]['length'] = $length;
|
||||
}
|
||||
if (null !== $unsigned) {
|
||||
$definition[0]['unsigned'] = $unsigned;
|
||||
}
|
||||
if (null !== $fixed) {
|
||||
$definition[0]['fixed'] = $fixed;
|
||||
}
|
||||
if ($default !== false) {
|
||||
$definition[0]['default'] = $default;
|
||||
}
|
||||
if ($autoincrement !== false) {
|
||||
$definition[0]['autoincrement'] = $autoincrement;
|
||||
}
|
||||
foreach ($types as $key => $type) {
|
||||
$definition[$key] = $definition[0];
|
||||
if ($type == 'clob' || $type == 'blob') {
|
||||
unset($definition[$key]['default']);
|
||||
}
|
||||
$definition[$key]['type'] = $type;
|
||||
$definition[$key]['mdb2type'] = $type;
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableIndexDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of an index into an array
|
||||
*
|
||||
* @param string $table_name name of table that should be used in method
|
||||
* @param string $index_name name of index that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableIndexDefinition($table_name, $index_name)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table_name);
|
||||
|
||||
$query = 'SELECT relname, indkey FROM pg_index, pg_class';
|
||||
$query.= ' WHERE pg_class.oid = pg_index.indexrelid';
|
||||
$query.= " AND indisunique != 't' AND indisprimary != 't'";
|
||||
$query.= ' AND pg_class.relname = %s';
|
||||
$index_name_mdb2 = $db->getIndexName($index_name);
|
||||
$row = $db->queryRow(sprintf($query, $db->quote($index_name_mdb2, 'text')), null, MDB2_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($row) || empty($row)) {
|
||||
// fallback to the given $index_name, without transformation
|
||||
$row = $db->queryRow(sprintf($query, $db->quote($index_name, 'text')), null, MDB2_FETCHMODE_ASSOC);
|
||||
}
|
||||
if (PEAR::isError($row)) {
|
||||
return $row;
|
||||
}
|
||||
|
||||
if (empty($row)) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'it was not specified an existing table index', __FUNCTION__);
|
||||
}
|
||||
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
|
||||
$db->loadModule('Manager', null, true);
|
||||
$columns = $db->manager->listTableFields($table_name);
|
||||
|
||||
$definition = array();
|
||||
|
||||
$index_column_numbers = explode(' ', $row['indkey']);
|
||||
|
||||
$colpos = 1;
|
||||
foreach ($index_column_numbers as $number) {
|
||||
$definition['fields'][$columns[($number - 1)]] = array(
|
||||
'position' => $colpos++,
|
||||
'sorting' => 'ascending',
|
||||
);
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableConstraintDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a constraint into an array
|
||||
*
|
||||
* @param string $table_name name of table that should be used in method
|
||||
* @param string $constraint_name name of constraint that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableConstraintDefinition($table_name, $constraint_name)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table_name);
|
||||
|
||||
$query = "SELECT c.oid,
|
||||
c.conname AS constraint_name,
|
||||
CASE WHEN c.contype = 'c' THEN 1 ELSE 0 END AS \"check\",
|
||||
CASE WHEN c.contype = 'f' THEN 1 ELSE 0 END AS \"foreign\",
|
||||
CASE WHEN c.contype = 'p' THEN 1 ELSE 0 END AS \"primary\",
|
||||
CASE WHEN c.contype = 'u' THEN 1 ELSE 0 END AS \"unique\",
|
||||
CASE WHEN c.condeferrable = 'f' THEN 0 ELSE 1 END AS deferrable,
|
||||
CASE WHEN c.condeferred = 'f' THEN 0 ELSE 1 END AS initiallydeferred,
|
||||
--array_to_string(c.conkey, ' ') AS constraint_key,
|
||||
t.relname AS table_name,
|
||||
t2.relname AS references_table,
|
||||
CASE confupdtype
|
||||
WHEN 'a' THEN 'NO ACTION'
|
||||
WHEN 'r' THEN 'RESTRICT'
|
||||
WHEN 'c' THEN 'CASCADE'
|
||||
WHEN 'n' THEN 'SET NULL'
|
||||
WHEN 'd' THEN 'SET DEFAULT'
|
||||
END AS onupdate,
|
||||
CASE confdeltype
|
||||
WHEN 'a' THEN 'NO ACTION'
|
||||
WHEN 'r' THEN 'RESTRICT'
|
||||
WHEN 'c' THEN 'CASCADE'
|
||||
WHEN 'n' THEN 'SET NULL'
|
||||
WHEN 'd' THEN 'SET DEFAULT'
|
||||
END AS ondelete,
|
||||
CASE confmatchtype
|
||||
WHEN 'u' THEN 'UNSPECIFIED'
|
||||
WHEN 'f' THEN 'FULL'
|
||||
WHEN 'p' THEN 'PARTIAL'
|
||||
END AS match,
|
||||
--array_to_string(c.confkey, ' ') AS fk_constraint_key,
|
||||
consrc
|
||||
FROM pg_constraint c
|
||||
LEFT JOIN pg_class t ON c.conrelid = t.oid
|
||||
LEFT JOIN pg_class t2 ON c.confrelid = t2.oid
|
||||
WHERE c.conname = %s
|
||||
AND t.relname = " . $db->quote($table, 'text');
|
||||
$constraint_name_mdb2 = $db->getIndexName($constraint_name);
|
||||
$row = $db->queryRow(sprintf($query, $db->quote($constraint_name_mdb2, 'text')), null, MDB2_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($row) || empty($row)) {
|
||||
// fallback to the given $index_name, without transformation
|
||||
$constraint_name_mdb2 = $constraint_name;
|
||||
$row = $db->queryRow(sprintf($query, $db->quote($constraint_name_mdb2, 'text')), null, MDB2_FETCHMODE_ASSOC);
|
||||
}
|
||||
if (PEAR::isError($row)) {
|
||||
return $row;
|
||||
}
|
||||
$uniqueIndex = false;
|
||||
if (empty($row)) {
|
||||
// We might be looking for a UNIQUE index that was not created
|
||||
// as a constraint but should be treated as such.
|
||||
$query = 'SELECT relname AS constraint_name,
|
||||
indkey,
|
||||
0 AS "check",
|
||||
0 AS "foreign",
|
||||
0 AS "primary",
|
||||
1 AS "unique",
|
||||
0 AS deferrable,
|
||||
0 AS initiallydeferred,
|
||||
NULL AS references_table,
|
||||
NULL AS onupdate,
|
||||
NULL AS ondelete,
|
||||
NULL AS match
|
||||
FROM pg_index, pg_class
|
||||
WHERE pg_class.oid = pg_index.indexrelid
|
||||
AND indisunique = \'t\'
|
||||
AND pg_class.relname = %s';
|
||||
$constraint_name_mdb2 = $db->getIndexName($constraint_name);
|
||||
$row = $db->queryRow(sprintf($query, $db->quote($constraint_name_mdb2, 'text')), null, MDB2_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($row) || empty($row)) {
|
||||
// fallback to the given $index_name, without transformation
|
||||
$constraint_name_mdb2 = $constraint_name;
|
||||
$row = $db->queryRow(sprintf($query, $db->quote($constraint_name_mdb2, 'text')), null, MDB2_FETCHMODE_ASSOC);
|
||||
}
|
||||
if (PEAR::isError($row)) {
|
||||
return $row;
|
||||
}
|
||||
if (empty($row)) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
$constraint_name . ' is not an existing table constraint', __FUNCTION__);
|
||||
}
|
||||
$uniqueIndex = true;
|
||||
}
|
||||
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
|
||||
$definition = array(
|
||||
'primary' => (boolean)$row['primary'],
|
||||
'unique' => (boolean)$row['unique'],
|
||||
'foreign' => (boolean)$row['foreign'],
|
||||
'check' => (boolean)$row['check'],
|
||||
'fields' => array(),
|
||||
'references' => array(
|
||||
'table' => $row['references_table'],
|
||||
'fields' => array(),
|
||||
),
|
||||
'deferrable' => (boolean)$row['deferrable'],
|
||||
'initiallydeferred' => (boolean)$row['initiallydeferred'],
|
||||
'onupdate' => $row['onupdate'],
|
||||
'ondelete' => $row['ondelete'],
|
||||
'match' => $row['match'],
|
||||
);
|
||||
|
||||
if ($uniqueIndex) {
|
||||
$db->loadModule('Manager', null, true);
|
||||
$columns = $db->manager->listTableFields($table_name);
|
||||
$index_column_numbers = explode(' ', $row['indkey']);
|
||||
$colpos = 1;
|
||||
foreach ($index_column_numbers as $number) {
|
||||
$definition['fields'][$columns[($number - 1)]] = array(
|
||||
'position' => $colpos++,
|
||||
'sorting' => 'ascending',
|
||||
);
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
$query = 'SELECT a.attname
|
||||
FROM pg_constraint c
|
||||
LEFT JOIN pg_class t ON c.conrelid = t.oid
|
||||
LEFT JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(c.conkey)
|
||||
WHERE c.conname = %s
|
||||
AND t.relname = ' . $db->quote($table, 'text');
|
||||
$fields = $db->queryCol(sprintf($query, $db->quote($constraint_name_mdb2, 'text')), null);
|
||||
if (PEAR::isError($fields)) {
|
||||
return $fields;
|
||||
}
|
||||
$colpos = 1;
|
||||
foreach ($fields as $field) {
|
||||
$definition['fields'][$field] = array(
|
||||
'position' => $colpos++,
|
||||
'sorting' => 'ascending',
|
||||
);
|
||||
}
|
||||
|
||||
if ($definition['foreign']) {
|
||||
$query = 'SELECT a.attname
|
||||
FROM pg_constraint c
|
||||
LEFT JOIN pg_class t ON c.confrelid = t.oid
|
||||
LEFT JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(c.confkey)
|
||||
WHERE c.conname = %s
|
||||
AND t.relname = ' . $db->quote($definition['references']['table'], 'text');
|
||||
$foreign_fields = $db->queryCol(sprintf($query, $db->quote($constraint_name_mdb2, 'text')), null);
|
||||
if (PEAR::isError($foreign_fields)) {
|
||||
return $foreign_fields;
|
||||
}
|
||||
$colpos = 1;
|
||||
foreach ($foreign_fields as $foreign_field) {
|
||||
$definition['references']['fields'][$foreign_field] = array(
|
||||
'position' => $colpos++,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($definition['check']) {
|
||||
$check_def = $db->queryOne("SELECT pg_get_constraintdef(" . $row['oid'] . ", 't')");
|
||||
// ...
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTriggerDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a trigger into an array
|
||||
*
|
||||
* EXPERIMENTAL
|
||||
*
|
||||
* WARNING: this function is experimental and may change the returned value
|
||||
* at any time until labelled as non-experimental
|
||||
*
|
||||
* @param string $trigger name of trigger that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*
|
||||
* @TODO: add support for plsql functions and functions with args
|
||||
*/
|
||||
function getTriggerDefinition($trigger)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = "SELECT trg.tgname AS trigger_name,
|
||||
tbl.relname AS table_name,
|
||||
CASE
|
||||
WHEN p.proname IS NOT NULL THEN 'EXECUTE PROCEDURE ' || p.proname || '();'
|
||||
ELSE ''
|
||||
END AS trigger_body,
|
||||
CASE trg.tgtype & cast(2 as int2)
|
||||
WHEN 0 THEN 'AFTER'
|
||||
ELSE 'BEFORE'
|
||||
END AS trigger_type,
|
||||
CASE trg.tgtype & cast(28 as int2)
|
||||
WHEN 16 THEN 'UPDATE'
|
||||
WHEN 8 THEN 'DELETE'
|
||||
WHEN 4 THEN 'INSERT'
|
||||
WHEN 20 THEN 'INSERT, UPDATE'
|
||||
WHEN 28 THEN 'INSERT, UPDATE, DELETE'
|
||||
WHEN 24 THEN 'UPDATE, DELETE'
|
||||
WHEN 12 THEN 'INSERT, DELETE'
|
||||
END AS trigger_event,
|
||||
CASE trg.tgenabled
|
||||
WHEN 'O' THEN 't'
|
||||
ELSE trg.tgenabled
|
||||
END AS trigger_enabled,
|
||||
obj_description(trg.oid, 'pg_trigger') AS trigger_comment
|
||||
FROM pg_trigger trg,
|
||||
pg_class tbl,
|
||||
pg_proc p
|
||||
WHERE trg.tgrelid = tbl.oid
|
||||
AND trg.tgfoid = p.oid
|
||||
AND trg.tgname = ". $db->quote($trigger, 'text');
|
||||
$types = array(
|
||||
'trigger_name' => 'text',
|
||||
'table_name' => 'text',
|
||||
'trigger_body' => 'text',
|
||||
'trigger_type' => 'text',
|
||||
'trigger_event' => 'text',
|
||||
'trigger_comment' => 'text',
|
||||
'trigger_enabled' => 'boolean',
|
||||
);
|
||||
return $db->queryRow($query, $types, MDB2_FETCHMODE_ASSOC);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table or a result set
|
||||
*
|
||||
* NOTE: only supports 'table' and 'flags' if <var>$result</var>
|
||||
* is a table name.
|
||||
*
|
||||
* @param object|string $result MDB2_result object from a query or a
|
||||
* string containing the name of a table.
|
||||
* While this also accepts a query result
|
||||
* resource identifier, this behavior is
|
||||
* deprecated.
|
||||
* @param int $mode a valid tableInfo mode
|
||||
*
|
||||
* @return array an associative array with the information requested.
|
||||
* A MDB2_Error object on failure.
|
||||
*
|
||||
* @see MDB2_Driver_Common::tableInfo()
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
if (is_string($result)) {
|
||||
return parent::tableInfo($result, $mode);
|
||||
}
|
||||
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$resource = MDB2::isResultCommon($result) ? $result->getResource() : $result;
|
||||
if (!is_resource($resource)) {
|
||||
return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'Could not generate result resource', __FUNCTION__);
|
||||
}
|
||||
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$case_func = 'strtolower';
|
||||
} else {
|
||||
$case_func = 'strtoupper';
|
||||
}
|
||||
} else {
|
||||
$case_func = 'strval';
|
||||
}
|
||||
|
||||
$count = @pg_num_fields($resource);
|
||||
$res = array();
|
||||
|
||||
if ($mode) {
|
||||
$res['num_fields'] = $count;
|
||||
}
|
||||
|
||||
$db->loadModule('Datatype', null, true);
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$res[$i] = array(
|
||||
'table' => function_exists('pg_field_table') ? @pg_field_table($resource, $i) : '',
|
||||
'name' => $case_func(@pg_field_name($resource, $i)),
|
||||
'type' => @pg_field_type($resource, $i),
|
||||
'length' => @pg_field_size($resource, $i),
|
||||
'flags' => '',
|
||||
);
|
||||
$mdb2type_info = $db->datatype->mapNativeDatatype($res[$i]);
|
||||
if (PEAR::isError($mdb2type_info)) {
|
||||
return $mdb2type_info;
|
||||
}
|
||||
$res[$i]['mdb2type'] = $mdb2type_info[0][0];
|
||||
if ($mode & MDB2_TABLEINFO_ORDER) {
|
||||
$res['order'][$res[$i]['name']] = $i;
|
||||
}
|
||||
if ($mode & MDB2_TABLEINFO_ORDERTABLE) {
|
||||
$res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
?>
|
||||
+611
@@ -0,0 +1,611 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2007 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith, Lorenzo Alberton |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his 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 |
|
||||
// | REGENTS 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Lukas Smith <smith@pooteeweet.org> |
|
||||
// | Lorenzo Alberton <l.alberton@quipo.it> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'MDB2/Driver/Reverse/Common.php';
|
||||
|
||||
/**
|
||||
* MDB2 SQlite driver for the schema reverse engineering module
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Driver_Reverse_sqlite extends MDB2_Driver_Reverse_Common
|
||||
{
|
||||
/**
|
||||
* Remove SQL comments from the field definition
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _removeComments($sql) {
|
||||
$lines = explode("\n", $sql);
|
||||
foreach ($lines as $k => $line) {
|
||||
$pieces = explode('--', $line);
|
||||
if (count($pieces) > 1 && (substr_count($pieces[0], '\'') % 2) == 0) {
|
||||
$lines[$k] = substr($line, 0, strpos($line, '--'));
|
||||
}
|
||||
}
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function _getTableColumns($sql)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
$start_pos = strpos($sql, '(');
|
||||
$end_pos = strrpos($sql, ')');
|
||||
$column_def = substr($sql, $start_pos+1, $end_pos-$start_pos-1);
|
||||
// replace the decimal length-places-separator with a colon
|
||||
$column_def = preg_replace('/(\d),(\d)/', '\1:\2', $column_def);
|
||||
$column_def = $this->_removeComments($column_def);
|
||||
$column_sql = explode(',', $column_def);
|
||||
$columns = array();
|
||||
$count = count($column_sql);
|
||||
if ($count == 0) {
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'unexpected empty table column definition list', __FUNCTION__);
|
||||
}
|
||||
$regexp = '/^\s*([^\s]+) +(CHAR|VARCHAR|VARCHAR2|TEXT|BOOLEAN|SMALLINT|INT|INTEGER|DECIMAL|TINYINT|BIGINT|DOUBLE|FLOAT|DATETIME|DATE|TIME|LONGTEXT|LONGBLOB)( ?\(([1-9][0-9]*)(:([1-9][0-9]*))?\))?( NULL| NOT NULL)?( UNSIGNED)?( NULL| NOT NULL)?( PRIMARY KEY)?( DEFAULT (\'[^\']*\'|[^ ]+))?( NULL| NOT NULL)?( PRIMARY KEY)?(\s*\-\-.*)?$/i';
|
||||
$regexp2 = '/^\s*([^ ]+) +(PRIMARY|UNIQUE|CHECK)$/i';
|
||||
for ($i=0, $j=0; $i<$count; ++$i) {
|
||||
if (!preg_match($regexp, trim($column_sql[$i]), $matches)) {
|
||||
if (!preg_match($regexp2, trim($column_sql[$i]))) {
|
||||
continue;
|
||||
}
|
||||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
|
||||
'unexpected table column SQL definition: "'.$column_sql[$i].'"', __FUNCTION__);
|
||||
}
|
||||
$columns[$j]['name'] = trim($matches[1], implode('', $db->identifier_quoting));
|
||||
$columns[$j]['type'] = strtolower($matches[2]);
|
||||
if (isset($matches[4]) && strlen($matches[4])) {
|
||||
$columns[$j]['length'] = $matches[4];
|
||||
}
|
||||
if (isset($matches[6]) && strlen($matches[6])) {
|
||||
$columns[$j]['decimal'] = $matches[6];
|
||||
}
|
||||
if (isset($matches[8]) && strlen($matches[8])) {
|
||||
$columns[$j]['unsigned'] = true;
|
||||
}
|
||||
if (isset($matches[9]) && strlen($matches[9])) {
|
||||
$columns[$j]['autoincrement'] = true;
|
||||
}
|
||||
if (isset($matches[12]) && strlen($matches[12])) {
|
||||
$default = $matches[12];
|
||||
if (strlen($default) && $default[0]=="'") {
|
||||
$default = str_replace("''", "'", substr($default, 1, strlen($default)-2));
|
||||
}
|
||||
if ($default === 'NULL') {
|
||||
$default = null;
|
||||
}
|
||||
$columns[$j]['default'] = $default;
|
||||
} else {
|
||||
$columns[$j]['default'] = null;
|
||||
}
|
||||
if (isset($matches[7]) && strlen($matches[7])) {
|
||||
$columns[$j]['notnull'] = ($matches[7] === ' NOT NULL');
|
||||
} else if (isset($matches[9]) && strlen($matches[9])) {
|
||||
$columns[$j]['notnull'] = ($matches[9] === ' NOT NULL');
|
||||
} else if (isset($matches[13]) && strlen($matches[13])) {
|
||||
$columns[$j]['notnull'] = ($matches[13] === ' NOT NULL');
|
||||
}
|
||||
++$j;
|
||||
}
|
||||
return $columns;
|
||||
}
|
||||
|
||||
// {{{ getTableFieldDefinition()
|
||||
|
||||
/**
|
||||
* Get the stucture of a field into an array
|
||||
*
|
||||
* @param string $table_name name of table that should be used in method
|
||||
* @param string $field_name name of field that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure.
|
||||
* The returned array contains an array for each field definition,
|
||||
* with (some of) these indices:
|
||||
* [notnull] [nativetype] [length] [fixed] [default] [type] [mdb2type]
|
||||
* @access public
|
||||
*/
|
||||
function getTableFieldDefinition($table_name, $field_name)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table_name);
|
||||
|
||||
$result = $db->loadModule('Datatype', null, true);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
$query = "SELECT sql FROM sqlite_master WHERE type='table' AND ";
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$query.= 'LOWER(name)='.$db->quote(strtolower($table), 'text');
|
||||
} else {
|
||||
$query.= 'name='.$db->quote($table, 'text');
|
||||
}
|
||||
$sql = $db->queryOne($query);
|
||||
if (PEAR::isError($sql)) {
|
||||
return $sql;
|
||||
}
|
||||
$columns = $this->_getTableColumns($sql);
|
||||
foreach ($columns as $column) {
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
if ($db->options['field_case'] == CASE_LOWER) {
|
||||
$column['name'] = strtolower($column['name']);
|
||||
} else {
|
||||
$column['name'] = strtoupper($column['name']);
|
||||
}
|
||||
} else {
|
||||
$column = array_change_key_case($column, $db->options['field_case']);
|
||||
}
|
||||
if ($field_name == $column['name']) {
|
||||
$mapped_datatype = $db->datatype->mapNativeDatatype($column);
|
||||
if (PEAR::isError($mapped_datatype)) {
|
||||
return $mapped_datatype;
|
||||
}
|
||||
list($types, $length, $unsigned, $fixed) = $mapped_datatype;
|
||||
$notnull = false;
|
||||
if (!empty($column['notnull'])) {
|
||||
$notnull = $column['notnull'];
|
||||
}
|
||||
$default = false;
|
||||
if (array_key_exists('default', $column)) {
|
||||
$default = $column['default'];
|
||||
if ((null === $default) && $notnull) {
|
||||
$default = '';
|
||||
}
|
||||
}
|
||||
$autoincrement = false;
|
||||
if (!empty($column['autoincrement'])) {
|
||||
$autoincrement = true;
|
||||
}
|
||||
|
||||
$definition[0] = array(
|
||||
'notnull' => $notnull,
|
||||
'nativetype' => preg_replace('/^([a-z]+)[^a-z].*/i', '\\1', $column['type'])
|
||||
);
|
||||
if (null !== $length) {
|
||||
$definition[0]['length'] = $length;
|
||||
}
|
||||
if (null !== $unsigned) {
|
||||
$definition[0]['unsigned'] = $unsigned;
|
||||
}
|
||||
if (null !== $fixed) {
|
||||
$definition[0]['fixed'] = $fixed;
|
||||
}
|
||||
if ($default !== false) {
|
||||
$definition[0]['default'] = $default;
|
||||
}
|
||||
if ($autoincrement !== false) {
|
||||
$definition[0]['autoincrement'] = $autoincrement;
|
||||
}
|
||||
foreach ($types as $key => $type) {
|
||||
$definition[$key] = $definition[0];
|
||||
if ($type == 'clob' || $type == 'blob') {
|
||||
unset($definition[$key]['default']);
|
||||
}
|
||||
$definition[$key]['type'] = $type;
|
||||
$definition[$key]['mdb2type'] = $type;
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'it was not specified an existing table column', __FUNCTION__);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableIndexDefinition()
|
||||
|
||||
/**
|
||||
* Get the stucture of an index into an array
|
||||
*
|
||||
* @param string $table_name name of table that should be used in method
|
||||
* @param string $index_name name of index that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableIndexDefinition($table_name, $index_name)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table_name);
|
||||
|
||||
$query = "SELECT sql FROM sqlite_master WHERE type='index' AND ";
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$query.= 'LOWER(name)=%s AND LOWER(tbl_name)=' . $db->quote(strtolower($table), 'text');
|
||||
} else {
|
||||
$query.= 'name=%s AND tbl_name=' . $db->quote($table, 'text');
|
||||
}
|
||||
$query.= ' AND sql NOT NULL ORDER BY name';
|
||||
$index_name_mdb2 = $db->getIndexName($index_name);
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$qry = sprintf($query, $db->quote(strtolower($index_name_mdb2), 'text'));
|
||||
} else {
|
||||
$qry = sprintf($query, $db->quote($index_name_mdb2, 'text'));
|
||||
}
|
||||
$sql = $db->queryOne($qry, 'text');
|
||||
if (PEAR::isError($sql) || empty($sql)) {
|
||||
// fallback to the given $index_name, without transformation
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$qry = sprintf($query, $db->quote(strtolower($index_name), 'text'));
|
||||
} else {
|
||||
$qry = sprintf($query, $db->quote($index_name, 'text'));
|
||||
}
|
||||
$sql = $db->queryOne($qry, 'text');
|
||||
}
|
||||
if (PEAR::isError($sql)) {
|
||||
return $sql;
|
||||
}
|
||||
if (!$sql) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'it was not specified an existing table index', __FUNCTION__);
|
||||
}
|
||||
|
||||
$sql = strtolower($sql);
|
||||
$start_pos = strpos($sql, '(');
|
||||
$end_pos = strrpos($sql, ')');
|
||||
$column_names = substr($sql, $start_pos+1, $end_pos-$start_pos-1);
|
||||
$column_names = explode(',', $column_names);
|
||||
|
||||
if (preg_match("/^create unique/", $sql)) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'it was not specified an existing table index', __FUNCTION__);
|
||||
}
|
||||
|
||||
$definition = array();
|
||||
$count = count($column_names);
|
||||
for ($i=0; $i<$count; ++$i) {
|
||||
$column_name = strtok($column_names[$i], ' ');
|
||||
$collation = strtok(' ');
|
||||
$definition['fields'][$column_name] = array(
|
||||
'position' => $i+1
|
||||
);
|
||||
if (!empty($collation)) {
|
||||
$definition['fields'][$column_name]['sorting'] =
|
||||
($collation=='ASC' ? 'ascending' : 'descending');
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($definition['fields'])) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'it was not specified an existing table index', __FUNCTION__);
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTableConstraintDefinition()
|
||||
|
||||
/**
|
||||
* Get the stucture of a constraint into an array
|
||||
*
|
||||
* @param string $table_name name of table that should be used in method
|
||||
* @param string $constraint_name name of constraint that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTableConstraintDefinition($table_name, $constraint_name)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
list($schema, $table) = $this->splitTableSchema($table_name);
|
||||
|
||||
$query = "SELECT sql FROM sqlite_master WHERE type='index' AND ";
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$query.= 'LOWER(name)=%s AND LOWER(tbl_name)=' . $db->quote(strtolower($table), 'text');
|
||||
} else {
|
||||
$query.= 'name=%s AND tbl_name=' . $db->quote($table, 'text');
|
||||
}
|
||||
$query.= ' AND sql NOT NULL ORDER BY name';
|
||||
$constraint_name_mdb2 = $db->getIndexName($constraint_name);
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$qry = sprintf($query, $db->quote(strtolower($constraint_name_mdb2), 'text'));
|
||||
} else {
|
||||
$qry = sprintf($query, $db->quote($constraint_name_mdb2, 'text'));
|
||||
}
|
||||
$sql = $db->queryOne($qry, 'text');
|
||||
if (PEAR::isError($sql) || empty($sql)) {
|
||||
// fallback to the given $index_name, without transformation
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$qry = sprintf($query, $db->quote(strtolower($constraint_name), 'text'));
|
||||
} else {
|
||||
$qry = sprintf($query, $db->quote($constraint_name, 'text'));
|
||||
}
|
||||
$sql = $db->queryOne($qry, 'text');
|
||||
}
|
||||
if (PEAR::isError($sql)) {
|
||||
return $sql;
|
||||
}
|
||||
//default values, eventually overridden
|
||||
$definition = array(
|
||||
'primary' => false,
|
||||
'unique' => false,
|
||||
'foreign' => false,
|
||||
'check' => false,
|
||||
'fields' => array(),
|
||||
'references' => array(
|
||||
'table' => '',
|
||||
'fields' => array(),
|
||||
),
|
||||
'onupdate' => '',
|
||||
'ondelete' => '',
|
||||
'match' => '',
|
||||
'deferrable' => false,
|
||||
'initiallydeferred' => false,
|
||||
);
|
||||
if (!$sql) {
|
||||
$query = "SELECT sql FROM sqlite_master WHERE type='table' AND ";
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$query.= 'LOWER(name)='.$db->quote(strtolower($table), 'text');
|
||||
} else {
|
||||
$query.= 'name='.$db->quote($table, 'text');
|
||||
}
|
||||
$query.= " AND sql NOT NULL ORDER BY name";
|
||||
$sql = $db->queryOne($query, 'text');
|
||||
if (PEAR::isError($sql)) {
|
||||
return $sql;
|
||||
}
|
||||
if ($constraint_name == 'primary') {
|
||||
// search in table definition for PRIMARY KEYs
|
||||
if (preg_match("/\bPRIMARY\s+KEY\b\s*\(([^)]+)/i", $sql, $tmp)) {
|
||||
$definition['primary'] = true;
|
||||
$definition['fields'] = array();
|
||||
$column_names = explode(',', $tmp[1]);
|
||||
$colpos = 1;
|
||||
foreach ($column_names as $column_name) {
|
||||
$definition['fields'][trim($column_name)] = array(
|
||||
'position' => $colpos++
|
||||
);
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
if (preg_match("/\"([^\"]+)\"[^\,\"]+\bPRIMARY\s+KEY\b[^\,\)]*/i", $sql, $tmp)) {
|
||||
$definition['primary'] = true;
|
||||
$definition['fields'] = array();
|
||||
$column_names = explode(',', $tmp[1]);
|
||||
$colpos = 1;
|
||||
foreach ($column_names as $column_name) {
|
||||
$definition['fields'][trim($column_name)] = array(
|
||||
'position' => $colpos++
|
||||
);
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
} else {
|
||||
// search in table definition for FOREIGN KEYs
|
||||
$pattern = "/\bCONSTRAINT\b\s+%s\s+
|
||||
\bFOREIGN\s+KEY\b\s*\(([^\)]+)\)\s*
|
||||
\bREFERENCES\b\s+([^\s]+)\s*\(([^\)]+)\)\s*
|
||||
(?:\bMATCH\s*([^\s]+))?\s*
|
||||
(?:\bON\s+UPDATE\s+([^\s,\)]+))?\s*
|
||||
(?:\bON\s+DELETE\s+([^\s,\)]+))?\s*
|
||||
/imsx";
|
||||
$found_fk = false;
|
||||
if (preg_match(sprintf($pattern, $constraint_name_mdb2), $sql, $tmp)) {
|
||||
$found_fk = true;
|
||||
} elseif (preg_match(sprintf($pattern, $constraint_name), $sql, $tmp)) {
|
||||
$found_fk = true;
|
||||
}
|
||||
if ($found_fk) {
|
||||
$definition['foreign'] = true;
|
||||
$definition['match'] = 'SIMPLE';
|
||||
$definition['onupdate'] = 'NO ACTION';
|
||||
$definition['ondelete'] = 'NO ACTION';
|
||||
$definition['references']['table'] = $tmp[2];
|
||||
$column_names = explode(',', $tmp[1]);
|
||||
$colpos = 1;
|
||||
foreach ($column_names as $column_name) {
|
||||
$definition['fields'][trim($column_name)] = array(
|
||||
'position' => $colpos++
|
||||
);
|
||||
}
|
||||
$referenced_cols = explode(',', $tmp[3]);
|
||||
$colpos = 1;
|
||||
foreach ($referenced_cols as $column_name) {
|
||||
$definition['references']['fields'][trim($column_name)] = array(
|
||||
'position' => $colpos++
|
||||
);
|
||||
}
|
||||
if (isset($tmp[4])) {
|
||||
$definition['match'] = $tmp[4];
|
||||
}
|
||||
if (isset($tmp[5])) {
|
||||
$definition['onupdate'] = $tmp[5];
|
||||
}
|
||||
if (isset($tmp[6])) {
|
||||
$definition['ondelete'] = $tmp[6];
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
}
|
||||
$sql = false;
|
||||
}
|
||||
if (!$sql) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
$constraint_name . ' is not an existing table constraint', __FUNCTION__);
|
||||
}
|
||||
|
||||
$sql = strtolower($sql);
|
||||
$start_pos = strpos($sql, '(');
|
||||
$end_pos = strrpos($sql, ')');
|
||||
$column_names = substr($sql, $start_pos+1, $end_pos-$start_pos-1);
|
||||
$column_names = explode(',', $column_names);
|
||||
|
||||
if (!preg_match("/^create unique/", $sql)) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
$constraint_name . ' is not an existing table constraint', __FUNCTION__);
|
||||
}
|
||||
|
||||
$definition['unique'] = true;
|
||||
$count = count($column_names);
|
||||
for ($i=0; $i<$count; ++$i) {
|
||||
$column_name = strtok($column_names[$i]," ");
|
||||
$collation = strtok(" ");
|
||||
$definition['fields'][$column_name] = array(
|
||||
'position' => $i+1
|
||||
);
|
||||
if (!empty($collation)) {
|
||||
$definition['fields'][$column_name]['sorting'] =
|
||||
($collation=='ASC' ? 'ascending' : 'descending');
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($definition['fields'])) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
$constraint_name . ' is not an existing table constraint', __FUNCTION__);
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getTriggerDefinition()
|
||||
|
||||
/**
|
||||
* Get the structure of a trigger into an array
|
||||
*
|
||||
* EXPERIMENTAL
|
||||
*
|
||||
* WARNING: this function is experimental and may change the returned value
|
||||
* at any time until labelled as non-experimental
|
||||
*
|
||||
* @param string $trigger name of trigger that should be used in method
|
||||
* @return mixed data array on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getTriggerDefinition($trigger)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$query = "SELECT name as trigger_name,
|
||||
tbl_name AS table_name,
|
||||
sql AS trigger_body,
|
||||
NULL AS trigger_type,
|
||||
NULL AS trigger_event,
|
||||
NULL AS trigger_comment,
|
||||
1 AS trigger_enabled
|
||||
FROM sqlite_master
|
||||
WHERE type='trigger'";
|
||||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
|
||||
$query.= ' AND LOWER(name)='.$db->quote(strtolower($trigger), 'text');
|
||||
} else {
|
||||
$query.= ' AND name='.$db->quote($trigger, 'text');
|
||||
}
|
||||
$types = array(
|
||||
'trigger_name' => 'text',
|
||||
'table_name' => 'text',
|
||||
'trigger_body' => 'text',
|
||||
'trigger_type' => 'text',
|
||||
'trigger_event' => 'text',
|
||||
'trigger_comment' => 'text',
|
||||
'trigger_enabled' => 'boolean',
|
||||
);
|
||||
$def = $db->queryRow($query, $types, MDB2_FETCHMODE_ASSOC);
|
||||
if (PEAR::isError($def)) {
|
||||
return $def;
|
||||
}
|
||||
if (empty($def)) {
|
||||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
|
||||
'it was not specified an existing trigger', __FUNCTION__);
|
||||
}
|
||||
if (preg_match("/^create\s+(?:temp|temporary)?trigger\s+(?:if\s+not\s+exists\s+)?.*(before|after)?\s+(insert|update|delete)/Uims", $def['trigger_body'], $tmp)) {
|
||||
$def['trigger_type'] = strtoupper($tmp[1]);
|
||||
$def['trigger_event'] = strtoupper($tmp[2]);
|
||||
}
|
||||
return $def;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ tableInfo()
|
||||
|
||||
/**
|
||||
* Returns information about a table
|
||||
*
|
||||
* @param string $result a string containing the name of a table
|
||||
* @param int $mode a valid tableInfo mode
|
||||
*
|
||||
* @return array an associative array with the information requested.
|
||||
* A MDB2_Error object on failure.
|
||||
*
|
||||
* @see MDB2_Driver_Common::tableInfo()
|
||||
* @since Method available since Release 1.7.0
|
||||
*/
|
||||
function tableInfo($result, $mode = null)
|
||||
{
|
||||
if (is_string($result)) {
|
||||
return parent::tableInfo($result, $mode);
|
||||
}
|
||||
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
return $db->raiseError(MDB2_ERROR_NOT_CAPABLE, null, null,
|
||||
'This DBMS can not obtain tableInfo from result sets', __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
Vendored
+1729
File diff suppressed because it is too large
Load Diff
Vendored
+1583
File diff suppressed because it is too large
Load Diff
Vendored
+1104
File diff suppressed because it is too large
Load Diff
Vendored
+723
@@ -0,0 +1,723 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP versions 4 and 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2006 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his 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 |
|
||||
// | REGENTS 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
|
||||
/**
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Used by autoPrepare()
|
||||
*/
|
||||
define('MDB2_AUTOQUERY_INSERT', 1);
|
||||
define('MDB2_AUTOQUERY_UPDATE', 2);
|
||||
define('MDB2_AUTOQUERY_DELETE', 3);
|
||||
define('MDB2_AUTOQUERY_SELECT', 4);
|
||||
|
||||
/**
|
||||
* MDB2_Extended: class which adds several high level methods to MDB2
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Extended extends MDB2_Module_Common
|
||||
{
|
||||
// {{{ autoPrepare()
|
||||
|
||||
/**
|
||||
* Generate an insert, update or delete query and call prepare() on it
|
||||
*
|
||||
* @param string table
|
||||
* @param array the fields names
|
||||
* @param int type of query to build
|
||||
* MDB2_AUTOQUERY_INSERT
|
||||
* MDB2_AUTOQUERY_UPDATE
|
||||
* MDB2_AUTOQUERY_DELETE
|
||||
* MDB2_AUTOQUERY_SELECT
|
||||
* @param string (in case of update and delete queries, this string will be put after the sql WHERE statement)
|
||||
* @param array that contains the types of the placeholders
|
||||
* @param mixed array that contains the types of the columns in
|
||||
* the result set or MDB2_PREPARE_RESULT, if set to
|
||||
* MDB2_PREPARE_MANIP the query is handled as a manipulation query
|
||||
*
|
||||
* @return resource handle for the query
|
||||
* @see buildManipSQL
|
||||
* @access public
|
||||
*/
|
||||
function autoPrepare($table, $table_fields, $mode = MDB2_AUTOQUERY_INSERT,
|
||||
$where = false, $types = null, $result_types = MDB2_PREPARE_MANIP)
|
||||
{
|
||||
$query = $this->buildManipSQL($table, $table_fields, $mode, $where);
|
||||
if (PEAR::isError($query)) {
|
||||
return $query;
|
||||
}
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
$lobs = array();
|
||||
foreach ((array)$types as $param => $type) {
|
||||
if (($type == 'clob') || ($type == 'blob')) {
|
||||
$lobs[$param] = $table_fields[$param];
|
||||
}
|
||||
}
|
||||
return $db->prepare($query, $types, $result_types, $lobs);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ autoExecute()
|
||||
|
||||
/**
|
||||
* Generate an insert, update or delete query and call prepare() and execute() on it
|
||||
*
|
||||
* @param string name of the table
|
||||
* @param array assoc ($key=>$value) where $key is a field name and $value its value
|
||||
* @param int type of query to build
|
||||
* MDB2_AUTOQUERY_INSERT
|
||||
* MDB2_AUTOQUERY_UPDATE
|
||||
* MDB2_AUTOQUERY_DELETE
|
||||
* MDB2_AUTOQUERY_SELECT
|
||||
* @param string (in case of update and delete queries, this string will be put after the sql WHERE statement)
|
||||
* @param array that contains the types of the placeholders
|
||||
* @param string which specifies which result class to use
|
||||
* @param mixed array that contains the types of the columns in
|
||||
* the result set or MDB2_PREPARE_RESULT, if set to
|
||||
* MDB2_PREPARE_MANIP the query is handled as a manipulation query
|
||||
*
|
||||
* @return bool|MDB2_Error true on success, a MDB2 error on failure
|
||||
* @see buildManipSQL
|
||||
* @see autoPrepare
|
||||
* @access public
|
||||
*/
|
||||
function autoExecute($table, $fields_values, $mode = MDB2_AUTOQUERY_INSERT,
|
||||
$where = false, $types = null, $result_class = true, $result_types = MDB2_PREPARE_MANIP)
|
||||
{
|
||||
$fields_values = (array)$fields_values;
|
||||
if ($mode == MDB2_AUTOQUERY_SELECT) {
|
||||
if (is_array($result_types)) {
|
||||
$keys = array_keys($result_types);
|
||||
} elseif (!empty($fields_values)) {
|
||||
$keys = $fields_values;
|
||||
} else {
|
||||
$keys = array();
|
||||
}
|
||||
} else {
|
||||
$keys = array_keys($fields_values);
|
||||
}
|
||||
$params = array_values($fields_values);
|
||||
if (empty($params)) {
|
||||
$query = $this->buildManipSQL($table, $keys, $mode, $where);
|
||||
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
if ($mode == MDB2_AUTOQUERY_SELECT) {
|
||||
$result = $db->query($query, $result_types, $result_class);
|
||||
} else {
|
||||
$result = $db->exec($query);
|
||||
}
|
||||
} else {
|
||||
$stmt = $this->autoPrepare($table, $keys, $mode, $where, $types, $result_types);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
$result = $stmt->execute($params, $result_class);
|
||||
$stmt->free();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ buildManipSQL()
|
||||
|
||||
/**
|
||||
* Make automaticaly an sql query for prepare()
|
||||
*
|
||||
* Example : buildManipSQL('table_sql', array('field1', 'field2', 'field3'), MDB2_AUTOQUERY_INSERT)
|
||||
* will return the string : INSERT INTO table_sql (field1,field2,field3) VALUES (?,?,?)
|
||||
* NB : - This belongs more to a SQL Builder class, but this is a simple facility
|
||||
* - Be carefull ! If you don't give a $where param with an UPDATE/DELETE query, all
|
||||
* the records of the table will be updated/deleted !
|
||||
*
|
||||
* @param string name of the table
|
||||
* @param ordered array containing the fields names
|
||||
* @param int type of query to build
|
||||
* MDB2_AUTOQUERY_INSERT
|
||||
* MDB2_AUTOQUERY_UPDATE
|
||||
* MDB2_AUTOQUERY_DELETE
|
||||
* MDB2_AUTOQUERY_SELECT
|
||||
* @param string (in case of update and delete queries, this string will be put after the sql WHERE statement)
|
||||
*
|
||||
* @return string sql query for prepare()
|
||||
* @access public
|
||||
*/
|
||||
function buildManipSQL($table, $table_fields, $mode, $where = false)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if ($db->options['quote_identifier']) {
|
||||
$table = $db->quoteIdentifier($table);
|
||||
}
|
||||
|
||||
if (!empty($table_fields) && $db->options['quote_identifier']) {
|
||||
foreach ($table_fields as $key => $field) {
|
||||
$table_fields[$key] = $db->quoteIdentifier($field);
|
||||
}
|
||||
}
|
||||
|
||||
if ((false !== $where) && (null !== $where)) {
|
||||
if (is_array($where)) {
|
||||
$where = implode(' AND ', $where);
|
||||
}
|
||||
$where = ' WHERE '.$where;
|
||||
}
|
||||
|
||||
switch ($mode) {
|
||||
case MDB2_AUTOQUERY_INSERT:
|
||||
if (empty($table_fields)) {
|
||||
return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'Insert requires table fields', __FUNCTION__);
|
||||
}
|
||||
$cols = implode(', ', $table_fields);
|
||||
$values = '?'.str_repeat(', ?', (count($table_fields) - 1));
|
||||
return 'INSERT INTO '.$table.' ('.$cols.') VALUES ('.$values.')';
|
||||
break;
|
||||
case MDB2_AUTOQUERY_UPDATE:
|
||||
if (empty($table_fields)) {
|
||||
return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
|
||||
'Update requires table fields', __FUNCTION__);
|
||||
}
|
||||
$set = implode(' = ?, ', $table_fields).' = ?';
|
||||
$sql = 'UPDATE '.$table.' SET '.$set.$where;
|
||||
return $sql;
|
||||
break;
|
||||
case MDB2_AUTOQUERY_DELETE:
|
||||
$sql = 'DELETE FROM '.$table.$where;
|
||||
return $sql;
|
||||
break;
|
||||
case MDB2_AUTOQUERY_SELECT:
|
||||
$cols = !empty($table_fields) ? implode(', ', $table_fields) : '*';
|
||||
$sql = 'SELECT '.$cols.' FROM '.$table.$where;
|
||||
return $sql;
|
||||
break;
|
||||
}
|
||||
return $db->raiseError(MDB2_ERROR_SYNTAX, null, null,
|
||||
'Non existant mode', __FUNCTION__);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ limitQuery()
|
||||
|
||||
/**
|
||||
* Generates a limited query
|
||||
*
|
||||
* @param string query
|
||||
* @param array that contains the types of the columns in the result set
|
||||
* @param integer the numbers of rows to fetch
|
||||
* @param integer the row to start to fetching
|
||||
* @param string which specifies which result class to use
|
||||
* @param mixed string which specifies which class to wrap results in
|
||||
*
|
||||
* @return MDB2_Result|MDB2_Error result set on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function limitQuery($query, $types, $limit, $offset = 0, $result_class = true,
|
||||
$result_wrap_class = false)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
$result = $db->setLimit($limit, $offset);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
return $db->query($query, $types, $result_class, $result_wrap_class);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ execParam()
|
||||
|
||||
/**
|
||||
* Execute a parameterized DML statement.
|
||||
*
|
||||
* @param string the SQL query
|
||||
* @param array if supplied, prepare/execute will be used
|
||||
* with this array as execute parameters
|
||||
* @param array that contains the types of the values defined in $params
|
||||
*
|
||||
* @return int|MDB2_Error affected rows on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function execParam($query, $params = array(), $param_types = null)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
settype($params, 'array');
|
||||
if (empty($params)) {
|
||||
return $db->exec($query);
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($query, $param_types, MDB2_PREPARE_MANIP);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
$result = $stmt->execute($params);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$stmt->free();
|
||||
return $result;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getOne()
|
||||
|
||||
/**
|
||||
* Fetch the first column of the first row of data returned from a query.
|
||||
* Takes care of doing the query and freeing the results when finished.
|
||||
*
|
||||
* @param string the SQL query
|
||||
* @param string that contains the type of the column in the result set
|
||||
* @param array if supplied, prepare/execute will be used
|
||||
* with this array as execute parameters
|
||||
* @param array that contains the types of the values defined in $params
|
||||
* @param int|string which column to return
|
||||
*
|
||||
* @return scalar|MDB2_Error data on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getOne($query, $type = null, $params = array(),
|
||||
$param_types = null, $colnum = 0)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
settype($params, 'array');
|
||||
settype($type, 'array');
|
||||
if (empty($params)) {
|
||||
return $db->queryOne($query, $type, $colnum);
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($query, $param_types, $type);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
$result = $stmt->execute($params);
|
||||
if (!MDB2::isResultCommon($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$one = $result->fetchOne($colnum);
|
||||
$stmt->free();
|
||||
$result->free();
|
||||
return $one;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getRow()
|
||||
|
||||
/**
|
||||
* Fetch the first row of data returned from a query. Takes care
|
||||
* of doing the query and freeing the results when finished.
|
||||
*
|
||||
* @param string the SQL query
|
||||
* @param array that contains the types of the columns in the result set
|
||||
* @param array if supplied, prepare/execute will be used
|
||||
* with this array as execute parameters
|
||||
* @param array that contains the types of the values defined in $params
|
||||
* @param int the fetch mode to use
|
||||
*
|
||||
* @return array|MDB2_Error data on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getRow($query, $types = null, $params = array(),
|
||||
$param_types = null, $fetchmode = MDB2_FETCHMODE_DEFAULT)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
settype($params, 'array');
|
||||
if (empty($params)) {
|
||||
return $db->queryRow($query, $types, $fetchmode);
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($query, $param_types, $types);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
$result = $stmt->execute($params);
|
||||
if (!MDB2::isResultCommon($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$row = $result->fetchRow($fetchmode);
|
||||
$stmt->free();
|
||||
$result->free();
|
||||
return $row;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getCol()
|
||||
|
||||
/**
|
||||
* Fetch a single column from a result set and return it as an
|
||||
* indexed array.
|
||||
*
|
||||
* @param string the SQL query
|
||||
* @param string that contains the type of the column in the result set
|
||||
* @param array if supplied, prepare/execute will be used
|
||||
* with this array as execute parameters
|
||||
* @param array that contains the types of the values defined in $params
|
||||
* @param int|string which column to return
|
||||
*
|
||||
* @return array|MDB2_Error data on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getCol($query, $type = null, $params = array(),
|
||||
$param_types = null, $colnum = 0)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
settype($params, 'array');
|
||||
settype($type, 'array');
|
||||
if (empty($params)) {
|
||||
return $db->queryCol($query, $type, $colnum);
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($query, $param_types, $type);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
$result = $stmt->execute($params);
|
||||
if (!MDB2::isResultCommon($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$col = $result->fetchCol($colnum);
|
||||
$stmt->free();
|
||||
$result->free();
|
||||
return $col;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getAll()
|
||||
|
||||
/**
|
||||
* Fetch all the rows returned from a query.
|
||||
*
|
||||
* @param string the SQL query
|
||||
* @param array that contains the types of the columns in the result set
|
||||
* @param array if supplied, prepare/execute will be used
|
||||
* with this array as execute parameters
|
||||
* @param array that contains the types of the values defined in $params
|
||||
* @param int the fetch mode to use
|
||||
* @param bool if set to true, the $all will have the first
|
||||
* column as its first dimension
|
||||
* @param bool $force_array used only when the query returns exactly
|
||||
* two columns. If true, the values of the returned array will be
|
||||
* one-element arrays instead of scalars.
|
||||
* @param bool $group if true, the values of the returned array is
|
||||
* wrapped in another array. If the same key value (in the first
|
||||
* column) repeats itself, the values will be appended to this array
|
||||
* instead of overwriting the existing values.
|
||||
*
|
||||
* @return array|MDB2_Error data on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getAll($query, $types = null, $params = array(),
|
||||
$param_types = null, $fetchmode = MDB2_FETCHMODE_DEFAULT,
|
||||
$rekey = false, $force_array = false, $group = false)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
settype($params, 'array');
|
||||
if (empty($params)) {
|
||||
return $db->queryAll($query, $types, $fetchmode, $rekey, $force_array, $group);
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($query, $param_types, $types);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
$result = $stmt->execute($params);
|
||||
if (!MDB2::isResultCommon($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$all = $result->fetchAll($fetchmode, $rekey, $force_array, $group);
|
||||
$stmt->free();
|
||||
$result->free();
|
||||
return $all;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getAssoc()
|
||||
|
||||
/**
|
||||
* Fetch the entire result set of a query and return it as an
|
||||
* associative array using the first column as the key.
|
||||
*
|
||||
* If the result set contains more than two columns, the value
|
||||
* will be an array of the values from column 2-n. If the result
|
||||
* set contains only two columns, the returned value will be a
|
||||
* scalar with the value of the second column (unless forced to an
|
||||
* array with the $force_array parameter). A MDB2 error code is
|
||||
* returned on errors. If the result set contains fewer than two
|
||||
* columns, a MDB2_ERROR_TRUNCATED error is returned.
|
||||
*
|
||||
* For example, if the table 'mytable' contains:
|
||||
* <pre>
|
||||
* ID TEXT DATE
|
||||
* --------------------------------
|
||||
* 1 'one' 944679408
|
||||
* 2 'two' 944679408
|
||||
* 3 'three' 944679408
|
||||
* </pre>
|
||||
* Then the call getAssoc('SELECT id,text FROM mytable') returns:
|
||||
* <pre>
|
||||
* array(
|
||||
* '1' => 'one',
|
||||
* '2' => 'two',
|
||||
* '3' => 'three',
|
||||
* )
|
||||
* </pre>
|
||||
* ...while the call getAssoc('SELECT id,text,date FROM mytable') returns:
|
||||
* <pre>
|
||||
* array(
|
||||
* '1' => array('one', '944679408'),
|
||||
* '2' => array('two', '944679408'),
|
||||
* '3' => array('three', '944679408')
|
||||
* )
|
||||
* </pre>
|
||||
*
|
||||
* If the more than one row occurs with the same value in the
|
||||
* first column, the last row overwrites all previous ones by
|
||||
* default. Use the $group parameter if you don't want to
|
||||
* overwrite like this. Example:
|
||||
* <pre>
|
||||
* getAssoc('SELECT category,id,name FROM mytable', null, null
|
||||
* MDB2_FETCHMODE_ASSOC, false, true) returns:
|
||||
* array(
|
||||
* '1' => array(array('id' => '4', 'name' => 'number four'),
|
||||
* array('id' => '6', 'name' => 'number six')
|
||||
* ),
|
||||
* '9' => array(array('id' => '4', 'name' => 'number four'),
|
||||
* array('id' => '6', 'name' => 'number six')
|
||||
* )
|
||||
* )
|
||||
* </pre>
|
||||
*
|
||||
* Keep in mind that database functions in PHP usually return string
|
||||
* values for results regardless of the database's internal type.
|
||||
*
|
||||
* @param string the SQL query
|
||||
* @param array that contains the types of the columns in the result set
|
||||
* @param array if supplied, prepare/execute will be used
|
||||
* with this array as execute parameters
|
||||
* @param array that contains the types of the values defined in $params
|
||||
* @param bool $force_array used only when the query returns
|
||||
* exactly two columns. If TRUE, the values of the returned array
|
||||
* will be one-element arrays instead of scalars.
|
||||
* @param bool $group if TRUE, the values of the returned array
|
||||
* is wrapped in another array. If the same key value (in the first
|
||||
* column) repeats itself, the values will be appended to this array
|
||||
* instead of overwriting the existing values.
|
||||
*
|
||||
* @return array|MDB2_Error data on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getAssoc($query, $types = null, $params = array(), $param_types = null,
|
||||
$fetchmode = MDB2_FETCHMODE_DEFAULT, $force_array = false, $group = false)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
settype($params, 'array');
|
||||
if (empty($params)) {
|
||||
return $db->queryAll($query, $types, $fetchmode, true, $force_array, $group);
|
||||
}
|
||||
|
||||
$stmt = $db->prepare($query, $param_types, $types);
|
||||
if (PEAR::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
$result = $stmt->execute($params);
|
||||
if (!MDB2::isResultCommon($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$all = $result->fetchAll($fetchmode, true, $force_array, $group);
|
||||
$stmt->free();
|
||||
$result->free();
|
||||
return $all;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ executeMultiple()
|
||||
|
||||
/**
|
||||
* This function does several execute() calls on the same statement handle.
|
||||
* $params must be an array indexed numerically from 0, one execute call is
|
||||
* done for every 'row' in the array.
|
||||
*
|
||||
* If an error occurs during execute(), executeMultiple() does not execute
|
||||
* the unfinished rows, but rather returns that error.
|
||||
*
|
||||
* @param resource query handle from prepare()
|
||||
* @param array numeric array containing the data to insert into the query
|
||||
*
|
||||
* @return bool|MDB2_Error true on success, a MDB2 error on failure
|
||||
* @access public
|
||||
* @see prepare(), execute()
|
||||
*/
|
||||
function executeMultiple($stmt, $params = null)
|
||||
{
|
||||
if (MDB2::isError($stmt)) {
|
||||
return $stmt;
|
||||
}
|
||||
for ($i = 0, $j = count($params); $i < $j; $i++) {
|
||||
$result = $stmt->execute($params[$i]);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getBeforeID()
|
||||
|
||||
/**
|
||||
* Returns the next free id of a sequence if the RDBMS
|
||||
* does not support auto increment
|
||||
*
|
||||
* @param string name of the table into which a new row was inserted
|
||||
* @param string name of the field into which a new row was inserted
|
||||
* @param bool when true the sequence is automatic created, if it not exists
|
||||
* @param bool if the returned value should be quoted
|
||||
*
|
||||
* @return int|MDB2_Error id on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getBeforeID($table, $field = null, $ondemand = true, $quote = true)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if ($db->supports('auto_increment') !== true) {
|
||||
$seq = $table.(empty($field) ? '' : '_'.$field);
|
||||
$id = $db->nextID($seq, $ondemand);
|
||||
if (!$quote || PEAR::isError($id)) {
|
||||
return $id;
|
||||
}
|
||||
return $db->quote($id, 'integer');
|
||||
} elseif (!$quote) {
|
||||
return null;
|
||||
}
|
||||
return 'NULL';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getAfterID()
|
||||
|
||||
/**
|
||||
* Returns the autoincrement ID if supported or $id
|
||||
*
|
||||
* @param mixed value as returned by getBeforeId()
|
||||
* @param string name of the table into which a new row was inserted
|
||||
* @param string name of the field into which a new row was inserted
|
||||
*
|
||||
* @return int|MDB2_Error id on success, a MDB2 error on failure
|
||||
* @access public
|
||||
*/
|
||||
function getAfterID($id, $table, $field = null)
|
||||
{
|
||||
$db = $this->getDBInstance();
|
||||
if (PEAR::isError($db)) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
if ($db->supports('auto_increment') !== true) {
|
||||
return $id;
|
||||
}
|
||||
return $db->lastInsertID($table, $field);
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
?>
|
||||
Vendored
+262
@@ -0,0 +1,262 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP version 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2006 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his 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 |
|
||||
// | REGENTS 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
|
||||
/**
|
||||
* PHP5 Iterator
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_Iterator implements Iterator
|
||||
{
|
||||
protected $fetchmode;
|
||||
/**
|
||||
* @var MDB2_Result_Common
|
||||
*/
|
||||
protected $result;
|
||||
protected $row;
|
||||
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct(MDB2_Result_Common $result, $fetchmode = MDB2_FETCHMODE_DEFAULT)
|
||||
{
|
||||
$this->result = $result;
|
||||
$this->fetchmode = $fetchmode;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ seek()
|
||||
|
||||
/**
|
||||
* Seek forward to a specific row in a result set
|
||||
*
|
||||
* @param int number of the row where the data can be found
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function seek($rownum)
|
||||
{
|
||||
$this->row = null;
|
||||
if ($this->result) {
|
||||
$this->result->seek($rownum);
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ next()
|
||||
|
||||
/**
|
||||
* Fetch next row of data
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$this->row = null;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ current()
|
||||
|
||||
/**
|
||||
* return a row of data
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
if (null === $this->row) {
|
||||
$row = $this->result->fetchRow($this->fetchmode);
|
||||
if (PEAR::isError($row)) {
|
||||
$row = false;
|
||||
}
|
||||
$this->row = $row;
|
||||
}
|
||||
return $this->row;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ valid()
|
||||
|
||||
/**
|
||||
* Check if the end of the result set has been reached
|
||||
*
|
||||
* @return bool true/false, false is also returned on failure
|
||||
* @access public
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return (bool)$this->current();
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ free()
|
||||
|
||||
/**
|
||||
* Free the internal resources associated with result.
|
||||
*
|
||||
* @return bool|MDB2_Error true on success, false|MDB2_Error if result is invalid
|
||||
* @access public
|
||||
*/
|
||||
public function free()
|
||||
{
|
||||
if ($this->result) {
|
||||
return $this->result->free();
|
||||
}
|
||||
$this->result = false;
|
||||
$this->row = null;
|
||||
return false;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ key()
|
||||
|
||||
/**
|
||||
* Returns the row number
|
||||
*
|
||||
* @return int|bool|MDB2_Error true on success, false|MDB2_Error if result is invalid
|
||||
* @access public
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
if ($this->result) {
|
||||
return $this->result->rowCount();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ rewind()
|
||||
|
||||
/**
|
||||
* Seek to the first row in a result set
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ destructor
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->free();
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP5 buffered Iterator
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_BufferedIterator extends MDB2_Iterator implements SeekableIterator
|
||||
{
|
||||
// {{{ valid()
|
||||
|
||||
/**
|
||||
* Check if the end of the result set has been reached
|
||||
*
|
||||
* @return bool|MDB2_Error true on success, false|MDB2_Error if result is invalid
|
||||
* @access public
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
if ($this->result) {
|
||||
return $this->result->valid();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{count()
|
||||
|
||||
/**
|
||||
* Returns the number of rows in a result object
|
||||
*
|
||||
* @return int|MDB2_Error number of rows, false|MDB2_Error if result is invalid
|
||||
* @access public
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
if ($this->result) {
|
||||
return $this->result->numRows();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ rewind()
|
||||
|
||||
/**
|
||||
* Seek to the first row in a result set
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->seek(0);
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
|
||||
?>
|
||||
Vendored
+264
@@ -0,0 +1,264 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP version 5 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1998-2006 Manuel Lemos, Tomas V.V.Cox, |
|
||||
// | Stig. S. Bakken, Lukas Smith |
|
||||
// | All rights reserved. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB |
|
||||
// | API as well as database abstraction for PHP applications. |
|
||||
// | This LICENSE is in the BSD license style. |
|
||||
// | |
|
||||
// | 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, |
|
||||
// | Lukas Smith nor the names of his 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 |
|
||||
// | REGENTS 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. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Lukas Smith <smith@pooteeweet.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
|
||||
/**
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
|
||||
require_once 'MDB2.php';
|
||||
|
||||
/**
|
||||
* MDB2_LOB: user land stream wrapper implementation for LOB support
|
||||
*
|
||||
* @package MDB2
|
||||
* @category Database
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
*/
|
||||
class MDB2_LOB
|
||||
{
|
||||
/**
|
||||
* contains the key to the global MDB2 instance array of the associated
|
||||
* MDB2 instance
|
||||
*
|
||||
* @var integer
|
||||
* @access protected
|
||||
*/
|
||||
var $db_index;
|
||||
|
||||
/**
|
||||
* contains the key to the global MDB2_LOB instance array of the associated
|
||||
* MDB2_LOB instance
|
||||
*
|
||||
* @var integer
|
||||
* @access protected
|
||||
*/
|
||||
var $lob_index;
|
||||
|
||||
// {{{ stream_open()
|
||||
|
||||
/**
|
||||
* open stream
|
||||
*
|
||||
* @param string specifies the URL that was passed to fopen()
|
||||
* @param string the mode used to open the file
|
||||
* @param int holds additional flags set by the streams API
|
||||
* @param string not used
|
||||
*
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
if (!preg_match('/^rb?\+?$/', $mode)) {
|
||||
return false;
|
||||
}
|
||||
$url = parse_url($path);
|
||||
if (empty($url['host'])) {
|
||||
return false;
|
||||
}
|
||||
$this->db_index = (int)$url['host'];
|
||||
if (!isset($GLOBALS['_MDB2_databases'][$this->db_index])) {
|
||||
return false;
|
||||
}
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$this->lob_index = (int)$url['user'];
|
||||
if (!isset($db->datatype->lobs[$this->lob_index])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ stream_read()
|
||||
|
||||
/**
|
||||
* read stream
|
||||
*
|
||||
* @param int number of bytes to read
|
||||
*
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function stream_read($count)
|
||||
{
|
||||
if (isset($GLOBALS['_MDB2_databases'][$this->db_index])) {
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$db->datatype->_retrieveLOB($db->datatype->lobs[$this->lob_index]);
|
||||
|
||||
$data = $db->datatype->_readLOB($db->datatype->lobs[$this->lob_index], $count);
|
||||
$length = strlen($data);
|
||||
if ($length == 0) {
|
||||
$db->datatype->lobs[$this->lob_index]['endOfLOB'] = true;
|
||||
}
|
||||
$db->datatype->lobs[$this->lob_index]['position'] += $length;
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ stream_write()
|
||||
|
||||
/**
|
||||
* write stream, note implemented
|
||||
*
|
||||
* @param string data
|
||||
*
|
||||
* @return int
|
||||
* @access public
|
||||
*/
|
||||
function stream_write($data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ stream_tell()
|
||||
|
||||
/**
|
||||
* return the current position
|
||||
*
|
||||
* @return int current position
|
||||
* @access public
|
||||
*/
|
||||
function stream_tell()
|
||||
{
|
||||
if (isset($GLOBALS['_MDB2_databases'][$this->db_index])) {
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
return $db->datatype->lobs[$this->lob_index]['position'];
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ stream_eof()
|
||||
|
||||
/**
|
||||
* Check if stream reaches EOF
|
||||
*
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function stream_eof()
|
||||
{
|
||||
if (!isset($GLOBALS['_MDB2_databases'][$this->db_index])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
$result = $db->datatype->_endOfLOB($db->datatype->lobs[$this->lob_index]);
|
||||
if (version_compare(phpversion(), "5.0", ">=")
|
||||
&& version_compare(phpversion(), "5.1", "<")
|
||||
) {
|
||||
return !$result;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ stream_seek()
|
||||
|
||||
/**
|
||||
* Seek stream, not implemented
|
||||
*
|
||||
* @param int offset
|
||||
* @param int whence
|
||||
*
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function stream_seek($offset, $whence)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ stream_stat()
|
||||
|
||||
/**
|
||||
* return information about stream
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function stream_stat()
|
||||
{
|
||||
if (isset($GLOBALS['_MDB2_databases'][$this->db_index])) {
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
return array(
|
||||
'db_index' => $this->db_index,
|
||||
'lob_index' => $this->lob_index,
|
||||
);
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ stream_close()
|
||||
|
||||
/**
|
||||
* close stream
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function stream_close()
|
||||
{
|
||||
if (isset($GLOBALS['_MDB2_databases'][$this->db_index])) {
|
||||
$db =& $GLOBALS['_MDB2_databases'][$this->db_index];
|
||||
if (isset($db->datatype->lobs[$this->lob_index])) {
|
||||
$db->datatype->_destroyLOB($db->datatype->lobs[$this->lob_index]);
|
||||
unset($db->datatype->lobs[$this->lob_index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
|
||||
// register streams wrapper
|
||||
if (!stream_wrapper_register("MDB2LOB", "MDB2_LOB")) {
|
||||
MDB2::raiseError();
|
||||
return false;
|
||||
}
|
||||
|
||||
?>
|
||||
Vendored
+2797
File diff suppressed because it is too large
Load Diff
Vendored
+903
@@ -0,0 +1,903 @@
|
||||
<?php /* vim: se et ts=4 sw=4 sts=4 fdm=marker tw=80: */
|
||||
/**
|
||||
* Copyright (c) 1998-2010 Manuel Lemos, Tomas V.V.Cox,
|
||||
* Stig. S. Bakken, Lukas Smith, Igor Feghali
|
||||
* All rights reserved.
|
||||
*
|
||||
* MDB2_Schema enables users to maintain RDBMS independant schema files
|
||||
* in XML that can be used to manipulate both data and database schemas
|
||||
* This LICENSE is in the BSD license style.
|
||||
*
|
||||
* 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,
|
||||
* Lukas Smith, Igor Feghali nor the names of his 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
|
||||
* REGENTS 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.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Database
|
||||
* @package MDB2_Schema
|
||||
* @author Christian Dickmann <dickmann@php.net>
|
||||
* @author Igor Feghali <ifeghali@php.net>
|
||||
* @license BSD http://www.opensource.org/licenses/bsd-license.php
|
||||
* @version SVN: $Id$
|
||||
* @link http://pear.php.net/packages/MDB2_Schema
|
||||
*/
|
||||
|
||||
require_once 'XML/Parser.php';
|
||||
require_once 'MDB2/Schema/Validate.php';
|
||||
|
||||
/**
|
||||
* Parses an XML schema file
|
||||
*
|
||||
* @category Database
|
||||
* @package MDB2_Schema
|
||||
* @author Christian Dickmann <dickmann@php.net>
|
||||
* @license BSD http://www.opensource.org/licenses/bsd-license.php
|
||||
* @link http://pear.php.net/packages/MDB2_Schema
|
||||
*/
|
||||
class MDB2_Schema_Parser extends XML_Parser
|
||||
{
|
||||
var $database_definition = array();
|
||||
|
||||
var $elements = array();
|
||||
|
||||
var $element = '';
|
||||
|
||||
var $count = 0;
|
||||
|
||||
var $table = array();
|
||||
|
||||
var $table_name = '';
|
||||
|
||||
var $field = array();
|
||||
|
||||
var $field_name = '';
|
||||
|
||||
var $init = array();
|
||||
|
||||
var $init_function = array();
|
||||
|
||||
var $init_expression = array();
|
||||
|
||||
var $init_field = array();
|
||||
|
||||
var $index = array();
|
||||
|
||||
var $index_name = '';
|
||||
|
||||
var $constraint = array();
|
||||
|
||||
var $constraint_name = '';
|
||||
|
||||
var $var_mode = false;
|
||||
|
||||
var $variables = array();
|
||||
|
||||
var $sequence = array();
|
||||
|
||||
var $sequence_name = '';
|
||||
|
||||
var $error;
|
||||
|
||||
var $structure = false;
|
||||
|
||||
var $val;
|
||||
|
||||
/**
|
||||
* PHP 5 constructor
|
||||
*
|
||||
* @param array $variables mixed array with user defined schema
|
||||
* variables
|
||||
* @param bool $fail_on_invalid_names array with reserved words per RDBMS
|
||||
* @param array $structure multi dimensional array with
|
||||
* database schema and data
|
||||
* @param array $valid_types information of all valid fields
|
||||
* types
|
||||
* @param bool $force_defaults if true sets a default value to
|
||||
* field when not explicit
|
||||
* @param int $max_identifiers_length maximum allowed size for entities
|
||||
* name
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function __construct($variables, $fail_on_invalid_names = true,
|
||||
$structure = false, $valid_types = array(), $force_defaults = true,
|
||||
$max_identifiers_length = null
|
||||
) {
|
||||
// force ISO-8859-1 due to different defaults for PHP4 and PHP5
|
||||
// todo: this probably needs to be investigated some more andcleaned up
|
||||
parent::__construct('ISO-8859-1');
|
||||
|
||||
$this->variables = $variables;
|
||||
$this->structure = $structure;
|
||||
$this->val = new MDB2_Schema_Validate(
|
||||
$fail_on_invalid_names,
|
||||
$valid_types,
|
||||
$force_defaults,
|
||||
$max_identifiers_length
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP 4 compatible constructor
|
||||
*
|
||||
* @param array $variables mixed array with user defined schema
|
||||
* variables
|
||||
* @param bool $fail_on_invalid_names array with reserved words per RDBMS
|
||||
* @param array $structure multi dimensional array with
|
||||
* database schema and data
|
||||
* @param array $valid_types information of all valid fields
|
||||
* types
|
||||
* @param bool $force_defaults if true sets a default value to
|
||||
* field when not explicit
|
||||
* @param int $max_identifiers_length maximum allowed size for entities
|
||||
* name
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function MDB2_Schema_Parser($variables, $fail_on_invalid_names = true,
|
||||
$structure = false, $valid_types = array(), $force_defaults = true,
|
||||
$max_identifiers_length = null
|
||||
) {
|
||||
$this->__construct($variables, $fail_on_invalid_names, $structure, $valid_types, $force_defaults);
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered when reading a XML open tag <element>
|
||||
*
|
||||
* @param resource $xp xml parser resource
|
||||
* @param string $element element name
|
||||
* @param array $attribs attributes
|
||||
*
|
||||
* @return void
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
function startHandler($xp, $element, &$attribs)
|
||||
{
|
||||
if (strtolower($element) == 'variable') {
|
||||
$this->var_mode = true;
|
||||
return;
|
||||
}
|
||||
|
||||
$this->elements[$this->count++] = strtolower($element);
|
||||
|
||||
$this->element = implode('-', $this->elements);
|
||||
|
||||
switch ($this->element) {
|
||||
/* Initialization */
|
||||
case 'database-table-initialization':
|
||||
$this->table['initialization'] = array();
|
||||
break;
|
||||
|
||||
/* Insert */
|
||||
/* insert: field+ */
|
||||
case 'database-table-initialization-insert':
|
||||
$this->init = array('type' => 'insert', 'data' => array('field' => array()));
|
||||
break;
|
||||
/* insert-select: field+, table, where? */
|
||||
case 'database-table-initialization-insert-select':
|
||||
$this->init['data']['table'] = '';
|
||||
break;
|
||||
|
||||
/* Update */
|
||||
/* update: field+, where? */
|
||||
case 'database-table-initialization-update':
|
||||
$this->init = array('type' => 'update', 'data' => array('field' => array()));
|
||||
break;
|
||||
|
||||
/* Delete */
|
||||
/* delete: where */
|
||||
case 'database-table-initialization-delete':
|
||||
$this->init = array('type' => 'delete', 'data' => array('where' => array()));
|
||||
break;
|
||||
|
||||
/* Insert and Update */
|
||||
case 'database-table-initialization-insert-field':
|
||||
case 'database-table-initialization-insert-select-field':
|
||||
case 'database-table-initialization-update-field':
|
||||
$this->init_field = array('name' => '', 'group' => array());
|
||||
break;
|
||||
case 'database-table-initialization-insert-field-value':
|
||||
case 'database-table-initialization-insert-select-field-value':
|
||||
case 'database-table-initialization-update-field-value':
|
||||
/* if value tag is empty cdataHandler is not called so we must force value element creation here */
|
||||
$this->init_field['group'] = array('type' => 'value', 'data' => '');
|
||||
break;
|
||||
case 'database-table-initialization-insert-field-null':
|
||||
case 'database-table-initialization-insert-select-field-null':
|
||||
case 'database-table-initialization-update-field-null':
|
||||
$this->init_field['group'] = array('type' => 'null');
|
||||
break;
|
||||
case 'database-table-initialization-insert-field-function':
|
||||
case 'database-table-initialization-insert-select-field-function':
|
||||
case 'database-table-initialization-update-field-function':
|
||||
$this->init_function = array('name' => '');
|
||||
break;
|
||||
case 'database-table-initialization-insert-field-expression':
|
||||
case 'database-table-initialization-insert-select-field-expression':
|
||||
case 'database-table-initialization-update-field-expression':
|
||||
$this->init_expression = array();
|
||||
break;
|
||||
|
||||
/* All */
|
||||
case 'database-table-initialization-insert-select-where':
|
||||
case 'database-table-initialization-update-where':
|
||||
case 'database-table-initialization-delete-where':
|
||||
$this->init['data']['where'] = array('type' => '', 'data' => array());
|
||||
break;
|
||||
case 'database-table-initialization-insert-select-where-expression':
|
||||
case 'database-table-initialization-update-where-expression':
|
||||
case 'database-table-initialization-delete-where-expression':
|
||||
$this->init_expression = array();
|
||||
break;
|
||||
|
||||
/* One level simulation of expression-function recursion */
|
||||
case 'database-table-initialization-insert-field-expression-function':
|
||||
case 'database-table-initialization-insert-select-field-expression-function':
|
||||
case 'database-table-initialization-insert-select-where-expression-function':
|
||||
case 'database-table-initialization-update-field-expression-function':
|
||||
case 'database-table-initialization-update-where-expression-function':
|
||||
case 'database-table-initialization-delete-where-expression-function':
|
||||
$this->init_function = array('name' => '');
|
||||
break;
|
||||
|
||||
/* One level simulation of function-expression recursion */
|
||||
case 'database-table-initialization-insert-field-function-expression':
|
||||
case 'database-table-initialization-insert-select-field-function-expression':
|
||||
case 'database-table-initialization-insert-select-where-function-expression':
|
||||
case 'database-table-initialization-update-field-function-expression':
|
||||
case 'database-table-initialization-update-where-function-expression':
|
||||
case 'database-table-initialization-delete-where-function-expression':
|
||||
$this->init_expression = array();
|
||||
break;
|
||||
|
||||
/* Definition */
|
||||
case 'database':
|
||||
$this->database_definition = array(
|
||||
'name' => '',
|
||||
'create' => '',
|
||||
'overwrite' => '',
|
||||
'charset' => '',
|
||||
'description' => '',
|
||||
'comments' => '',
|
||||
'tables' => array(),
|
||||
'sequences' => array()
|
||||
);
|
||||
break;
|
||||
case 'database-table':
|
||||
$this->table_name = '';
|
||||
|
||||
$this->table = array(
|
||||
'was' => '',
|
||||
'description' => '',
|
||||
'comments' => '',
|
||||
'fields' => array(),
|
||||
'indexes' => array(),
|
||||
'constraints' => array(),
|
||||
'initialization' => array()
|
||||
);
|
||||
break;
|
||||
case 'database-table-declaration-field':
|
||||
case 'database-table-declaration-foreign-field':
|
||||
case 'database-table-declaration-foreign-references-field':
|
||||
$this->field_name = '';
|
||||
|
||||
$this->field = array();
|
||||
break;
|
||||
case 'database-table-declaration-index-field':
|
||||
$this->field_name = '';
|
||||
|
||||
$this->field = array('sorting' => '', 'length' => '');
|
||||
break;
|
||||
/* force field attributes to be initialized when the tag is empty in the XML */
|
||||
case 'database-table-declaration-field-was':
|
||||
$this->field['was'] = '';
|
||||
break;
|
||||
case 'database-table-declaration-field-type':
|
||||
$this->field['type'] = '';
|
||||
break;
|
||||
case 'database-table-declaration-field-fixed':
|
||||
$this->field['fixed'] = '';
|
||||
break;
|
||||
case 'database-table-declaration-field-default':
|
||||
$this->field['default'] = '';
|
||||
break;
|
||||
case 'database-table-declaration-field-notnull':
|
||||
$this->field['notnull'] = '';
|
||||
break;
|
||||
case 'database-table-declaration-field-autoincrement':
|
||||
$this->field['autoincrement'] = '';
|
||||
break;
|
||||
case 'database-table-declaration-field-unsigned':
|
||||
$this->field['unsigned'] = '';
|
||||
break;
|
||||
case 'database-table-declaration-field-length':
|
||||
$this->field['length'] = '';
|
||||
break;
|
||||
case 'database-table-declaration-field-description':
|
||||
$this->field['description'] = '';
|
||||
break;
|
||||
case 'database-table-declaration-field-comments':
|
||||
$this->field['comments'] = '';
|
||||
break;
|
||||
case 'database-table-declaration-index':
|
||||
$this->index_name = '';
|
||||
|
||||
$this->index = array(
|
||||
'was' => '',
|
||||
'unique' =>'',
|
||||
'primary' => '',
|
||||
'fields' => array()
|
||||
);
|
||||
break;
|
||||
case 'database-table-declaration-foreign':
|
||||
$this->constraint_name = '';
|
||||
|
||||
$this->constraint = array(
|
||||
'was' => '',
|
||||
'match' => '',
|
||||
'ondelete' => '',
|
||||
'onupdate' => '',
|
||||
'deferrable' => '',
|
||||
'initiallydeferred' => '',
|
||||
'foreign' => true,
|
||||
'fields' => array(),
|
||||
'references' => array('table' => '', 'fields' => array())
|
||||
);
|
||||
break;
|
||||
case 'database-sequence':
|
||||
$this->sequence_name = '';
|
||||
|
||||
$this->sequence = array(
|
||||
'was' => '',
|
||||
'start' => '',
|
||||
'description' => '',
|
||||
'comments' => '',
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered when reading a XML close tag </element>
|
||||
*
|
||||
* @param resource $xp xml parser resource
|
||||
* @param string $element element name
|
||||
*
|
||||
* @return void
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
function endHandler($xp, $element)
|
||||
{
|
||||
if (strtolower($element) == 'variable') {
|
||||
$this->var_mode = false;
|
||||
return;
|
||||
}
|
||||
|
||||
switch ($this->element) {
|
||||
/* Initialization */
|
||||
|
||||
/* Insert */
|
||||
case 'database-table-initialization-insert-select':
|
||||
$this->init['data'] = array('select' => $this->init['data']);
|
||||
break;
|
||||
|
||||
/* Insert and Delete */
|
||||
case 'database-table-initialization-insert-field':
|
||||
case 'database-table-initialization-insert-select-field':
|
||||
case 'database-table-initialization-update-field':
|
||||
$result = $this->val->validateDataField($this->table['fields'], $this->init['data']['field'], $this->init_field);
|
||||
if (PEAR::isError($result)) {
|
||||
$this->raiseError($result->getUserinfo(), 0, $xp, $result->getCode());
|
||||
} else {
|
||||
$this->init['data']['field'][] = $this->init_field;
|
||||
}
|
||||
break;
|
||||
case 'database-table-initialization-insert-field-function':
|
||||
case 'database-table-initialization-insert-select-field-function':
|
||||
case 'database-table-initialization-update-field-function':
|
||||
$this->init_field['group'] = array('type' => 'function', 'data' => $this->init_function);
|
||||
break;
|
||||
case 'database-table-initialization-insert-field-expression':
|
||||
case 'database-table-initialization-insert-select-field-expression':
|
||||
case 'database-table-initialization-update-field-expression':
|
||||
$this->init_field['group'] = array('type' => 'expression', 'data' => $this->init_expression);
|
||||
break;
|
||||
|
||||
/* All */
|
||||
case 'database-table-initialization-insert-select-where-expression':
|
||||
case 'database-table-initialization-update-where-expression':
|
||||
case 'database-table-initialization-delete-where-expression':
|
||||
$this->init['data']['where']['type'] = 'expression';
|
||||
$this->init['data']['where']['data'] = $this->init_expression;
|
||||
break;
|
||||
case 'database-table-initialization-insert':
|
||||
case 'database-table-initialization-delete':
|
||||
case 'database-table-initialization-update':
|
||||
$this->table['initialization'][] = $this->init;
|
||||
break;
|
||||
|
||||
/* One level simulation of expression-function recursion */
|
||||
case 'database-table-initialization-insert-field-expression-function':
|
||||
case 'database-table-initialization-insert-select-field-expression-function':
|
||||
case 'database-table-initialization-insert-select-where-expression-function':
|
||||
case 'database-table-initialization-update-field-expression-function':
|
||||
case 'database-table-initialization-update-where-expression-function':
|
||||
case 'database-table-initialization-delete-where-expression-function':
|
||||
$this->init_expression['operants'][] = array('type' => 'function', 'data' => $this->init_function);
|
||||
break;
|
||||
|
||||
/* One level simulation of function-expression recursion */
|
||||
case 'database-table-initialization-insert-field-function-expression':
|
||||
case 'database-table-initialization-insert-select-field-function-expression':
|
||||
case 'database-table-initialization-insert-select-where-function-expression':
|
||||
case 'database-table-initialization-update-field-function-expression':
|
||||
case 'database-table-initialization-update-where-function-expression':
|
||||
case 'database-table-initialization-delete-where-function-expression':
|
||||
$this->init_function['arguments'][] = array('type' => 'expression', 'data' => $this->init_expression);
|
||||
break;
|
||||
|
||||
/* Table definition */
|
||||
case 'database-table':
|
||||
$result = $this->val->validateTable($this->database_definition['tables'], $this->table, $this->table_name);
|
||||
if (PEAR::isError($result)) {
|
||||
$this->raiseError($result->getUserinfo(), 0, $xp, $result->getCode());
|
||||
} else {
|
||||
$this->database_definition['tables'][$this->table_name] = $this->table;
|
||||
}
|
||||
break;
|
||||
case 'database-table-name':
|
||||
if (isset($this->structure['tables'][$this->table_name])) {
|
||||
$this->table = $this->structure['tables'][$this->table_name];
|
||||
}
|
||||
break;
|
||||
|
||||
/* Field declaration */
|
||||
case 'database-table-declaration-field':
|
||||
$result = $this->val->validateField($this->table['fields'], $this->field, $this->field_name);
|
||||
if (PEAR::isError($result)) {
|
||||
$this->raiseError($result->getUserinfo(), 0, $xp, $result->getCode());
|
||||
} else {
|
||||
$this->table['fields'][$this->field_name] = $this->field;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Index declaration */
|
||||
case 'database-table-declaration-index':
|
||||
$result = $this->val->validateIndex($this->table['indexes'], $this->index, $this->index_name);
|
||||
if (PEAR::isError($result)) {
|
||||
$this->raiseError($result->getUserinfo(), 0, $xp, $result->getCode());
|
||||
} else {
|
||||
$this->table['indexes'][$this->index_name] = $this->index;
|
||||
}
|
||||
break;
|
||||
case 'database-table-declaration-index-field':
|
||||
$result = $this->val->validateIndexField($this->index['fields'], $this->field, $this->field_name);
|
||||
if (PEAR::isError($result)) {
|
||||
$this->raiseError($result->getUserinfo(), 0, $xp, $result->getCode());
|
||||
} else {
|
||||
$this->index['fields'][$this->field_name] = $this->field;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Foreign Key declaration */
|
||||
case 'database-table-declaration-foreign':
|
||||
$result = $this->val->validateConstraint($this->table['constraints'], $this->constraint, $this->constraint_name);
|
||||
if (PEAR::isError($result)) {
|
||||
$this->raiseError($result->getUserinfo(), 0, $xp, $result->getCode());
|
||||
} else {
|
||||
$this->table['constraints'][$this->constraint_name] = $this->constraint;
|
||||
}
|
||||
break;
|
||||
case 'database-table-declaration-foreign-field':
|
||||
$result = $this->val->validateConstraintField($this->constraint['fields'], $this->field_name);
|
||||
if (PEAR::isError($result)) {
|
||||
$this->raiseError($result->getUserinfo(), 0, $xp, $result->getCode());
|
||||
} else {
|
||||
$this->constraint['fields'][$this->field_name] = '';
|
||||
}
|
||||
break;
|
||||
case 'database-table-declaration-foreign-references-field':
|
||||
$result = $this->val->validateConstraintReferencedField($this->constraint['references']['fields'], $this->field_name);
|
||||
if (PEAR::isError($result)) {
|
||||
$this->raiseError($result->getUserinfo(), 0, $xp, $result->getCode());
|
||||
} else {
|
||||
$this->constraint['references']['fields'][$this->field_name] = '';
|
||||
}
|
||||
break;
|
||||
|
||||
/* Sequence declaration */
|
||||
case 'database-sequence':
|
||||
$result = $this->val->validateSequence($this->database_definition['sequences'], $this->sequence, $this->sequence_name);
|
||||
if (PEAR::isError($result)) {
|
||||
$this->raiseError($result->getUserinfo(), 0, $xp, $result->getCode());
|
||||
} else {
|
||||
$this->database_definition['sequences'][$this->sequence_name] = $this->sequence;
|
||||
}
|
||||
break;
|
||||
|
||||
/* End of File */
|
||||
case 'database':
|
||||
$result = $this->val->validateDatabase($this->database_definition);
|
||||
if (PEAR::isError($result)) {
|
||||
$this->raiseError($result->getUserinfo(), 0, $xp, $result->getCode());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
unset($this->elements[--$this->count]);
|
||||
$this->element = implode('-', $this->elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes a MDB2_Schema_Error into stack and returns it
|
||||
*
|
||||
* @param string $msg textual message
|
||||
* @param int $xmlecode PHP's XML parser error code
|
||||
* @param resource $xp xml parser resource
|
||||
* @param int $ecode MDB2_Schema's error code
|
||||
*
|
||||
* @return object
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
static function &raiseError($msg = null, $xmlecode = 0, $xp = null, $ecode = MDB2_SCHEMA_ERROR_PARSE, $userinfo = null,
|
||||
$error_class = null,
|
||||
$skipmsg = false)
|
||||
{
|
||||
if (is_null($this->error)) {
|
||||
$error = '';
|
||||
if (is_resource($msg)) {
|
||||
$error .= 'Parser error: '.xml_error_string(xml_get_error_code($msg));
|
||||
$xp = $msg;
|
||||
} else {
|
||||
$error .= 'Parser error: '.$msg;
|
||||
if (!is_resource($xp)) {
|
||||
$xp = $this->parser;
|
||||
}
|
||||
}
|
||||
|
||||
if ($error_string = xml_error_string($xmlecode)) {
|
||||
$error .= ' - '.$error_string;
|
||||
}
|
||||
|
||||
if (is_resource($xp)) {
|
||||
$byte = @xml_get_current_byte_index($xp);
|
||||
$line = @xml_get_current_line_number($xp);
|
||||
$column = @xml_get_current_column_number($xp);
|
||||
$error .= " - Byte: $byte; Line: $line; Col: $column";
|
||||
}
|
||||
|
||||
$error .= "\n";
|
||||
|
||||
$this->error = MDB2_Schema::raiseError($ecode, null, null, $error);
|
||||
}
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered when reading data in a XML element (text between tags)
|
||||
*
|
||||
* @param resource $xp xml parser resource
|
||||
* @param string $data text
|
||||
*
|
||||
* @return void
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
function cdataHandler($xp, $data)
|
||||
{
|
||||
if ($this->var_mode == true) {
|
||||
if (!isset($this->variables[$data])) {
|
||||
$this->raiseError('variable "'.$data.'" not found', null, $xp);
|
||||
return;
|
||||
}
|
||||
$data = $this->variables[$data];
|
||||
}
|
||||
|
||||
switch ($this->element) {
|
||||
/* Initialization */
|
||||
|
||||
/* Insert */
|
||||
case 'database-table-initialization-insert-select-table':
|
||||
$this->init['data']['table'] = $data;
|
||||
break;
|
||||
|
||||
/* Insert and Update */
|
||||
case 'database-table-initialization-insert-field-name':
|
||||
case 'database-table-initialization-insert-select-field-name':
|
||||
case 'database-table-initialization-update-field-name':
|
||||
$this->init_field['name'] .= $data;
|
||||
break;
|
||||
case 'database-table-initialization-insert-field-value':
|
||||
case 'database-table-initialization-insert-select-field-value':
|
||||
case 'database-table-initialization-update-field-value':
|
||||
$this->init_field['group']['data'] .= $data;
|
||||
break;
|
||||
case 'database-table-initialization-insert-field-function-name':
|
||||
case 'database-table-initialization-insert-select-field-function-name':
|
||||
case 'database-table-initialization-update-field-function-name':
|
||||
$this->init_function['name'] .= $data;
|
||||
break;
|
||||
case 'database-table-initialization-insert-field-function-value':
|
||||
case 'database-table-initialization-insert-select-field-function-value':
|
||||
case 'database-table-initialization-update-field-function-value':
|
||||
$this->init_function['arguments'][] = array('type' => 'value', 'data' => $data);
|
||||
break;
|
||||
case 'database-table-initialization-insert-field-function-column':
|
||||
case 'database-table-initialization-insert-select-field-function-column':
|
||||
case 'database-table-initialization-update-field-function-column':
|
||||
$this->init_function['arguments'][] = array('type' => 'column', 'data' => $data);
|
||||
break;
|
||||
case 'database-table-initialization-insert-field-column':
|
||||
case 'database-table-initialization-insert-select-field-column':
|
||||
case 'database-table-initialization-update-field-column':
|
||||
$this->init_field['group'] = array('type' => 'column', 'data' => $data);
|
||||
break;
|
||||
|
||||
/* All */
|
||||
case 'database-table-initialization-insert-field-expression-operator':
|
||||
case 'database-table-initialization-insert-select-field-expression-operator':
|
||||
case 'database-table-initialization-insert-select-where-expression-operator':
|
||||
case 'database-table-initialization-update-field-expression-operator':
|
||||
case 'database-table-initialization-update-where-expression-operator':
|
||||
case 'database-table-initialization-delete-where-expression-operator':
|
||||
$this->init_expression['operator'] = $data;
|
||||
break;
|
||||
case 'database-table-initialization-insert-field-expression-value':
|
||||
case 'database-table-initialization-insert-select-field-expression-value':
|
||||
case 'database-table-initialization-insert-select-where-expression-value':
|
||||
case 'database-table-initialization-update-field-expression-value':
|
||||
case 'database-table-initialization-update-where-expression-value':
|
||||
case 'database-table-initialization-delete-where-expression-value':
|
||||
$this->init_expression['operants'][] = array('type' => 'value', 'data' => $data);
|
||||
break;
|
||||
case 'database-table-initialization-insert-field-expression-column':
|
||||
case 'database-table-initialization-insert-select-field-expression-column':
|
||||
case 'database-table-initialization-insert-select-where-expression-column':
|
||||
case 'database-table-initialization-update-field-expression-column':
|
||||
case 'database-table-initialization-update-where-expression-column':
|
||||
case 'database-table-initialization-delete-where-expression-column':
|
||||
$this->init_expression['operants'][] = array('type' => 'column', 'data' => $data);
|
||||
break;
|
||||
|
||||
case 'database-table-initialization-insert-field-function-function':
|
||||
case 'database-table-initialization-insert-field-function-expression':
|
||||
case 'database-table-initialization-insert-field-expression-expression':
|
||||
case 'database-table-initialization-update-field-function-function':
|
||||
case 'database-table-initialization-update-field-function-expression':
|
||||
case 'database-table-initialization-update-field-expression-expression':
|
||||
case 'database-table-initialization-update-where-expression-expression':
|
||||
case 'database-table-initialization-delete-where-expression-expression':
|
||||
/* Recursion to be implemented yet */
|
||||
break;
|
||||
|
||||
/* One level simulation of expression-function recursion */
|
||||
case 'database-table-initialization-insert-field-expression-function-name':
|
||||
case 'database-table-initialization-insert-select-field-expression-function-name':
|
||||
case 'database-table-initialization-insert-select-where-expression-function-name':
|
||||
case 'database-table-initialization-update-field-expression-function-name':
|
||||
case 'database-table-initialization-update-where-expression-function-name':
|
||||
case 'database-table-initialization-delete-where-expression-function-name':
|
||||
$this->init_function['name'] .= $data;
|
||||
break;
|
||||
case 'database-table-initialization-insert-field-expression-function-value':
|
||||
case 'database-table-initialization-insert-select-field-expression-function-value':
|
||||
case 'database-table-initialization-insert-select-where-expression-function-value':
|
||||
case 'database-table-initialization-update-field-expression-function-value':
|
||||
case 'database-table-initialization-update-where-expression-function-value':
|
||||
case 'database-table-initialization-delete-where-expression-function-value':
|
||||
$this->init_function['arguments'][] = array('type' => 'value', 'data' => $data);
|
||||
break;
|
||||
case 'database-table-initialization-insert-field-expression-function-column':
|
||||
case 'database-table-initialization-insert-select-field-expression-function-column':
|
||||
case 'database-table-initialization-insert-select-where-expression-function-column':
|
||||
case 'database-table-initialization-update-field-expression-function-column':
|
||||
case 'database-table-initialization-update-where-expression-function-column':
|
||||
case 'database-table-initialization-delete-where-expression-function-column':
|
||||
$this->init_function['arguments'][] = array('type' => 'column', 'data' => $data);
|
||||
break;
|
||||
|
||||
/* One level simulation of function-expression recursion */
|
||||
case 'database-table-initialization-insert-field-function-expression-operator':
|
||||
case 'database-table-initialization-insert-select-field-function-expression-operator':
|
||||
case 'database-table-initialization-update-field-function-expression-operator':
|
||||
$this->init_expression['operator'] = $data;
|
||||
break;
|
||||
case 'database-table-initialization-insert-field-function-expression-value':
|
||||
case 'database-table-initialization-insert-select-field-function-expression-value':
|
||||
case 'database-table-initialization-update-field-function-expression-value':
|
||||
$this->init_expression['operants'][] = array('type' => 'value', 'data' => $data);
|
||||
break;
|
||||
case 'database-table-initialization-insert-field-function-expression-column':
|
||||
case 'database-table-initialization-insert-select-field-function-expression-column':
|
||||
case 'database-table-initialization-update-field-function-expression-column':
|
||||
$this->init_expression['operants'][] = array('type' => 'column', 'data' => $data);
|
||||
break;
|
||||
|
||||
/* Database */
|
||||
case 'database-name':
|
||||
$this->database_definition['name'] .= $data;
|
||||
break;
|
||||
case 'database-create':
|
||||
$this->database_definition['create'] .= $data;
|
||||
break;
|
||||
case 'database-overwrite':
|
||||
$this->database_definition['overwrite'] .= $data;
|
||||
break;
|
||||
case 'database-charset':
|
||||
$this->database_definition['charset'] .= $data;
|
||||
break;
|
||||
case 'database-description':
|
||||
$this->database_definition['description'] .= $data;
|
||||
break;
|
||||
case 'database-comments':
|
||||
$this->database_definition['comments'] .= $data;
|
||||
break;
|
||||
|
||||
/* Table declaration */
|
||||
case 'database-table-name':
|
||||
$this->table_name .= $data;
|
||||
break;
|
||||
case 'database-table-was':
|
||||
$this->table['was'] .= $data;
|
||||
break;
|
||||
case 'database-table-description':
|
||||
$this->table['description'] .= $data;
|
||||
break;
|
||||
case 'database-table-comments':
|
||||
$this->table['comments'] .= $data;
|
||||
break;
|
||||
|
||||
/* Field declaration */
|
||||
case 'database-table-declaration-field-name':
|
||||
$this->field_name .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-field-was':
|
||||
$this->field['was'] .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-field-type':
|
||||
$this->field['type'] .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-field-fixed':
|
||||
$this->field['fixed'] .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-field-default':
|
||||
$this->field['default'] .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-field-notnull':
|
||||
$this->field['notnull'] .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-field-autoincrement':
|
||||
$this->field['autoincrement'] .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-field-unsigned':
|
||||
$this->field['unsigned'] .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-field-length':
|
||||
$this->field['length'] .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-field-description':
|
||||
$this->field['description'] .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-field-comments':
|
||||
$this->field['comments'] .= $data;
|
||||
break;
|
||||
|
||||
/* Index declaration */
|
||||
case 'database-table-declaration-index-name':
|
||||
$this->index_name .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-index-was':
|
||||
$this->index['was'] .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-index-unique':
|
||||
$this->index['unique'] .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-index-primary':
|
||||
$this->index['primary'] .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-index-field-name':
|
||||
$this->field_name .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-index-field-sorting':
|
||||
$this->field['sorting'] .= $data;
|
||||
break;
|
||||
/* Add by Leoncx */
|
||||
case 'database-table-declaration-index-field-length':
|
||||
$this->field['length'] .= $data;
|
||||
break;
|
||||
|
||||
/* Foreign Key declaration */
|
||||
case 'database-table-declaration-foreign-name':
|
||||
$this->constraint_name .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-foreign-was':
|
||||
$this->constraint['was'] .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-foreign-match':
|
||||
$this->constraint['match'] .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-foreign-ondelete':
|
||||
$this->constraint['ondelete'] .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-foreign-onupdate':
|
||||
$this->constraint['onupdate'] .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-foreign-deferrable':
|
||||
$this->constraint['deferrable'] .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-foreign-initiallydeferred':
|
||||
$this->constraint['initiallydeferred'] .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-foreign-field':
|
||||
$this->field_name .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-foreign-references-table':
|
||||
$this->constraint['references']['table'] .= $data;
|
||||
break;
|
||||
case 'database-table-declaration-foreign-references-field':
|
||||
$this->field_name .= $data;
|
||||
break;
|
||||
|
||||
/* Sequence declaration */
|
||||
case 'database-sequence-name':
|
||||
$this->sequence_name .= $data;
|
||||
break;
|
||||
case 'database-sequence-was':
|
||||
$this->sequence['was'] .= $data;
|
||||
break;
|
||||
case 'database-sequence-start':
|
||||
$this->sequence['start'] .= $data;
|
||||
break;
|
||||
case 'database-sequence-description':
|
||||
$this->sequence['description'] .= $data;
|
||||
break;
|
||||
case 'database-sequence-comments':
|
||||
$this->sequence['comments'] .= $data;
|
||||
break;
|
||||
case 'database-sequence-on':
|
||||
$this->sequence['on'] = array('table' => '', 'field' => '');
|
||||
break;
|
||||
case 'database-sequence-on-table':
|
||||
$this->sequence['on']['table'] .= $data;
|
||||
break;
|
||||
case 'database-sequence-on-field':
|
||||
$this->sequence['on']['field'] .= $data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+829
@@ -0,0 +1,829 @@
|
||||
<?php /* vim: se et ts=4 sw=4 sts=4 fdm=marker tw=80: */
|
||||
/**
|
||||
* Copyright (c) 1998-2010 Manuel Lemos, Tomas V.V.Cox,
|
||||
* Stig. S. Bakken, Lukas Smith, Igor Feghali
|
||||
* All rights reserved.
|
||||
*
|
||||
* MDB2_Schema enables users to maintain RDBMS independant schema files
|
||||
* in XML that can be used to manipulate both data and database schemas
|
||||
* This LICENSE is in the BSD license style.
|
||||
*
|
||||
* 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,
|
||||
* Lukas Smith, Igor Feghali nor the names of his 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
|
||||
* REGENTS 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.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Database
|
||||
* @package MDB2_Schema
|
||||
* @author Igor Feghali <ifeghali@php.net>
|
||||
* @license BSD http://www.opensource.org/licenses/bsd-license.php
|
||||
* @version SVN: $Id$
|
||||
* @link http://pear.php.net/packages/MDB2_Schema
|
||||
*/
|
||||
|
||||
require_once 'XML/Unserializer.php';
|
||||
require_once 'MDB2/Schema/Validate.php';
|
||||
|
||||
/**
|
||||
* Parses an XML schema file
|
||||
*
|
||||
* @category Database
|
||||
* @package MDB2_Schema
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
* @author Igor Feghali <ifeghali@php.net>
|
||||
* @license BSD http://www.opensource.org/licenses/bsd-license.php
|
||||
* @link http://pear.php.net/packages/MDB2_Schema
|
||||
*/
|
||||
class MDB2_Schema_Parser2 extends XML_Unserializer
|
||||
{
|
||||
var $database_definition = array();
|
||||
|
||||
var $database_loaded = array();
|
||||
|
||||
var $variables = array();
|
||||
|
||||
var $error;
|
||||
|
||||
var $structure = false;
|
||||
|
||||
var $val;
|
||||
|
||||
var $options = array();
|
||||
|
||||
var $table = array();
|
||||
|
||||
var $table_name = '';
|
||||
|
||||
var $field = array();
|
||||
|
||||
var $field_name = '';
|
||||
|
||||
var $index = array();
|
||||
|
||||
var $index_name = '';
|
||||
|
||||
var $constraint = array();
|
||||
|
||||
var $constraint_name = '';
|
||||
|
||||
var $sequence = array();
|
||||
|
||||
var $sequence_name = '';
|
||||
|
||||
var $init = array();
|
||||
|
||||
/**
|
||||
* PHP 5 constructor
|
||||
*
|
||||
* @param array $variables mixed array with user defined schema
|
||||
* variables
|
||||
* @param bool $fail_on_invalid_names array with reserved words per RDBMS
|
||||
* @param array $structure multi dimensional array with
|
||||
* database schema and data
|
||||
* @param array $valid_types information of all valid fields
|
||||
* types
|
||||
* @param bool $force_defaults if true sets a default value to
|
||||
* field when not explicit
|
||||
* @param int $max_identifiers_length maximum allowed size for entities
|
||||
* name
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function __construct($variables, $fail_on_invalid_names = true,
|
||||
$structure = false, $valid_types = array(), $force_defaults = true,
|
||||
$max_identifiers_length = null
|
||||
) {
|
||||
// force ISO-8859-1 due to different defaults for PHP4 and PHP5
|
||||
// todo: this probably needs to be investigated some more and cleaned up
|
||||
$this->options['encoding'] = 'ISO-8859-1';
|
||||
|
||||
$this->options['XML_UNSERIALIZER_OPTION_ATTRIBUTES_PARSE'] = true;
|
||||
$this->options['XML_UNSERIALIZER_OPTION_ATTRIBUTES_ARRAYKEY'] = false;
|
||||
|
||||
$this->options['forceEnum'] = array('table', 'field', 'index', 'foreign', 'insert', 'update', 'delete', 'sequence');
|
||||
|
||||
/*
|
||||
* todo: find a way to force the following items not to be parsed as arrays
|
||||
* as it cause problems in functions with multiple arguments
|
||||
*/
|
||||
//$this->options['forceNEnum'] = array('value', 'column');
|
||||
$this->variables = $variables;
|
||||
$this->structure = $structure;
|
||||
|
||||
$this->val = new MDB2_Schema_Validate($fail_on_invalid_names, $valid_types, $force_defaults);
|
||||
parent::XML_Unserializer($this->options);
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP 4 compatible constructor
|
||||
*
|
||||
* @param array $variables mixed array with user defined schema
|
||||
* variables
|
||||
* @param bool $fail_on_invalid_names array with reserved words per RDBMS
|
||||
* @param array $structure multi dimensional array with
|
||||
* database schema and data
|
||||
* @param array $valid_types information of all valid fields
|
||||
* types
|
||||
* @param bool $force_defaults if true sets a default value to
|
||||
* field when not explicit
|
||||
* @param int $max_identifiers_length maximum allowed size for entities
|
||||
* name
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function MDB2_Schema_Parser2($variables, $fail_on_invalid_names = true,
|
||||
$structure = false, $valid_types = array(), $force_defaults = true,
|
||||
$max_identifiers_length = null
|
||||
) {
|
||||
$this->__construct($variables, $fail_on_invalid_names, $structure, $valid_types, $force_defaults);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main method. Parses XML Schema File.
|
||||
*
|
||||
* @return bool|error object
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function parse()
|
||||
{
|
||||
$result = $this->unserialize($this->filename, true);
|
||||
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
} else {
|
||||
$this->database_loaded = $this->getUnserializedData();
|
||||
return $this->fixDatabaseKeys($this->database_loaded);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the necessary stuff to set the input XML schema file
|
||||
*
|
||||
* @param string $filename full path to schema file
|
||||
*
|
||||
* @return boolean MDB2_OK on success
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function setInputFile($filename)
|
||||
{
|
||||
$this->filename = $filename;
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforce the default values for mandatory keys and ensure everything goes
|
||||
* always in the same order (simulates the behaviour of the original
|
||||
* parser). Works at database level.
|
||||
*
|
||||
* @param array $database multi dimensional array with database definition
|
||||
* and data.
|
||||
*
|
||||
* @return bool|error MDB2_OK on success or error object
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function fixDatabaseKeys($database)
|
||||
{
|
||||
$this->database_definition = array(
|
||||
'name' => '',
|
||||
'create' => '',
|
||||
'overwrite' => '',
|
||||
'charset' => '',
|
||||
'description' => '',
|
||||
'comments' => '',
|
||||
'tables' => array(),
|
||||
'sequences' => array()
|
||||
);
|
||||
|
||||
if (!empty($database['name'])) {
|
||||
$this->database_definition['name'] = $database['name'];
|
||||
}
|
||||
if (!empty($database['create'])) {
|
||||
$this->database_definition['create'] = $database['create'];
|
||||
}
|
||||
if (!empty($database['overwrite'])) {
|
||||
$this->database_definition['overwrite'] = $database['overwrite'];
|
||||
}
|
||||
if (!empty($database['charset'])) {
|
||||
$this->database_definition['charset'] = $database['charset'];
|
||||
}
|
||||
if (!empty($database['description'])) {
|
||||
$this->database_definition['description'] = $database['description'];
|
||||
}
|
||||
if (!empty($database['comments'])) {
|
||||
$this->database_definition['comments'] = $database['comments'];
|
||||
}
|
||||
|
||||
if (!empty($database['table']) && is_array($database['table'])) {
|
||||
foreach ($database['table'] as $table) {
|
||||
$this->fixTableKeys($table);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($database['sequence']) && is_array($database['sequence'])) {
|
||||
foreach ($database['sequence'] as $sequence) {
|
||||
$this->fixSequenceKeys($sequence);
|
||||
}
|
||||
}
|
||||
|
||||
$result = $this->val->validateDatabase($this->database_definition);
|
||||
if (PEAR::isError($result)) {
|
||||
return $this->raiseError($result->getUserinfo());
|
||||
}
|
||||
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforce the default values for mandatory keys and ensure everything goes
|
||||
* always in the same order (simulates the behaviour of the original
|
||||
* parser). Works at table level.
|
||||
*
|
||||
* @param array $table multi dimensional array with table definition
|
||||
* and data.
|
||||
*
|
||||
* @return bool|error MDB2_OK on success or error object
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function fixTableKeys($table)
|
||||
{
|
||||
$this->table = array(
|
||||
'was' => '',
|
||||
'description' => '',
|
||||
'comments' => '',
|
||||
'fields' => array(),
|
||||
'indexes' => array(),
|
||||
'constraints' => array(),
|
||||
'initialization' => array()
|
||||
);
|
||||
|
||||
if (!empty($table['name'])) {
|
||||
$this->table_name = $table['name'];
|
||||
} else {
|
||||
$this->table_name = '';
|
||||
}
|
||||
if (!empty($table['was'])) {
|
||||
$this->table['was'] = $table['was'];
|
||||
}
|
||||
if (!empty($table['description'])) {
|
||||
$this->table['description'] = $table['description'];
|
||||
}
|
||||
if (!empty($table['comments'])) {
|
||||
$this->table['comments'] = $table['comments'];
|
||||
}
|
||||
|
||||
if (!empty($table['declaration']) && is_array($table['declaration'])) {
|
||||
if (!empty($table['declaration']['field']) && is_array($table['declaration']['field'])) {
|
||||
foreach ($table['declaration']['field'] as $field) {
|
||||
$this->fixTableFieldKeys($field);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($table['declaration']['index']) && is_array($table['declaration']['index'])) {
|
||||
foreach ($table['declaration']['index'] as $index) {
|
||||
$this->fixTableIndexKeys($index);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($table['declaration']['foreign']) && is_array($table['declaration']['foreign'])) {
|
||||
foreach ($table['declaration']['foreign'] as $constraint) {
|
||||
$this->fixTableConstraintKeys($constraint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($table['initialization']) && is_array($table['initialization'])) {
|
||||
if (!empty($table['initialization']['insert']) && is_array($table['initialization']['insert'])) {
|
||||
foreach ($table['initialization']['insert'] as $init) {
|
||||
$this->fixTableInitializationKeys($init, 'insert');
|
||||
}
|
||||
}
|
||||
if (!empty($table['initialization']['update']) && is_array($table['initialization']['update'])) {
|
||||
foreach ($table['initialization']['update'] as $init) {
|
||||
$this->fixTableInitializationKeys($init, 'update');
|
||||
}
|
||||
}
|
||||
if (!empty($table['initialization']['delete']) && is_array($table['initialization']['delete'])) {
|
||||
foreach ($table['initialization']['delete'] as $init) {
|
||||
$this->fixTableInitializationKeys($init, 'delete');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result = $this->val->validateTable($this->database_definition['tables'], $this->table, $this->table_name);
|
||||
if (PEAR::isError($result)) {
|
||||
return $this->raiseError($result->getUserinfo());
|
||||
} else {
|
||||
$this->database_definition['tables'][$this->table_name] = $this->table;
|
||||
}
|
||||
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforce the default values for mandatory keys and ensure everything goes
|
||||
* always in the same order (simulates the behaviour of the original
|
||||
* parser). Works at table field level.
|
||||
*
|
||||
* @param array $field array with table field definition
|
||||
*
|
||||
* @return bool|error MDB2_OK on success or error object
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function fixTableFieldKeys($field)
|
||||
{
|
||||
$this->field = array();
|
||||
if (!empty($field['name'])) {
|
||||
$this->field_name = $field['name'];
|
||||
} else {
|
||||
$this->field_name = '';
|
||||
}
|
||||
if (!empty($field['was'])) {
|
||||
$this->field['was'] = $field['was'];
|
||||
}
|
||||
if (!empty($field['type'])) {
|
||||
$this->field['type'] = $field['type'];
|
||||
}
|
||||
if (!empty($field['fixed'])) {
|
||||
$this->field['fixed'] = $field['fixed'];
|
||||
}
|
||||
if (isset($field['default'])) {
|
||||
$this->field['default'] = $field['default'];
|
||||
}
|
||||
if (!empty($field['notnull'])) {
|
||||
$this->field['notnull'] = $field['notnull'];
|
||||
}
|
||||
if (!empty($field['autoincrement'])) {
|
||||
$this->field['autoincrement'] = $field['autoincrement'];
|
||||
}
|
||||
if (!empty($field['unsigned'])) {
|
||||
$this->field['unsigned'] = $field['unsigned'];
|
||||
}
|
||||
if (!empty($field['length'])) {
|
||||
$this->field['length'] = $field['length'];
|
||||
}
|
||||
if (!empty($field['description'])) {
|
||||
$this->field['description'] = $field['description'];
|
||||
}
|
||||
if (!empty($field['comments'])) {
|
||||
$this->field['comments'] = $field['comments'];
|
||||
}
|
||||
|
||||
$result = $this->val->validateField($this->table['fields'], $this->field, $this->field_name);
|
||||
if (PEAR::isError($result)) {
|
||||
return $this->raiseError($result->getUserinfo());
|
||||
} else {
|
||||
$this->table['fields'][$this->field_name] = $this->field;
|
||||
}
|
||||
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforce the default values for mandatory keys and ensure everything goes
|
||||
* always in the same order (simulates the behaviour of the original
|
||||
* parser). Works at table index level.
|
||||
*
|
||||
* @param array $index array with table index definition
|
||||
*
|
||||
* @return bool|error MDB2_OK on success or error object
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function fixTableIndexKeys($index)
|
||||
{
|
||||
$this->index = array(
|
||||
'was' => '',
|
||||
'unique' =>'',
|
||||
'primary' => '',
|
||||
'fields' => array()
|
||||
);
|
||||
|
||||
if (!empty($index['name'])) {
|
||||
$this->index_name = $index['name'];
|
||||
} else {
|
||||
$this->index_name = '';
|
||||
}
|
||||
if (!empty($index['was'])) {
|
||||
$this->index['was'] = $index['was'];
|
||||
}
|
||||
if (!empty($index['unique'])) {
|
||||
$this->index['unique'] = $index['unique'];
|
||||
}
|
||||
if (!empty($index['primary'])) {
|
||||
$this->index['primary'] = $index['primary'];
|
||||
}
|
||||
if (!empty($index['field'])) {
|
||||
foreach ($index['field'] as $field) {
|
||||
if (!empty($field['name'])) {
|
||||
$this->field_name = $field['name'];
|
||||
} else {
|
||||
$this->field_name = '';
|
||||
}
|
||||
$this->field = array(
|
||||
'sorting' => '',
|
||||
'length' => ''
|
||||
);
|
||||
|
||||
if (!empty($field['sorting'])) {
|
||||
$this->field['sorting'] = $field['sorting'];
|
||||
}
|
||||
if (!empty($field['length'])) {
|
||||
$this->field['length'] = $field['length'];
|
||||
}
|
||||
|
||||
$result = $this->val->validateIndexField($this->index['fields'], $this->field, $this->field_name);
|
||||
if (PEAR::isError($result)) {
|
||||
return $this->raiseError($result->getUserinfo());
|
||||
}
|
||||
|
||||
$this->index['fields'][$this->field_name] = $this->field;
|
||||
}
|
||||
}
|
||||
|
||||
$result = $this->val->validateIndex($this->table['indexes'], $this->index, $this->index_name);
|
||||
if (PEAR::isError($result)) {
|
||||
return $this->raiseError($result->getUserinfo());
|
||||
} else {
|
||||
$this->table['indexes'][$this->index_name] = $this->index;
|
||||
}
|
||||
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforce the default values for mandatory keys and ensure everything goes
|
||||
* always in the same order (simulates the behaviour of the original
|
||||
* parser). Works at table constraint level.
|
||||
*
|
||||
* @param array $constraint array with table index definition
|
||||
*
|
||||
* @return bool|error MDB2_OK on success or error object
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function fixTableConstraintKeys($constraint)
|
||||
{
|
||||
$this->constraint = array(
|
||||
'was' => '',
|
||||
'match' => '',
|
||||
'ondelete' => '',
|
||||
'onupdate' => '',
|
||||
'deferrable' => '',
|
||||
'initiallydeferred' => '',
|
||||
'foreign' => true,
|
||||
'fields' => array(),
|
||||
'references' => array('table' => '', 'fields' => array())
|
||||
);
|
||||
|
||||
if (!empty($constraint['name'])) {
|
||||
$this->constraint_name = $constraint['name'];
|
||||
} else {
|
||||
$this->constraint_name = '';
|
||||
}
|
||||
if (!empty($constraint['was'])) {
|
||||
$this->constraint['was'] = $constraint['was'];
|
||||
}
|
||||
if (!empty($constraint['match'])) {
|
||||
$this->constraint['match'] = $constraint['match'];
|
||||
}
|
||||
if (!empty($constraint['ondelete'])) {
|
||||
$this->constraint['ondelete'] = $constraint['ondelete'];
|
||||
}
|
||||
if (!empty($constraint['onupdate'])) {
|
||||
$this->constraint['onupdate'] = $constraint['onupdate'];
|
||||
}
|
||||
if (!empty($constraint['deferrable'])) {
|
||||
$this->constraint['deferrable'] = $constraint['deferrable'];
|
||||
}
|
||||
if (!empty($constraint['initiallydeferred'])) {
|
||||
$this->constraint['initiallydeferred'] = $constraint['initiallydeferred'];
|
||||
}
|
||||
if (!empty($constraint['field']) && is_array($constraint['field'])) {
|
||||
foreach ($constraint['field'] as $field) {
|
||||
$result = $this->val->validateConstraintField($this->constraint['fields'], $field);
|
||||
if (PEAR::isError($result)) {
|
||||
return $this->raiseError($result->getUserinfo());
|
||||
}
|
||||
|
||||
$this->constraint['fields'][$field] = '';
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($constraint['references']) && is_array($constraint['references'])) {
|
||||
/**
|
||||
* As we forced 'table' to be enumerated
|
||||
* we have to fix it on the foreign-references-table context
|
||||
*/
|
||||
if (!empty($constraint['references']['table']) && is_array($constraint['references']['table'])) {
|
||||
$this->constraint['references']['table'] = $constraint['references']['table'][0];
|
||||
}
|
||||
|
||||
if (!empty($constraint['references']['field']) && is_array($constraint['references']['field'])) {
|
||||
foreach ($constraint['references']['field'] as $field) {
|
||||
$result = $this->val->validateConstraintReferencedField($this->constraint['references']['fields'], $field);
|
||||
if (PEAR::isError($result)) {
|
||||
return $this->raiseError($result->getUserinfo());
|
||||
}
|
||||
|
||||
$this->constraint['references']['fields'][$field] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result = $this->val->validateConstraint($this->table['constraints'], $this->constraint, $this->constraint_name);
|
||||
if (PEAR::isError($result)) {
|
||||
return $this->raiseError($result->getUserinfo());
|
||||
} else {
|
||||
$this->table['constraints'][$this->constraint_name] = $this->constraint;
|
||||
}
|
||||
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforce the default values for mandatory keys and ensure everything goes
|
||||
* always in the same order (simulates the behaviour of the original
|
||||
* parser). Works at table data level.
|
||||
*
|
||||
* @param array $element multi dimensional array with query definition
|
||||
* @param string $type whether its a insert|update|delete query
|
||||
*
|
||||
* @return bool|error MDB2_OK on success or error object
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function fixTableInitializationKeys($element, $type = '')
|
||||
{
|
||||
if (!empty($element['select']) && is_array($element['select'])) {
|
||||
$this->fixTableInitializationDataKeys($element['select']);
|
||||
$this->init = array( 'select' => $this->init );
|
||||
} else {
|
||||
$this->fixTableInitializationDataKeys($element);
|
||||
}
|
||||
|
||||
$this->table['initialization'][] = array( 'type' => $type, 'data' => $this->init );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforce the default values for mandatory keys and ensure everything goes
|
||||
* always in the same order (simulates the behaviour of the original
|
||||
* parser). Works deeper at the table initialization level (data). At this
|
||||
* point we are look at one of the below:
|
||||
*
|
||||
* <insert>
|
||||
* {field}+
|
||||
* </insert>
|
||||
*
|
||||
* <select> (this is a select extracted off a insert-select query)
|
||||
* <table/>
|
||||
* {field}+
|
||||
* <where>
|
||||
* {expression}
|
||||
* </where>?
|
||||
* </select>
|
||||
*
|
||||
* <update>
|
||||
* {field}+
|
||||
* <where>
|
||||
* {expression}
|
||||
* </where>?
|
||||
* </update>
|
||||
*
|
||||
* <delete>
|
||||
* <where>
|
||||
* {expression}
|
||||
* </where>
|
||||
* </delete>
|
||||
*
|
||||
* @param array $element multi dimensional array with query definition
|
||||
*
|
||||
* @return bool|error MDB2_OK on success or error object
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function fixTableInitializationDataKeys($element)
|
||||
{
|
||||
$this->init = array();
|
||||
if (!empty($element['field']) && is_array($element['field'])) {
|
||||
foreach ($element['field'] as $field) {
|
||||
$name = $field['name'];
|
||||
unset($field['name']);
|
||||
|
||||
$this->setExpression($field);
|
||||
$this->init['field'][] = array( 'name' => $name, 'group' => $field );
|
||||
}
|
||||
}
|
||||
/**
|
||||
* As we forced 'table' to be enumerated
|
||||
* we have to fix it on the insert-select context
|
||||
*/
|
||||
if (!empty($element['table']) && is_array($element['table'])) {
|
||||
$this->init['table'] = $element['table'][0];
|
||||
}
|
||||
if (!empty($element['where']) && is_array($element['where'])) {
|
||||
$this->init['where'] = $element['where'];
|
||||
$this->setExpression($this->init['where']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively diggs into an "expression" element. According to our
|
||||
* documentation an "expression" element is of the kind:
|
||||
*
|
||||
* <expression>
|
||||
* <null/> or <value/> or <column/> or {function} or {expression}
|
||||
* <operator/>
|
||||
* <null/> or <value/> or <column/> or {function} or {expression}
|
||||
* </expression>
|
||||
*
|
||||
* @param array &$arr reference to current element definition
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function setExpression(&$arr)
|
||||
{
|
||||
$element = each($arr);
|
||||
|
||||
$arr = array( 'type' => $element['key'] );
|
||||
|
||||
$element = $element['value'];
|
||||
|
||||
switch ($arr['type']) {
|
||||
case 'null':
|
||||
break;
|
||||
case 'value':
|
||||
case 'column':
|
||||
$arr['data'] = $element;
|
||||
break;
|
||||
case 'function':
|
||||
if (!empty($element)
|
||||
&& is_array($element)
|
||||
) {
|
||||
$arr['data'] = array( 'name' => $element['name'] );
|
||||
unset($element['name']);
|
||||
|
||||
foreach ($element as $type => $value) {
|
||||
if (!empty($value)) {
|
||||
if (is_array($value)) {
|
||||
foreach ($value as $argument) {
|
||||
$argument = array( $type => $argument );
|
||||
$this->setExpression($argument);
|
||||
$arr['data']['arguments'][] = $argument;
|
||||
}
|
||||
} else {
|
||||
$arr['data']['arguments'][] = array( 'type' => $type, 'data' => $value );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'expression':
|
||||
$arr['data'] = array( 'operants' => array(), 'operator' => $element['operator'] );
|
||||
unset($element['operator']);
|
||||
|
||||
foreach ($element as $k => $v) {
|
||||
$argument = array( $k => $v );
|
||||
$this->setExpression($argument);
|
||||
$arr['data']['operants'][] = $argument;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforce the default values for mandatory keys and ensure everything goes
|
||||
* always in the same order (simulates the behaviour of the original
|
||||
* parser). Works at database sequences level. A "sequence" element looks
|
||||
* like:
|
||||
*
|
||||
* <sequence>
|
||||
* <name/>
|
||||
* <was/>?
|
||||
* <start/>?
|
||||
* <description/>?
|
||||
* <comments/>?
|
||||
* <on>
|
||||
* <table/>
|
||||
* <field/>
|
||||
* </on>?
|
||||
* </sequence>
|
||||
*
|
||||
* @param array $sequence multi dimensional array with sequence definition
|
||||
*
|
||||
* @return bool|error MDB2_OK on success or error object
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function fixSequenceKeys($sequence)
|
||||
{
|
||||
$this->sequence = array(
|
||||
'was' => '',
|
||||
'start' => '',
|
||||
'description' => '',
|
||||
'comments' => '',
|
||||
);
|
||||
|
||||
if (!empty($sequence['name'])) {
|
||||
$this->sequence_name = $sequence['name'];
|
||||
} else {
|
||||
$this->sequence_name = '';
|
||||
}
|
||||
if (!empty($sequence['was'])) {
|
||||
$this->sequence['was'] = $sequence['was'];
|
||||
}
|
||||
if (!empty($sequence['start'])) {
|
||||
$this->sequence['start'] = $sequence['start'];
|
||||
}
|
||||
if (!empty($sequence['description'])) {
|
||||
$this->sequence['description'] = $sequence['description'];
|
||||
}
|
||||
if (!empty($sequence['comments'])) {
|
||||
$this->sequence['comments'] = $sequence['comments'];
|
||||
}
|
||||
if (!empty($sequence['on']) && is_array($sequence['on'])) {
|
||||
/**
|
||||
* As we forced 'table' to be enumerated
|
||||
* we have to fix it on the sequence-on-table context
|
||||
*/
|
||||
if (!empty($sequence['on']['table']) && is_array($sequence['on']['table'])) {
|
||||
$this->sequence['on']['table'] = $sequence['on']['table'][0];
|
||||
}
|
||||
|
||||
/**
|
||||
* As we forced 'field' to be enumerated
|
||||
* we have to fix it on the sequence-on-field context
|
||||
*/
|
||||
if (!empty($sequence['on']['field']) && is_array($sequence['on']['field'])) {
|
||||
$this->sequence['on']['field'] = $sequence['on']['field'][0];
|
||||
}
|
||||
}
|
||||
|
||||
$result = $this->val->validateSequence($this->database_definition['sequences'], $this->sequence, $this->sequence_name);
|
||||
if (PEAR::isError($result)) {
|
||||
return $this->raiseError($result->getUserinfo());
|
||||
} else {
|
||||
$this->database_definition['sequences'][$this->sequence_name] = $this->sequence;
|
||||
}
|
||||
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes a MDB2_Schema_Error into stack and returns it
|
||||
*
|
||||
* @param string $msg textual message
|
||||
* @param int $ecode MDB2_Schema's error code
|
||||
*
|
||||
* @return object
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
function &raiseError($msg = null, $ecode = MDB2_SCHEMA_ERROR_PARSE)
|
||||
{
|
||||
if (is_null($this->error)) {
|
||||
$error = 'Parser error: '.$msg."\n";
|
||||
|
||||
$this->error = MDB2_Schema::raiseError($ecode, null, null, $error);
|
||||
}
|
||||
return $this->error;
|
||||
}
|
||||
}
|
||||
+437
@@ -0,0 +1,437 @@
|
||||
<?php /* vim: se et ts=4 sw=4 sts=4 fdm=marker tw=80: */
|
||||
/**
|
||||
* Copyright (c) 1998-2010 Manuel Lemos, Tomas V.V.Cox,
|
||||
* Stig. S. Bakken, Lukas Smith, Igor Feghali
|
||||
* All rights reserved.
|
||||
*
|
||||
* MDB2_Schema enables users to maintain RDBMS independant schema files
|
||||
* in XML that can be used to manipulate both data and database schemas
|
||||
* This LICENSE is in the BSD license style.
|
||||
*
|
||||
* 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,
|
||||
* Lukas Smith, Igor Feghali nor the names of his 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
|
||||
* REGENTS 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.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Database
|
||||
* @package MDB2_Schema
|
||||
* @author Lorenzo Alberton <l.alberton@quipo.it>
|
||||
* @license BSD http://www.opensource.org/licenses/bsd-license.php
|
||||
* @version SVN: $Id$
|
||||
* @link http://pear.php.net/packages/MDB2_Schema
|
||||
*/
|
||||
// {{{ $GLOBALS['_MDB2_Schema_Reserved']['ibase']
|
||||
/**
|
||||
* Has a list of reserved words of Interbase/Firebird
|
||||
*
|
||||
* @package MDB2_Schema
|
||||
* @category Database
|
||||
* @access protected
|
||||
* @author Lorenzo Alberton <l.alberton@quipo.it>
|
||||
*/
|
||||
$GLOBALS['_MDB2_Schema_Reserved']['ibase'] = array(
|
||||
'ABS',
|
||||
'ABSOLUTE',
|
||||
'ACTION',
|
||||
'ACTIVE',
|
||||
'ADD',
|
||||
'ADMIN',
|
||||
'AFTER',
|
||||
'ALL',
|
||||
'ALLOCATE',
|
||||
'ALTER',
|
||||
'AND',
|
||||
'ANY',
|
||||
'ARE',
|
||||
'AS',
|
||||
'ASC',
|
||||
'ASCENDING',
|
||||
'ASSERTION',
|
||||
'AT',
|
||||
'AUTHORIZATION',
|
||||
'AUTO',
|
||||
'AUTODDL',
|
||||
'AVG',
|
||||
'BACKUP',
|
||||
'BASE_NAME',
|
||||
'BASED',
|
||||
'BASENAME',
|
||||
'BEFORE',
|
||||
'BEGIN',
|
||||
'BETWEEN',
|
||||
'BIGINT',
|
||||
'BIT',
|
||||
'BIT_LENGTH',
|
||||
'BLOB',
|
||||
'BLOCK',
|
||||
'BLOBEDIT',
|
||||
'BOOLEAN',
|
||||
'BOTH',
|
||||
'BOTH',
|
||||
'BREAK',
|
||||
'BUFFER',
|
||||
'BY',
|
||||
'CACHE',
|
||||
'CASCADE',
|
||||
'CASCADED',
|
||||
'CASE',
|
||||
'CASE',
|
||||
'CAST',
|
||||
'CATALOG',
|
||||
'CHAR',
|
||||
'CHAR_LENGTH',
|
||||
'CHARACTER',
|
||||
'CHARACTER_LENGTH',
|
||||
'CHECK',
|
||||
'CHECK_POINT_LEN',
|
||||
'CHECK_POINT_LENGTH',
|
||||
'CLOSE',
|
||||
'COALESCE',
|
||||
'COLLATE',
|
||||
'COLLATION',
|
||||
'COLUMN',
|
||||
'COMMENT',
|
||||
'COMMIT',
|
||||
'COMMITTED',
|
||||
'COMPILETIME',
|
||||
'COMPUTED',
|
||||
'CONDITIONAL',
|
||||
'CONNECT',
|
||||
'CONNECTION',
|
||||
'CONSTRAINT',
|
||||
'CONSTRAINTS',
|
||||
'CONTAINING',
|
||||
'CONTINUE',
|
||||
'CONVERT',
|
||||
'CORRESPONDING',
|
||||
'COUNT',
|
||||
'CREATE',
|
||||
'CROSS',
|
||||
'CSTRING',
|
||||
'CURRENT',
|
||||
'CURRENT_CONNECTION',
|
||||
'CURRENT_DATE',
|
||||
'CURRENT_ROLE',
|
||||
'CURRENT_TIME',
|
||||
'CURRENT_TIMESTAMP',
|
||||
'CURRENT_TRANSACTION',
|
||||
'CURRENT_USER',
|
||||
'DATABASE',
|
||||
'DATE',
|
||||
'DAY',
|
||||
'DB_KEY',
|
||||
'DEALLOCATE',
|
||||
'DEBUG',
|
||||
'DEC',
|
||||
'DECIMAL',
|
||||
'DECLARE',
|
||||
'DEFAULT',
|
||||
'DEFERRABLE',
|
||||
'DEFERRED',
|
||||
'DELETE',
|
||||
'DELETING',
|
||||
'DESC',
|
||||
'DESCENDING',
|
||||
'DESCRIBE',
|
||||
'DESCRIPTOR',
|
||||
'DIAGNOSTICS',
|
||||
'DIFFERENCE',
|
||||
'DISCONNECT',
|
||||
'DISPLAY',
|
||||
'DISTINCT',
|
||||
'DO',
|
||||
'DOMAIN',
|
||||
'DOUBLE',
|
||||
'DROP',
|
||||
'ECHO',
|
||||
'EDIT',
|
||||
'ELSE',
|
||||
'END',
|
||||
'END-EXEC',
|
||||
'ENTRY_POINT',
|
||||
'ESCAPE',
|
||||
'EVENT',
|
||||
'EXCEPT',
|
||||
'EXCEPTION',
|
||||
'EXEC',
|
||||
'EXECUTE',
|
||||
'EXISTS',
|
||||
'EXIT',
|
||||
'EXTERN',
|
||||
'EXTERNAL',
|
||||
'EXTRACT',
|
||||
'FALSE',
|
||||
'FETCH',
|
||||
'FILE',
|
||||
'FILTER',
|
||||
'FIRST',
|
||||
'FLOAT',
|
||||
'FOR',
|
||||
'FOREIGN',
|
||||
'FOUND',
|
||||
'FREE_IT',
|
||||
'FROM',
|
||||
'FULL',
|
||||
'FUNCTION',
|
||||
'GDSCODE',
|
||||
'GEN_ID',
|
||||
'GENERATOR',
|
||||
'GET',
|
||||
'GLOBAL',
|
||||
'GO',
|
||||
'GOTO',
|
||||
'GRANT',
|
||||
'GROUP',
|
||||
'GROUP_COMMIT_WAIT',
|
||||
'GROUP_COMMIT_WAIT_TIME',
|
||||
'HAVING',
|
||||
'HELP',
|
||||
'HOUR',
|
||||
'IDENTITY',
|
||||
'IF',
|
||||
'IIF',
|
||||
'IMMEDIATE',
|
||||
'IN',
|
||||
'INACTIVE',
|
||||
'INDEX',
|
||||
'INDICATOR',
|
||||
'INIT',
|
||||
'INITIALLY',
|
||||
'INNER',
|
||||
'INPUT',
|
||||
'INPUT_TYPE',
|
||||
'INSENSITIVE',
|
||||
'INSERT',
|
||||
'INSERTING',
|
||||
'INT',
|
||||
'INTEGER',
|
||||
'INTERSECT',
|
||||
'INTERVAL',
|
||||
'INTO',
|
||||
'IS',
|
||||
'ISOLATION',
|
||||
'ISQL',
|
||||
'JOIN',
|
||||
'KEY',
|
||||
'LANGUAGE',
|
||||
'LAST',
|
||||
'LC_MESSAGES',
|
||||
'LC_TYPE',
|
||||
'LEADING',
|
||||
'LEADING',
|
||||
'LEADING',
|
||||
'LEAVE',
|
||||
'LEFT',
|
||||
'LENGTH',
|
||||
'LEV',
|
||||
'LEVEL',
|
||||
'LIKE',
|
||||
'LOCAL',
|
||||
'LOCK',
|
||||
'LOG_BUF_SIZE',
|
||||
'LOG_BUFFER_SIZE',
|
||||
'LOGFILE',
|
||||
'LONG',
|
||||
'LOWER',
|
||||
'MANUAL',
|
||||
'MATCH',
|
||||
'MAX',
|
||||
'MAX_SEGMENT',
|
||||
'MAXIMUM',
|
||||
'MAXIMUM_SEGMENT',
|
||||
'MERGE',
|
||||
'MESSAGE',
|
||||
'MIN',
|
||||
'MINIMUM',
|
||||
'MINUTE',
|
||||
'MODULE',
|
||||
'MODULE_NAME',
|
||||
'MONTH',
|
||||
'NAMES',
|
||||
'NATIONAL',
|
||||
'NATURAL',
|
||||
'NCHAR',
|
||||
'NEXT',
|
||||
'NO',
|
||||
'NOAUTO',
|
||||
'NOT',
|
||||
'NULL',
|
||||
'NULLIF',
|
||||
'NULLS',
|
||||
'NUM_LOG_BUFFERS',
|
||||
'NUM_LOG_BUFS',
|
||||
'NUMERIC',
|
||||
'OCTET_LENGTH',
|
||||
'OF',
|
||||
'ON',
|
||||
'ONLY',
|
||||
'OPEN',
|
||||
'OPTION',
|
||||
'OR',
|
||||
'ORDER',
|
||||
'OUTER',
|
||||
'OUTPUT',
|
||||
'OUTPUT_TYPE',
|
||||
'OVERFLOW',
|
||||
'OVERLAPS',
|
||||
'PAD',
|
||||
'PAGE',
|
||||
'PAGE_SIZE',
|
||||
'PAGELENGTH',
|
||||
'PAGES',
|
||||
'PARAMETER',
|
||||
'PARTIAL',
|
||||
'PASSWORD',
|
||||
'PERCENT',
|
||||
'PLAN',
|
||||
'POSITION',
|
||||
'POST_EVENT',
|
||||
'PRECISION',
|
||||
'PREPARE',
|
||||
'PRESERVE',
|
||||
'PRIMARY',
|
||||
'PRIOR',
|
||||
'PRIVILEGES',
|
||||
'PROCEDURE',
|
||||
'PUBLIC',
|
||||
'QUIT',
|
||||
'RAW_PARTITIONS',
|
||||
'RDB$DB_KEY',
|
||||
'READ',
|
||||
'REAL',
|
||||
'RECORD_VERSION',
|
||||
'RECREATE',
|
||||
'RECREATE ROW_COUNT',
|
||||
'REFERENCES',
|
||||
'RELATIVE',
|
||||
'RELEASE',
|
||||
'RESERV',
|
||||
'RESERVING',
|
||||
'RESTART',
|
||||
'RESTRICT',
|
||||
'RETAIN',
|
||||
'RETURN',
|
||||
'RETURNING',
|
||||
'RETURNING_VALUES',
|
||||
'RETURNS',
|
||||
'REVOKE',
|
||||
'RIGHT',
|
||||
'ROLE',
|
||||
'ROLLBACK',
|
||||
'ROW_COUNT',
|
||||
'ROWS',
|
||||
'RUNTIME',
|
||||
'SAVEPOINT',
|
||||
'SCALAR_ARRAY',
|
||||
'SCHEMA',
|
||||
'SCROLL',
|
||||
'SECOND',
|
||||
'SECTION',
|
||||
'SELECT',
|
||||
'SEQUENCE',
|
||||
'SESSION',
|
||||
'SESSION_USER',
|
||||
'SET',
|
||||
'SHADOW',
|
||||
'SHARED',
|
||||
'SHELL',
|
||||
'SHOW',
|
||||
'SINGULAR',
|
||||
'SIZE',
|
||||
'SKIP',
|
||||
'SMALLINT',
|
||||
'SNAPSHOT',
|
||||
'SOME',
|
||||
'SORT',
|
||||
'SPACE',
|
||||
'SQL',
|
||||
'SQLCODE',
|
||||
'SQLERROR',
|
||||
'SQLSTATE',
|
||||
'SQLWARNING',
|
||||
'STABILITY',
|
||||
'STARTING',
|
||||
'STARTS',
|
||||
'STATEMENT',
|
||||
'STATIC',
|
||||
'STATISTICS',
|
||||
'SUB_TYPE',
|
||||
'SUBSTRING',
|
||||
'SUM',
|
||||
'SUSPEND',
|
||||
'SYSTEM_USER',
|
||||
'TABLE',
|
||||
'TEMPORARY',
|
||||
'TERMINATOR',
|
||||
'THEN',
|
||||
'TIES',
|
||||
'TIME',
|
||||
'TIMESTAMP',
|
||||
'TIMEZONE_HOUR',
|
||||
'TIMEZONE_MINUTE',
|
||||
'TO',
|
||||
'TRAILING',
|
||||
'TRANSACTION',
|
||||
'TRANSLATE',
|
||||
'TRANSLATION',
|
||||
'TRIGGER',
|
||||
'TRIM',
|
||||
'TRUE',
|
||||
'TYPE',
|
||||
'UNCOMMITTED',
|
||||
'UNION',
|
||||
'UNIQUE',
|
||||
'UNKNOWN',
|
||||
'UPDATE',
|
||||
'UPDATING',
|
||||
'UPPER',
|
||||
'USAGE',
|
||||
'USER',
|
||||
'USING',
|
||||
'VALUE',
|
||||
'VALUES',
|
||||
'VARCHAR',
|
||||
'VARIABLE',
|
||||
'VARYING',
|
||||
'VERSION',
|
||||
'VIEW',
|
||||
'WAIT',
|
||||
'WEEKDAY',
|
||||
'WHEN',
|
||||
'WHENEVER',
|
||||
'WHERE',
|
||||
'WHILE',
|
||||
'WITH',
|
||||
'WORK',
|
||||
'WRITE',
|
||||
'YEAR',
|
||||
'YEARDAY',
|
||||
'ZONE',
|
||||
);
|
||||
// }}}
|
||||
+260
@@ -0,0 +1,260 @@
|
||||
<?php /* vim: se et ts=4 sw=4 sts=4 fdm=marker tw=80: */
|
||||
/**
|
||||
* Copyright (c) 1998-2010 Manuel Lemos, Tomas V.V.Cox,
|
||||
* Stig. S. Bakken, Lukas Smith, Igor Feghali
|
||||
* All rights reserved.
|
||||
*
|
||||
* MDB2_Schema enables users to maintain RDBMS independant schema files
|
||||
* in XML that can be used to manipulate both data and database schemas
|
||||
* This LICENSE is in the BSD license style.
|
||||
*
|
||||
* 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,
|
||||
* Lukas Smith, Igor Feghali nor the names of his 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
|
||||
* REGENTS 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.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Database
|
||||
* @package MDB2_Schema
|
||||
* @author David Coallier <davidc@php.net>
|
||||
* @license BSD http://www.opensource.org/licenses/bsd-license.php
|
||||
* @version SVN: $Id$
|
||||
* @link http://pear.php.net/packages/MDB2_Schema
|
||||
*/
|
||||
|
||||
// {{{ $GLOBALS['_MDB2_Schema_Reserved']['mssql']
|
||||
/**
|
||||
* Has a list of all the reserved words for mssql.
|
||||
*
|
||||
* @package MDB2_Schema
|
||||
* @category Database
|
||||
* @access protected
|
||||
* @author David Coallier <davidc@php.net>
|
||||
*/
|
||||
$GLOBALS['_MDB2_Schema_Reserved']['mssql'] = array(
|
||||
'ADD',
|
||||
'CURRENT_TIMESTAMP',
|
||||
'GROUP',
|
||||
'OPENQUERY',
|
||||
'SERIALIZABLE',
|
||||
'ALL',
|
||||
'CURRENT_USER',
|
||||
'HAVING',
|
||||
'OPENROWSET',
|
||||
'SESSION_USER',
|
||||
'ALTER',
|
||||
'CURSOR',
|
||||
'HOLDLOCK',
|
||||
'OPTION',
|
||||
'SET',
|
||||
'AND',
|
||||
'DATABASE',
|
||||
'IDENTITY',
|
||||
'OR',
|
||||
'SETUSER',
|
||||
'ANY',
|
||||
'DBCC',
|
||||
'IDENTITYCOL',
|
||||
'ORDER',
|
||||
'SHUTDOWN',
|
||||
'AS',
|
||||
'DEALLOCATE',
|
||||
'IDENTITY_INSERT',
|
||||
'OUTER',
|
||||
'SOME',
|
||||
'ASC',
|
||||
'DECLARE',
|
||||
'IF',
|
||||
'OVER',
|
||||
'STATISTICS',
|
||||
'AUTHORIZATION',
|
||||
'DEFAULT',
|
||||
'IN',
|
||||
'PERCENT',
|
||||
'SUM',
|
||||
'AVG',
|
||||
'DELETE',
|
||||
'INDEX',
|
||||
'PERM',
|
||||
'SYSTEM_USER',
|
||||
'BACKUP',
|
||||
'DENY',
|
||||
'INNER',
|
||||
'PERMANENT',
|
||||
'TABLE',
|
||||
'BEGIN',
|
||||
'DESC',
|
||||
'INSERT',
|
||||
'PIPE',
|
||||
'TAPE',
|
||||
'BETWEEN',
|
||||
'DISK',
|
||||
'INTERSECT',
|
||||
'PLAN',
|
||||
'TEMP',
|
||||
'BREAK',
|
||||
'DISTINCT',
|
||||
'INTO',
|
||||
'PRECISION',
|
||||
'TEMPORARY',
|
||||
'BROWSE',
|
||||
'DISTRIBUTED',
|
||||
'IS',
|
||||
'PREPARE',
|
||||
'TEXTSIZE',
|
||||
'BULK',
|
||||
'DOUBLE',
|
||||
'ISOLATION',
|
||||
'PRIMARY',
|
||||
'THEN',
|
||||
'BY',
|
||||
'DROP',
|
||||
'JOIN',
|
||||
'PRINT',
|
||||
'TO',
|
||||
'CASCADE',
|
||||
'DUMMY',
|
||||
'KEY',
|
||||
'PRIVILEGES',
|
||||
'TOP',
|
||||
'CASE',
|
||||
'DUMP',
|
||||
'KILL',
|
||||
'PROC',
|
||||
'TRAN',
|
||||
'CHECK',
|
||||
'ELSE',
|
||||
'LEFT',
|
||||
'PROCEDURE',
|
||||
'TRANSACTION',
|
||||
'CHECKPOINT',
|
||||
'END',
|
||||
'LEVEL',
|
||||
'PROCESSEXIT',
|
||||
'TRIGGER',
|
||||
'CLOSE',
|
||||
'ERRLVL',
|
||||
'LIKE',
|
||||
'PUBLIC',
|
||||
'TRUNCATE',
|
||||
'CLUSTERED',
|
||||
'ERROREXIT',
|
||||
'LINENO',
|
||||
'RAISERROR',
|
||||
'TSEQUAL',
|
||||
'COALESCE',
|
||||
'ESCAPE',
|
||||
'LOAD',
|
||||
'READ',
|
||||
'UNCOMMITTED',
|
||||
'COLUMN',
|
||||
'EXCEPT',
|
||||
'MAX',
|
||||
'READTEXT',
|
||||
'UNION',
|
||||
'COMMIT',
|
||||
'EXEC',
|
||||
'MIN',
|
||||
'RECONFIGURE',
|
||||
'UNIQUE',
|
||||
'COMMITTED',
|
||||
'EXECUTE',
|
||||
'MIRROREXIT',
|
||||
'REFERENCES',
|
||||
'UPDATE',
|
||||
'COMPUTE',
|
||||
'EXISTS',
|
||||
'NATIONAL',
|
||||
'REPEATABLE',
|
||||
'UPDATETEXT',
|
||||
'CONFIRM',
|
||||
'EXIT',
|
||||
'NOCHECK',
|
||||
'REPLICATION',
|
||||
'USE',
|
||||
'CONSTRAINT',
|
||||
'FETCH',
|
||||
'NONCLUSTERED',
|
||||
'RESTORE',
|
||||
'USER',
|
||||
'CONTAINS',
|
||||
'FILE',
|
||||
'NOT',
|
||||
'RESTRICT',
|
||||
'VALUES',
|
||||
'CONTAINSTABLE',
|
||||
'FILLFACTOR',
|
||||
'NULL',
|
||||
'RETURN',
|
||||
'VARYING',
|
||||
'CONTINUE',
|
||||
'FLOPPY',
|
||||
'NULLIF',
|
||||
'REVOKE',
|
||||
'VIEW',
|
||||
'CONTROLROW',
|
||||
'FOR',
|
||||
'OF',
|
||||
'RIGHT',
|
||||
'WAITFOR',
|
||||
'CONVERT',
|
||||
'FOREIGN',
|
||||
'OFF',
|
||||
'ROLLBACK',
|
||||
'WHEN',
|
||||
'COUNT',
|
||||
'FREETEXT',
|
||||
'OFFSETS',
|
||||
'ROWCOUNT',
|
||||
'WHERE',
|
||||
'CREATE',
|
||||
'FREETEXTTABLE',
|
||||
'ON',
|
||||
'ROWGUIDCOL',
|
||||
'WHILE',
|
||||
'CROSS',
|
||||
'FROM',
|
||||
'ONCE',
|
||||
'RULE',
|
||||
'WITH',
|
||||
'CURRENT',
|
||||
'FULL',
|
||||
'ONLY',
|
||||
'SAVE',
|
||||
'WORK',
|
||||
'CURRENT_DATE',
|
||||
'GOTO',
|
||||
'OPEN',
|
||||
'SCHEMA',
|
||||
'WRITETEXT',
|
||||
'CURRENT_TIME',
|
||||
'GRANT',
|
||||
'OPENDATASOURCE',
|
||||
'SELECT',
|
||||
);
|
||||
//}}}
|
||||
+285
@@ -0,0 +1,285 @@
|
||||
<?php /* vim: se et ts=4 sw=4 sts=4 fdm=marker tw=80: */
|
||||
/**
|
||||
* Copyright (c) 1998-2010 Manuel Lemos, Tomas V.V.Cox,
|
||||
* Stig. S. Bakken, Lukas Smith, Igor Feghali
|
||||
* All rights reserved.
|
||||
*
|
||||
* MDB2_Schema enables users to maintain RDBMS independant schema files
|
||||
* in XML that can be used to manipulate both data and database schemas
|
||||
* This LICENSE is in the BSD license style.
|
||||
*
|
||||
* 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,
|
||||
* Lukas Smith, Igor Feghali nor the names of his 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
|
||||
* REGENTS 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.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Database
|
||||
* @package MDB2_Schema
|
||||
* @author David Coallier <davidc@php.net>
|
||||
* @license BSD http://www.opensource.org/licenses/bsd-license.php
|
||||
* @version SVN: $Id$
|
||||
* @link http://pear.php.net/packages/MDB2_Schema
|
||||
*/
|
||||
|
||||
// {{{ $GLOBALS['_MDB2_Schema_Reserved']['mysql']
|
||||
/**
|
||||
* Has a list of reserved words of mysql
|
||||
*
|
||||
* @package MDB2_Schema
|
||||
* @category Database
|
||||
* @access protected
|
||||
* @author David Coalier <davidc@php.net>
|
||||
*/
|
||||
$GLOBALS['_MDB2_Schema_Reserved']['mysql'] = array(
|
||||
'ADD',
|
||||
'ALL',
|
||||
'ALTER',
|
||||
'ANALYZE',
|
||||
'AND',
|
||||
'AS',
|
||||
'ASC',
|
||||
'ASENSITIVE',
|
||||
'BEFORE',
|
||||
'BETWEEN',
|
||||
'BIGINT',
|
||||
'BINARY',
|
||||
'BLOB',
|
||||
'BOTH',
|
||||
'BY',
|
||||
'CALL',
|
||||
'CASCADE',
|
||||
'CASE',
|
||||
'CHANGE',
|
||||
'CHAR',
|
||||
'CHARACTER',
|
||||
'CHECK',
|
||||
'COLLATE',
|
||||
'COLUMN',
|
||||
'CONDITION',
|
||||
'CONNECTION',
|
||||
'CONSTRAINT',
|
||||
'CONTINUE',
|
||||
'CONVERT',
|
||||
'CREATE',
|
||||
'CROSS',
|
||||
'CURRENT_DATE',
|
||||
'CURRENT_TIME',
|
||||
'CURRENT_TIMESTAMP',
|
||||
'CURRENT_USER',
|
||||
'CURSOR',
|
||||
'DATABASE',
|
||||
'DATABASES',
|
||||
'DAY_HOUR',
|
||||
'DAY_MICROSECOND',
|
||||
'DAY_MINUTE',
|
||||
'DAY_SECOND',
|
||||
'DEC',
|
||||
'DECIMAL',
|
||||
'DECLARE',
|
||||
'DEFAULT',
|
||||
'DELAYED',
|
||||
'DELETE',
|
||||
'DESC',
|
||||
'DESCRIBE',
|
||||
'DETERMINISTIC',
|
||||
'DISTINCT',
|
||||
'DISTINCTROW',
|
||||
'DIV',
|
||||
'DOUBLE',
|
||||
'DROP',
|
||||
'DUAL',
|
||||
'EACH',
|
||||
'ELSE',
|
||||
'ELSEIF',
|
||||
'ENCLOSED',
|
||||
'ESCAPED',
|
||||
'EXISTS',
|
||||
'EXIT',
|
||||
'EXPLAIN',
|
||||
'FALSE',
|
||||
'FETCH',
|
||||
'FLOAT',
|
||||
'FLOAT4',
|
||||
'FLOAT8',
|
||||
'FOR',
|
||||
'FORCE',
|
||||
'FOREIGN',
|
||||
'FROM',
|
||||
'FULLTEXT',
|
||||
'GOTO',
|
||||
'GRANT',
|
||||
'GROUP',
|
||||
'HAVING',
|
||||
'HIGH_PRIORITY',
|
||||
'HOUR_MICROSECOND',
|
||||
'HOUR_MINUTE',
|
||||
'HOUR_SECOND',
|
||||
'IF',
|
||||
'IGNORE',
|
||||
'IN',
|
||||
'INDEX',
|
||||
'INFILE',
|
||||
'INNER',
|
||||
'INOUT',
|
||||
'INSENSITIVE',
|
||||
'INSERT',
|
||||
'INT',
|
||||
'INT1',
|
||||
'INT2',
|
||||
'INT3',
|
||||
'INT4',
|
||||
'INT8',
|
||||
'INTEGER',
|
||||
'INTERVAL',
|
||||
'INTO',
|
||||
'IS',
|
||||
'ITERATE',
|
||||
'JOIN',
|
||||
'KEY',
|
||||
'KEYS',
|
||||
'KILL',
|
||||
'LABEL',
|
||||
'LEADING',
|
||||
'LEAVE',
|
||||
'LEFT',
|
||||
'LIKE',
|
||||
'LIMIT',
|
||||
'LINES',
|
||||
'LOAD',
|
||||
'LOCALTIME',
|
||||
'LOCALTIMESTAMP',
|
||||
'LOCK',
|
||||
'LONG',
|
||||
'LONGBLOB',
|
||||
'LONGTEXT',
|
||||
'LOOP',
|
||||
'LOW_PRIORITY',
|
||||
'MATCH',
|
||||
'MEDIUMBLOB',
|
||||
'MEDIUMINT',
|
||||
'MEDIUMTEXT',
|
||||
'MIDDLEINT',
|
||||
'MINUTE_MICROSECOND',
|
||||
'MINUTE_SECOND',
|
||||
'MOD',
|
||||
'MODIFIES',
|
||||
'NATURAL',
|
||||
'NOT',
|
||||
'NO_WRITE_TO_BINLOG',
|
||||
'NULL',
|
||||
'NUMERIC',
|
||||
'ON',
|
||||
'OPTIMIZE',
|
||||
'OPTION',
|
||||
'OPTIONALLY',
|
||||
'OR',
|
||||
'ORDER',
|
||||
'OUT',
|
||||
'OUTER',
|
||||
'OUTFILE',
|
||||
'PRECISION',
|
||||
'PRIMARY',
|
||||
'PROCEDURE',
|
||||
'PURGE',
|
||||
'RAID0',
|
||||
'READ',
|
||||
'READS',
|
||||
'REAL',
|
||||
'REFERENCES',
|
||||
'REGEXP',
|
||||
'RELEASE',
|
||||
'RENAME',
|
||||
'REPEAT',
|
||||
'REPLACE',
|
||||
'REQUIRE',
|
||||
'RESTRICT',
|
||||
'RETURN',
|
||||
'REVOKE',
|
||||
'RIGHT',
|
||||
'RLIKE',
|
||||
'SCHEMA',
|
||||
'SCHEMAS',
|
||||
'SECOND_MICROSECOND',
|
||||
'SELECT',
|
||||
'SENSITIVE',
|
||||
'SEPARATOR',
|
||||
'SET',
|
||||
'SHOW',
|
||||
'SMALLINT',
|
||||
'SONAME',
|
||||
'SPATIAL',
|
||||
'SPECIFIC',
|
||||
'SQL',
|
||||
'SQLEXCEPTION',
|
||||
'SQLSTATE',
|
||||
'SQLWARNING',
|
||||
'SQL_BIG_RESULT',
|
||||
'SQL_CALC_FOUND_ROWS',
|
||||
'SQL_SMALL_RESULT',
|
||||
'SSL',
|
||||
'STARTING',
|
||||
'STRAIGHT_JOIN',
|
||||
'TABLE',
|
||||
'TERMINATED',
|
||||
'THEN',
|
||||
'TINYBLOB',
|
||||
'TINYINT',
|
||||
'TINYTEXT',
|
||||
'TO',
|
||||
'TRAILING',
|
||||
'TRIGGER',
|
||||
'TRUE',
|
||||
'UNDO',
|
||||
'UNION',
|
||||
'UNIQUE',
|
||||
'UNLOCK',
|
||||
'UNSIGNED',
|
||||
'UPDATE',
|
||||
'USAGE',
|
||||
'USE',
|
||||
'USING',
|
||||
'UTC_DATE',
|
||||
'UTC_TIME',
|
||||
'UTC_TIMESTAMP',
|
||||
'VALUES',
|
||||
'VARBINARY',
|
||||
'VARCHAR',
|
||||
'VARCHARACTER',
|
||||
'VARYING',
|
||||
'WHEN',
|
||||
'WHERE',
|
||||
'WHILE',
|
||||
'WITH',
|
||||
'WRITE',
|
||||
'X509',
|
||||
'XOR',
|
||||
'YEAR_MONTH',
|
||||
'ZEROFILL',
|
||||
);
|
||||
// }}}
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
<?php /* vim: se et ts=4 sw=4 sts=4 fdm=marker tw=80: */
|
||||
/**
|
||||
* Copyright (c) 1998-2010 Manuel Lemos, Tomas V.V.Cox,
|
||||
* Stig. S. Bakken, Lukas Smith, Igor Feghali
|
||||
* All rights reserved.
|
||||
*
|
||||
* MDB2_Schema enables users to maintain RDBMS independant schema files
|
||||
* in XML that can be used to manipulate both data and database schemas
|
||||
* This LICENSE is in the BSD license style.
|
||||
*
|
||||
* 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,
|
||||
* Lukas Smith, Igor Feghali nor the names of his 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
|
||||
* REGENTS 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.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Database
|
||||
* @package MDB2_Schema
|
||||
* @author David Coallier <davidc@php.net>
|
||||
* @license BSD http://www.opensource.org/licenses/bsd-license.php
|
||||
* @version SVN: $Id$
|
||||
* @link http://pear.php.net/packages/MDB2_Schema
|
||||
*/
|
||||
|
||||
// {{{ $GLOBALS['_MDB2_Schema_Reserved']['oci8']
|
||||
/**
|
||||
* Has a list of all the reserved words for oracle.
|
||||
*
|
||||
* @package MDB2_Schema
|
||||
* @category Database
|
||||
* @access protected
|
||||
* @author David Coallier <davidc@php.net>
|
||||
*/
|
||||
$GLOBALS['_MDB2_Schema_Reserved']['oci8'] = array(
|
||||
'ACCESS',
|
||||
'ELSE',
|
||||
'MODIFY',
|
||||
'START',
|
||||
'ADD',
|
||||
'EXCLUSIVE',
|
||||
'NOAUDIT',
|
||||
'SELECT',
|
||||
'ALL',
|
||||
'EXISTS',
|
||||
'NOCOMPRESS',
|
||||
'SESSION',
|
||||
'ALTER',
|
||||
'FILE',
|
||||
'NOT',
|
||||
'SET',
|
||||
'AND',
|
||||
'FLOAT',
|
||||
'NOTFOUND ',
|
||||
'SHARE',
|
||||
'ANY',
|
||||
'FOR',
|
||||
'NOWAIT',
|
||||
'SIZE',
|
||||
'ARRAYLEN',
|
||||
'FROM',
|
||||
'NULL',
|
||||
'SMALLINT',
|
||||
'AS',
|
||||
'GRANT',
|
||||
'NUMBER',
|
||||
'SQLBUF',
|
||||
'ASC',
|
||||
'GROUP',
|
||||
'OF',
|
||||
'SUCCESSFUL',
|
||||
'AUDIT',
|
||||
'HAVING',
|
||||
'OFFLINE ',
|
||||
'SYNONYM',
|
||||
'BETWEEN',
|
||||
'IDENTIFIED',
|
||||
'ON',
|
||||
'SYSDATE',
|
||||
'BY',
|
||||
'IMMEDIATE',
|
||||
'ONLINE',
|
||||
'TABLE',
|
||||
'CHAR',
|
||||
'IN',
|
||||
'OPTION',
|
||||
'THEN',
|
||||
'CHECK',
|
||||
'INCREMENT',
|
||||
'OR',
|
||||
'TO',
|
||||
'CLUSTER',
|
||||
'INDEX',
|
||||
'ORDER',
|
||||
'TRIGGER',
|
||||
'COLUMN',
|
||||
'INITIAL',
|
||||
'PCTFREE',
|
||||
'UID',
|
||||
'COMMENT',
|
||||
'INSERT',
|
||||
'PRIOR',
|
||||
'UNION',
|
||||
'COMPRESS',
|
||||
'INTEGER',
|
||||
'PRIVILEGES',
|
||||
'UNIQUE',
|
||||
'CONNECT',
|
||||
'INTERSECT',
|
||||
'PUBLIC',
|
||||
'UPDATE',
|
||||
'CREATE',
|
||||
'INTO',
|
||||
'RAW',
|
||||
'USER',
|
||||
'CURRENT',
|
||||
'IS',
|
||||
'RENAME',
|
||||
'VALIDATE',
|
||||
'DATE',
|
||||
'LEVEL',
|
||||
'RESOURCE',
|
||||
'VALUES',
|
||||
'DECIMAL',
|
||||
'LIKE',
|
||||
'REVOKE',
|
||||
'VARCHAR',
|
||||
'DEFAULT',
|
||||
'LOCK',
|
||||
'ROW',
|
||||
'VARCHAR2',
|
||||
'DELETE',
|
||||
'LONG',
|
||||
'ROWID',
|
||||
'VIEW',
|
||||
'DESC',
|
||||
'MAXEXTENTS',
|
||||
'ROWLABEL',
|
||||
'WHENEVER',
|
||||
'DISTINCT',
|
||||
'MINUS',
|
||||
'ROWNUM',
|
||||
'WHERE',
|
||||
'DROP',
|
||||
'MODE',
|
||||
'ROWS',
|
||||
'WITH',
|
||||
);
|
||||
// }}}
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
<?php /* vim: se et ts=4 sw=4 sts=4 fdm=marker tw=80: */
|
||||
/**
|
||||
* Copyright (c) 1998-2010 Manuel Lemos, Tomas V.V.Cox,
|
||||
* Stig. S. Bakken, Lukas Smith, Igor Feghali
|
||||
* All rights reserved.
|
||||
*
|
||||
* MDB2_Schema enables users to maintain RDBMS independant schema files
|
||||
* in XML that can be used to manipulate both data and database schemas
|
||||
* This LICENSE is in the BSD license style.
|
||||
*
|
||||
* 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,
|
||||
* Lukas Smith, Igor Feghali nor the names of his 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
|
||||
* REGENTS 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.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Database
|
||||
* @package MDB2_Schema
|
||||
* @author Marcelo Santos Araujo <msaraujo@php.net>
|
||||
* @license BSD http://www.opensource.org/licenses/bsd-license.php
|
||||
* @version SVN: $Id$
|
||||
* @link http://pear.php.net/packages/MDB2_Schema
|
||||
*/
|
||||
|
||||
// {{{ $GLOBALS['_MDB2_Schema_Reserved']['pgsql']
|
||||
/**
|
||||
* Has a list of reserved words of pgsql
|
||||
*
|
||||
* @package MDB2_Schema
|
||||
* @category Database
|
||||
* @access protected
|
||||
* @author Marcelo Santos Araujo <msaraujo@php.net>
|
||||
*/
|
||||
$GLOBALS['_MDB2_Schema_Reserved']['pgsql'] = array(
|
||||
'ALL',
|
||||
'ANALYSE',
|
||||
'ANALYZE',
|
||||
'AND',
|
||||
'ANY',
|
||||
'AS',
|
||||
'ASC',
|
||||
'AUTHORIZATION',
|
||||
'BETWEEN',
|
||||
'BINARY',
|
||||
'BOTH',
|
||||
'CASE',
|
||||
'CAST',
|
||||
'CHECK',
|
||||
'COLLATE',
|
||||
'COLUMN',
|
||||
'CONSTRAINT',
|
||||
'CREATE',
|
||||
'CURRENT_DATE',
|
||||
'CURRENT_TIME',
|
||||
'CURRENT_TIMESTAMP',
|
||||
'CURRENT_USER',
|
||||
'DEFAULT',
|
||||
'DEFERRABLE',
|
||||
'DESC',
|
||||
'DISTINCT',
|
||||
'DO',
|
||||
'ELSE',
|
||||
'END',
|
||||
'EXCEPT',
|
||||
'FALSE',
|
||||
'FOR',
|
||||
'FOREIGN',
|
||||
'FREEZE',
|
||||
'FROM',
|
||||
'FULL',
|
||||
'GRANT',
|
||||
'GROUP',
|
||||
'HAVING',
|
||||
'ILIKE',
|
||||
'IN',
|
||||
'INITIALLY',
|
||||
'INNER',
|
||||
'INTERSECT',
|
||||
'INTO',
|
||||
'IS',
|
||||
'ISNULL',
|
||||
'JOIN',
|
||||
'LEADING',
|
||||
'LEFT',
|
||||
'LIKE',
|
||||
'LIMIT',
|
||||
'LOCALTIME',
|
||||
'LOCALTIMESTAMP',
|
||||
'NATURAL',
|
||||
'NEW',
|
||||
'NOT',
|
||||
'NOTNULL',
|
||||
'NULL',
|
||||
'OFF',
|
||||
'OFFSET',
|
||||
'OLD',
|
||||
'ON',
|
||||
'ONLY',
|
||||
'OR',
|
||||
'ORDER',
|
||||
'OUTER',
|
||||
'OVERLAPS',
|
||||
'PLACING',
|
||||
'PRIMARY',
|
||||
'REFERENCES',
|
||||
'SELECT',
|
||||
'SESSION_USER',
|
||||
'SIMILAR',
|
||||
'SOME',
|
||||
'TABLE',
|
||||
'THEN',
|
||||
'TO',
|
||||
'TRAILING',
|
||||
'TRUE',
|
||||
'UNION',
|
||||
'UNIQUE',
|
||||
'USER',
|
||||
'USING',
|
||||
'VERBOSE',
|
||||
'WHEN',
|
||||
'WHERE'
|
||||
);
|
||||
// }}}
|
||||
Vendored
+583
@@ -0,0 +1,583 @@
|
||||
<?php /* vim: se et ts=4 sw=4 sts=4 fdm=marker tw=80: */
|
||||
/**
|
||||
* Copyright (c) 1998-2010 Manuel Lemos, Tomas V.V.Cox,
|
||||
* Stig. S. Bakken, Lukas Smith, Igor Feghali
|
||||
* All rights reserved.
|
||||
*
|
||||
* MDB2_Schema enables users to maintain RDBMS independant schema files
|
||||
* in XML that can be used to manipulate both data and database schemas
|
||||
* This LICENSE is in the BSD license style.
|
||||
*
|
||||
* 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,
|
||||
* Lukas Smith, Igor Feghali nor the names of his 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
|
||||
* REGENTS 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.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Database
|
||||
* @package MDB2_Schema
|
||||
* @author Christian Weiske <cweiske@php.net>
|
||||
* @license BSD http://www.opensource.org/licenses/bsd-license.php
|
||||
* @version SVN: $Id$
|
||||
* @link http://pear.php.net/packages/MDB2_Schema
|
||||
*/
|
||||
|
||||
require_once 'MDB2/Schema.php';
|
||||
require_once 'MDB2/Schema/Tool/ParameterException.php';
|
||||
|
||||
/**
|
||||
* Command line tool to work with database schemas
|
||||
*
|
||||
* Functionality:
|
||||
* - dump a database schema to stdout
|
||||
* - import schema into database
|
||||
* - create a diff between two schemas
|
||||
* - apply diff to database
|
||||
*
|
||||
* @category Database
|
||||
* @package MDB2_Schema
|
||||
* @author Christian Weiske <cweiske@php.net>
|
||||
* @license BSD http://www.opensource.org/licenses/bsd-license.php
|
||||
* @link http://pear.php.net/packages/MDB2_Schema
|
||||
*/
|
||||
class MDB2_Schema_Tool
|
||||
{
|
||||
/**
|
||||
* Run the schema tool
|
||||
*
|
||||
* @param array $args Array of command line arguments
|
||||
*/
|
||||
public function __construct($args)
|
||||
{
|
||||
$strAction = $this->getAction($args);
|
||||
try {
|
||||
$this->{'do' . ucfirst($strAction)}($args);
|
||||
} catch (MDB2_Schema_Tool_ParameterException $e) {
|
||||
$this->{'doHelp' . ucfirst($strAction)}($e->getMessage());
|
||||
}
|
||||
}//public function __construct($args)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Runs the tool with command line arguments
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
$args = $GLOBALS['argv'];
|
||||
array_shift($args);
|
||||
|
||||
try {
|
||||
$tool = new MDB2_Schema_Tool($args);
|
||||
} catch (Exception $e) {
|
||||
self::toStdErr($e->getMessage() . "\n");
|
||||
}
|
||||
}//public static function run()
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reads the first parameter from the argument array and
|
||||
* returns the action.
|
||||
*
|
||||
* @param array &$args Command line parameters
|
||||
*
|
||||
* @return string Action to execute
|
||||
*/
|
||||
protected function getAction(&$args)
|
||||
{
|
||||
if (count($args) == 0) {
|
||||
return 'help';
|
||||
}
|
||||
$arg = array_shift($args);
|
||||
switch ($arg) {
|
||||
case 'h':
|
||||
case 'help':
|
||||
case '-h':
|
||||
case '--help':
|
||||
return 'help';
|
||||
case 'd':
|
||||
case 'dump':
|
||||
case '-d':
|
||||
case '--dump':
|
||||
return 'dump';
|
||||
case 'l':
|
||||
case 'load':
|
||||
case '-l':
|
||||
case '--load':
|
||||
return 'load';
|
||||
case 'i':
|
||||
case 'diff':
|
||||
case '-i':
|
||||
case '--diff':
|
||||
return 'diff';
|
||||
case 'a':
|
||||
case 'apply':
|
||||
case '-a':
|
||||
case '--apply':
|
||||
return 'apply';
|
||||
case 'n':
|
||||
case 'init':
|
||||
case '-i':
|
||||
case '--init':
|
||||
return 'init';
|
||||
default:
|
||||
throw new MDB2_Schema_Tool_ParameterException(
|
||||
"Unknown mode \"$arg\""
|
||||
);
|
||||
}
|
||||
}//protected function getAction(&$args)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Writes the message to stderr
|
||||
*
|
||||
* @param string $msg Message to print
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function toStdErr($msg)
|
||||
{
|
||||
file_put_contents('php://stderr', $msg);
|
||||
}//protected static function toStdErr($msg)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Displays generic help to stdout
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function doHelp()
|
||||
{
|
||||
self::toStdErr(
|
||||
<<<EOH
|
||||
Usage: mdb2_schematool mode parameters
|
||||
|
||||
Works with database schemas
|
||||
|
||||
mode: (- and -- are optional)
|
||||
h, help Show this help screen
|
||||
d, dump Dump a schema to stdout
|
||||
l, load Load a schema into database
|
||||
i, diff Create a diff between two schemas and dump it to stdout
|
||||
a, apply Apply a diff to a database
|
||||
n, init Initialize a database with data
|
||||
|
||||
EOH
|
||||
);
|
||||
}//protected function doHelp()
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Displays the help screen for "dump" command
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function doHelpDump()
|
||||
{
|
||||
self::toStdErr(
|
||||
<<<EOH
|
||||
Usage: mdb2_schematool dump [all|data|schema] [-p] DSN
|
||||
|
||||
Dumps a database schema to stdout
|
||||
|
||||
If dump type is not specified, defaults to "schema".
|
||||
|
||||
DSN: Data source name in the form of
|
||||
driver://user:password@host/database
|
||||
|
||||
User and password may be omitted.
|
||||
Using -p reads password from stdin which is more secure than passing it in the
|
||||
parameter.
|
||||
|
||||
EOH
|
||||
);
|
||||
}//protected function doHelpDump()
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Displays the help screen for "init" command
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function doHelpInit()
|
||||
{
|
||||
self::toStdErr(
|
||||
<<<EOH
|
||||
Usage: mdb2_schematool init source [-p] destination
|
||||
|
||||
Initializes a database with data
|
||||
(Inserts data on a previous created database at destination)
|
||||
|
||||
source should be a schema file containing data,
|
||||
destination should be a DSN
|
||||
|
||||
DSN: Data source name in the form of
|
||||
driver://user:password@host/database
|
||||
|
||||
User and password may be omitted.
|
||||
Using -p reads password from stdin which is more secure than passing it in the
|
||||
parameter.
|
||||
|
||||
EOH
|
||||
);
|
||||
}//protected function doHelpInit()
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Displays the help screen for "load" command
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function doHelpLoad()
|
||||
{
|
||||
self::toStdErr(
|
||||
<<<EOH
|
||||
Usage: mdb2_schematool load [-p] source [-p] destination
|
||||
|
||||
Loads a database schema from source to destination
|
||||
(Creates the database schema at destination)
|
||||
|
||||
source can be a DSN or a schema file,
|
||||
destination should be a DSN
|
||||
|
||||
DSN: Data source name in the form of
|
||||
driver://user:password@host/database
|
||||
|
||||
User and password may be omitted.
|
||||
Using -p reads password from stdin which is more secure than passing it in the
|
||||
parameter.
|
||||
|
||||
EOH
|
||||
);
|
||||
}//protected function doHelpLoad()
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of options for MDB2_Schema constructor
|
||||
*
|
||||
* @return array Options for MDB2_Schema constructor
|
||||
*/
|
||||
protected function getSchemaOptions()
|
||||
{
|
||||
$options = array(
|
||||
'log_line_break' => '<br>',
|
||||
'idxname_format' => '%s',
|
||||
'debug' => true,
|
||||
'quote_identifier' => true,
|
||||
'force_defaults' => false,
|
||||
'portability' => true,
|
||||
'use_transactions' => false,
|
||||
);
|
||||
return $options;
|
||||
}//protected function getSchemaOptions()
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the passed parameter is a PEAR_Error object
|
||||
* and throws an exception in that case.
|
||||
*
|
||||
* @param mixed $object Some variable to check
|
||||
* @param string $location Where the error occured
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function throwExceptionOnError($object, $location = '')
|
||||
{
|
||||
if (PEAR::isError($object)) {
|
||||
//FIXME: exception class
|
||||
//debug_print_backtrace();
|
||||
throw new Exception('Error ' . $location
|
||||
. "\n" . $object->getMessage()
|
||||
. "\n" . $object->getUserInfo()
|
||||
);
|
||||
}
|
||||
}//protected function throwExceptionOnError($object, $location = '')
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Loads a file or a dsn from the arguments
|
||||
*
|
||||
* @param array &$args Array of arguments to the program
|
||||
*
|
||||
* @return array Array of ('file'|'dsn', $value)
|
||||
*/
|
||||
protected function getFileOrDsn(&$args)
|
||||
{
|
||||
if (count($args) == 0) {
|
||||
throw new MDB2_Schema_Tool_ParameterException(
|
||||
'File or DSN expected'
|
||||
);
|
||||
}
|
||||
|
||||
$arg = array_shift($args);
|
||||
if ($arg == '-p') {
|
||||
$bAskPassword = true;
|
||||
$arg = array_shift($args);
|
||||
} else {
|
||||
$bAskPassword = false;
|
||||
}
|
||||
|
||||
if (strpos($arg, '://') === false) {
|
||||
if (file_exists($arg)) {
|
||||
//File
|
||||
return array('file', $arg);
|
||||
} else {
|
||||
throw new Exception('Schema file does not exist');
|
||||
}
|
||||
}
|
||||
|
||||
//read password if necessary
|
||||
if ($bAskPassword) {
|
||||
$password = $this->readPasswordFromStdin($arg);
|
||||
$arg = self::setPasswordIntoDsn($arg, $password);
|
||||
self::toStdErr($arg);
|
||||
}
|
||||
return array('dsn', $arg);
|
||||
}//protected function getFileOrDsn(&$args)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Takes a DSN data source name and integrates the given
|
||||
* password into it.
|
||||
*
|
||||
* @param string $dsn Data source name
|
||||
* @param string $password Password
|
||||
*
|
||||
* @return string DSN with password
|
||||
*/
|
||||
protected function setPasswordIntoDsn($dsn, $password)
|
||||
{
|
||||
//simple try to integrate password
|
||||
if (strpos($dsn, '@') === false) {
|
||||
//no @ -> no user and no password
|
||||
return str_replace('://', '://:' . $password . '@', $dsn);
|
||||
} else if (preg_match('|://[^:]+@|', $dsn)) {
|
||||
//user only, no password
|
||||
return str_replace('@', ':' . $password . '@', $dsn);
|
||||
} else if (strpos($dsn, ':@') !== false) {
|
||||
//abstract version
|
||||
return str_replace(':@', ':' . $password . '@', $dsn);
|
||||
}
|
||||
|
||||
return $dsn;
|
||||
}//protected function setPasswordIntoDsn($dsn, $password)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reads a password from stdin
|
||||
*
|
||||
* @param string $dsn DSN name to put into the message
|
||||
*
|
||||
* @return string Password
|
||||
*/
|
||||
protected function readPasswordFromStdin($dsn)
|
||||
{
|
||||
$stdin = fopen('php://stdin', 'r');
|
||||
self::toStdErr('Please insert password for ' . $dsn . "\n");
|
||||
$password = '';
|
||||
$breakme = false;
|
||||
while (false !== ($char = fgetc($stdin))) {
|
||||
if (ord($char) == 10 || $char == "\n" || $char == "\r") {
|
||||
break;
|
||||
}
|
||||
$password .= $char;
|
||||
}
|
||||
fclose($stdin);
|
||||
|
||||
return trim($password);
|
||||
}//protected function readPasswordFromStdin()
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a database schema dump and sends it to stdout
|
||||
*
|
||||
* @param array $args Command line arguments
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function doDump($args)
|
||||
{
|
||||
$dump_what = MDB2_SCHEMA_DUMP_STRUCTURE;
|
||||
$arg = '';
|
||||
if (count($args)) {
|
||||
$arg = $args[0];
|
||||
}
|
||||
|
||||
switch (strtolower($arg)) {
|
||||
case 'all':
|
||||
$dump_what = MDB2_SCHEMA_DUMP_ALL;
|
||||
array_shift($args);
|
||||
break;
|
||||
case 'data':
|
||||
$dump_what = MDB2_SCHEMA_DUMP_CONTENT;
|
||||
array_shift($args);
|
||||
break;
|
||||
case 'schema':
|
||||
array_shift($args);
|
||||
}
|
||||
|
||||
list($type, $dsn) = $this->getFileOrDsn($args);
|
||||
if ($type == 'file') {
|
||||
throw new MDB2_Schema_Tool_ParameterException(
|
||||
'Dumping a schema file as a schema file does not make much ' .
|
||||
'sense'
|
||||
);
|
||||
}
|
||||
|
||||
$schema = MDB2_Schema::factory($dsn, $this->getSchemaOptions());
|
||||
$this->throwExceptionOnError($schema);
|
||||
|
||||
$definition = $schema->getDefinitionFromDatabase();
|
||||
$this->throwExceptionOnError($definition);
|
||||
|
||||
|
||||
$dump_options = array(
|
||||
'output_mode' => 'file',
|
||||
'output' => 'php://stdout',
|
||||
'end_of_line' => "\r\n"
|
||||
);
|
||||
$op = $schema->dumpDatabase(
|
||||
$definition, $dump_options, $dump_what
|
||||
);
|
||||
$this->throwExceptionOnError($op);
|
||||
|
||||
$schema->disconnect();
|
||||
}//protected function doDump($args)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Loads a database schema
|
||||
*
|
||||
* @param array $args Command line arguments
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function doLoad($args)
|
||||
{
|
||||
list($typeSource, $dsnSource) = $this->getFileOrDsn($args);
|
||||
list($typeDest, $dsnDest) = $this->getFileOrDsn($args);
|
||||
|
||||
if ($typeDest == 'file') {
|
||||
throw new MDB2_Schema_Tool_ParameterException(
|
||||
'A schema can only be loaded into a database, not a file'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
$schemaDest = MDB2_Schema::factory($dsnDest, $this->getSchemaOptions());
|
||||
$this->throwExceptionOnError($schemaDest);
|
||||
|
||||
//load definition
|
||||
if ($typeSource == 'file') {
|
||||
$definition = $schemaDest->parseDatabaseDefinitionFile($dsnSource);
|
||||
$where = 'loading schema file';
|
||||
} else {
|
||||
$schemaSource = MDB2_Schema::factory(
|
||||
$dsnSource,
|
||||
$this->getSchemaOptions()
|
||||
);
|
||||
$this->throwExceptionOnError(
|
||||
$schemaSource,
|
||||
'connecting to source database'
|
||||
);
|
||||
|
||||
$definition = $schemaSource->getDefinitionFromDatabase();
|
||||
$where = 'loading definition from database';
|
||||
}
|
||||
$this->throwExceptionOnError($definition, $where);
|
||||
|
||||
|
||||
//create destination database from definition
|
||||
$simulate = false;
|
||||
$op = $schemaDest->createDatabase(
|
||||
$definition,
|
||||
array(),
|
||||
$simulate
|
||||
);
|
||||
$this->throwExceptionOnError($op, 'creating the database');
|
||||
}//protected function doLoad($args)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Initializes a database with data
|
||||
*
|
||||
* @param array $args Command line arguments
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function doInit($args)
|
||||
{
|
||||
list($typeSource, $dsnSource) = $this->getFileOrDsn($args);
|
||||
list($typeDest, $dsnDest) = $this->getFileOrDsn($args);
|
||||
|
||||
if ($typeSource != 'file') {
|
||||
throw new MDB2_Schema_Tool_ParameterException(
|
||||
'Data must come from a source file'
|
||||
);
|
||||
}
|
||||
|
||||
if ($typeDest != 'dsn') {
|
||||
throw new MDB2_Schema_Tool_ParameterException(
|
||||
'A schema can only be loaded into a database, not a file'
|
||||
);
|
||||
}
|
||||
|
||||
$schemaDest = MDB2_Schema::factory($dsnDest, $this->getSchemaOptions());
|
||||
$this->throwExceptionOnError(
|
||||
$schemaDest,
|
||||
'connecting to destination database'
|
||||
);
|
||||
|
||||
$definition = $schemaDest->getDefinitionFromDatabase();
|
||||
$this->throwExceptionOnError(
|
||||
$definition,
|
||||
'loading definition from database'
|
||||
);
|
||||
|
||||
$op = $schemaDest->writeInitialization($dsnSource, $definition);
|
||||
$this->throwExceptionOnError($op, 'initializing database');
|
||||
}//protected function doInit($args)
|
||||
|
||||
|
||||
}//class MDB2_Schema_Tool
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php /* vim: se et ts=4 sw=4 sts=4 fdm=marker tw=80: */
|
||||
/**
|
||||
* Copyright (c) 1998-2010 Manuel Lemos, Tomas V.V.Cox,
|
||||
* Stig. S. Bakken, Lukas Smith, Igor Feghali
|
||||
* All rights reserved.
|
||||
*
|
||||
* MDB2_Schema enables users to maintain RDBMS independant schema files
|
||||
* in XML that can be used to manipulate both data and database schemas
|
||||
* This LICENSE is in the BSD license style.
|
||||
*
|
||||
* 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,
|
||||
* Lukas Smith, Igor Feghali nor the names of his 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
|
||||
* REGENTS 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.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Database
|
||||
* @package MDB2_Schema
|
||||
* @author Christian Weiske <cweiske@php.net>
|
||||
* @license BSD http://www.opensource.org/licenses/bsd-license.php
|
||||
* @version SVN: $Id$
|
||||
* @link http://pear.php.net/packages/MDB2_Schema
|
||||
*/
|
||||
|
||||
/**
|
||||
* To be implemented yet
|
||||
*
|
||||
* @category Database
|
||||
* @package MDB2_Schema
|
||||
* @author Christian Weiske <cweiske@php.net>
|
||||
* @license BSD http://www.opensource.org/licenses/bsd-license.php
|
||||
* @link http://pear.php.net/packages/MDB2_Schema
|
||||
*/
|
||||
class MDB2_Schema_Tool_ParameterException extends Exception
|
||||
{
|
||||
}
|
||||
Vendored
+1026
File diff suppressed because it is too large
Load Diff
Vendored
+602
@@ -0,0 +1,602 @@
|
||||
<?php /* vim: se et ts=4 sw=4 sts=4 fdm=marker tw=80: */
|
||||
/**
|
||||
* Copyright (c) 1998-2010 Manuel Lemos, Tomas V.V.Cox,
|
||||
* Stig. S. Bakken, Lukas Smith, Igor Feghali
|
||||
* All rights reserved.
|
||||
*
|
||||
* MDB2_Schema enables users to maintain RDBMS independant schema files
|
||||
* in XML that can be used to manipulate both data and database schemas
|
||||
* This LICENSE is in the BSD license style.
|
||||
*
|
||||
* 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 Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,
|
||||
* Lukas Smith, Igor Feghali nor the names of his 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
|
||||
* REGENTS 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.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Database
|
||||
* @package MDB2_Schema
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
* @author Igor Feghali <ifeghali@php.net>
|
||||
* @license BSD http://www.opensource.org/licenses/bsd-license.php
|
||||
* @version SVN: $Id$
|
||||
* @link http://pear.php.net/packages/MDB2_Schema
|
||||
*/
|
||||
|
||||
/**
|
||||
* Writes an XML schema file
|
||||
*
|
||||
* @category Database
|
||||
* @package MDB2_Schema
|
||||
* @author Lukas Smith <smith@pooteeweet.org>
|
||||
* @license BSD http://www.opensource.org/licenses/bsd-license.php
|
||||
* @link http://pear.php.net/packages/MDB2_Schema
|
||||
*/
|
||||
class MDB2_Schema_Writer
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
var $valid_types = array();
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* PHP 5 constructor
|
||||
*
|
||||
* @param array $valid_types information of all valid fields
|
||||
* types
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function __construct($valid_types = array())
|
||||
{
|
||||
$this->valid_types = $valid_types;
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP 4 compatible constructor
|
||||
*
|
||||
* @param array $valid_types information of all valid fields
|
||||
* types
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function MDB2_Schema_Writer($valid_types = array())
|
||||
{
|
||||
$this->__construct($valid_types);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ raiseError()
|
||||
|
||||
/**
|
||||
* This method is used to communicate an error and invoke error
|
||||
* callbacks etc. Basically a wrapper for PEAR::raiseError
|
||||
* without the message string.
|
||||
*
|
||||
* @param int|PEAR_Error $code integer error code or and PEAR_Error
|
||||
* instance
|
||||
* @param int $mode error mode, see PEAR_Error docs error
|
||||
* level (E_USER_NOTICE etc). If error mode
|
||||
* is PEAR_ERROR_CALLBACK, this is the
|
||||
* callback function, either as a function
|
||||
* name, or as an array of an object and
|
||||
* method name. For other error modes this
|
||||
* parameter is ignored.
|
||||
* @param string $options Extra debug information. Defaults to the
|
||||
* last query and native error code.
|
||||
* @param string $userinfo User-friendly error message
|
||||
*
|
||||
* @return object a PEAR error object
|
||||
* @access public
|
||||
* @see PEAR_Error
|
||||
*/
|
||||
function &raiseError($code = null, $mode = null, $options = null, $userinfo = null)
|
||||
{
|
||||
$error = MDB2_Schema::raiseError($code, $mode, $options, $userinfo);
|
||||
return $error;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _escapeSpecialChars()
|
||||
|
||||
/**
|
||||
* add escapecharacters to all special characters in a string
|
||||
*
|
||||
* @param string $string string that should be escaped
|
||||
*
|
||||
* @return string escaped string
|
||||
* @access protected
|
||||
*/
|
||||
function _escapeSpecialChars($string)
|
||||
{
|
||||
if (!is_string($string)) {
|
||||
$string = strval($string);
|
||||
}
|
||||
|
||||
$escaped = '';
|
||||
for ($char = 0, $count = strlen($string); $char < $count; $char++) {
|
||||
switch ($string[$char]) {
|
||||
case '&':
|
||||
$escaped .= '&';
|
||||
break;
|
||||
case '>':
|
||||
$escaped .= '>';
|
||||
break;
|
||||
case '<':
|
||||
$escaped .= '<';
|
||||
break;
|
||||
case '"':
|
||||
$escaped .= '"';
|
||||
break;
|
||||
case '\'':
|
||||
$escaped .= ''';
|
||||
break;
|
||||
default:
|
||||
$code = ord($string[$char]);
|
||||
if ($code < 32 || $code > 127) {
|
||||
$escaped .= "&#$code;";
|
||||
} else {
|
||||
$escaped .= $string[$char];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $escaped;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _dumpBoolean()
|
||||
|
||||
/**
|
||||
* dump the structure of a sequence
|
||||
*
|
||||
* @param string $boolean boolean value or variable definition
|
||||
*
|
||||
* @return string with xml boolea definition
|
||||
* @access private
|
||||
*/
|
||||
function _dumpBoolean($boolean)
|
||||
{
|
||||
if (is_string($boolean)) {
|
||||
if ($boolean !== 'true' || $boolean !== 'false'
|
||||
|| preg_match('/<variable>.*</variable>/', $boolean)
|
||||
) {
|
||||
return $boolean;
|
||||
}
|
||||
}
|
||||
return $boolean ? 'true' : 'false';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dumpSequence()
|
||||
|
||||
/**
|
||||
* dump the structure of a sequence
|
||||
*
|
||||
* @param string $sequence_definition sequence definition
|
||||
* @param string $sequence_name sequence name
|
||||
* @param string $eol end of line characters
|
||||
* @param integer $dump determines what data to dump
|
||||
* MDB2_SCHEMA_DUMP_ALL : the entire db
|
||||
* MDB2_SCHEMA_DUMP_STRUCTURE : only the structure of the db
|
||||
* MDB2_SCHEMA_DUMP_CONTENT : only the content of the db
|
||||
*
|
||||
* @return mixed string xml sequence definition on success, or a error object
|
||||
* @access public
|
||||
*/
|
||||
function dumpSequence($sequence_definition, $sequence_name, $eol, $dump = MDB2_SCHEMA_DUMP_ALL)
|
||||
{
|
||||
$buffer = "$eol <sequence>$eol <name>$sequence_name</name>$eol";
|
||||
if ($dump == MDB2_SCHEMA_DUMP_ALL || $dump == MDB2_SCHEMA_DUMP_CONTENT) {
|
||||
if (!empty($sequence_definition['start'])) {
|
||||
$start = $sequence_definition['start'];
|
||||
$buffer .= " <start>$start</start>$eol";
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($sequence_definition['on'])) {
|
||||
$buffer .= " <on>$eol";
|
||||
$buffer .= " <table>".$sequence_definition['on']['table'];
|
||||
$buffer .= "</table>$eol <field>".$sequence_definition['on']['field'];
|
||||
$buffer .= "</field>$eol </on>$eol";
|
||||
}
|
||||
$buffer .= " </sequence>$eol";
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ dumpDatabase()
|
||||
|
||||
/**
|
||||
* Dump a previously parsed database structure in the Metabase schema
|
||||
* XML based format suitable for the Metabase parser. This function
|
||||
* may optionally dump the database definition with initialization
|
||||
* commands that specify the data that is currently present in the tables.
|
||||
*
|
||||
* @param array $database_definition unknown
|
||||
* @param array $arguments associative array that takes pairs of tag
|
||||
* names and values that define dump options.
|
||||
* array (
|
||||
* 'output_mode' => String
|
||||
* 'file' : dump into a file
|
||||
* default: dump using a function
|
||||
* 'output' => String
|
||||
* depending on the 'Output_Mode'
|
||||
* name of the file
|
||||
* name of the function
|
||||
* 'end_of_line' => String
|
||||
* end of line delimiter that should be used
|
||||
* default: "\n"
|
||||
* );
|
||||
* @param integer $dump determines what data to dump
|
||||
* MDB2_SCHEMA_DUMP_ALL : the entire db
|
||||
* MDB2_SCHEMA_DUMP_STRUCTURE : only the structure of the db
|
||||
* MDB2_SCHEMA_DUMP_CONTENT : only the content of the db
|
||||
*
|
||||
* @return mixed MDB2_OK on success, or a error object
|
||||
* @access public
|
||||
*/
|
||||
function dumpDatabase($database_definition, $arguments, $dump = MDB2_SCHEMA_DUMP_ALL)
|
||||
{
|
||||
if (!empty($arguments['output'])) {
|
||||
if (!empty($arguments['output_mode']) && $arguments['output_mode'] == 'file') {
|
||||
$fp = fopen($arguments['output'], 'w');
|
||||
if ($fp === false) {
|
||||
return $this->raiseError(MDB2_SCHEMA_ERROR_WRITER, null, null,
|
||||
'it was not possible to open output file');
|
||||
}
|
||||
|
||||
$output = false;
|
||||
} elseif (is_callable($arguments['output'])) {
|
||||
$output = $arguments['output'];
|
||||
} else {
|
||||
return $this->raiseError(MDB2_SCHEMA_ERROR_WRITER, null, null,
|
||||
'no valid output function specified');
|
||||
}
|
||||
} else {
|
||||
return $this->raiseError(MDB2_SCHEMA_ERROR_WRITER, null, null,
|
||||
'no output method specified');
|
||||
}
|
||||
|
||||
$eol = isset($arguments['end_of_line']) ? $arguments['end_of_line'] : "\n";
|
||||
|
||||
$sequences = array();
|
||||
if (!empty($database_definition['sequences'])
|
||||
&& is_array($database_definition['sequences'])
|
||||
) {
|
||||
foreach ($database_definition['sequences'] as $sequence_name => $sequence) {
|
||||
$table = !empty($sequence['on']) ? $sequence['on']['table'] :'';
|
||||
|
||||
$sequences[$table][] = $sequence_name;
|
||||
}
|
||||
}
|
||||
|
||||
$buffer = '<?xml version="1.0" encoding="ISO-8859-1" ?>'.$eol;
|
||||
$buffer .= "<database>$eol$eol <name>".$database_definition['name']."</name>";
|
||||
$buffer .= "$eol <create>".$this->_dumpBoolean($database_definition['create'])."</create>";
|
||||
$buffer .= "$eol <overwrite>".$this->_dumpBoolean($database_definition['overwrite'])."</overwrite>$eol";
|
||||
$buffer .= "$eol <charset>".$database_definition['charset']."</charset>$eol";
|
||||
|
||||
if ($output) {
|
||||
call_user_func($output, $buffer);
|
||||
} else {
|
||||
fwrite($fp, $buffer);
|
||||
}
|
||||
|
||||
if (!empty($database_definition['tables']) && is_array($database_definition['tables'])) {
|
||||
foreach ($database_definition['tables'] as $table_name => $table) {
|
||||
$buffer = "$eol <table>$eol$eol <name>$table_name</name>$eol";
|
||||
if ($dump == MDB2_SCHEMA_DUMP_ALL || $dump == MDB2_SCHEMA_DUMP_STRUCTURE) {
|
||||
$buffer .= "$eol <declaration>$eol";
|
||||
if (!empty($table['fields']) && is_array($table['fields'])) {
|
||||
foreach ($table['fields'] as $field_name => $field) {
|
||||
if (empty($field['type'])) {
|
||||
return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE, null, null,
|
||||
'it was not specified the type of the field "'.
|
||||
$field_name.'" of the table "'.$table_name.'"');
|
||||
}
|
||||
if (!empty($this->valid_types) && !array_key_exists($field['type'], $this->valid_types)) {
|
||||
return $this->raiseError(MDB2_SCHEMA_ERROR_UNSUPPORTED, null, null,
|
||||
'type "'.$field['type'].'" is not yet supported');
|
||||
}
|
||||
$buffer .= "$eol <field>$eol <name>$field_name</name>$eol <type>";
|
||||
$buffer .= $field['type']."</type>$eol";
|
||||
if (!empty($field['fixed']) && $field['type'] === 'text') {
|
||||
$buffer .= " <fixed>".$this->_dumpBoolean($field['fixed'])."</fixed>$eol";
|
||||
}
|
||||
if (array_key_exists('default', $field)
|
||||
&& $field['type'] !== 'clob' && $field['type'] !== 'blob'
|
||||
) {
|
||||
$buffer .= ' <default>'.$this->_escapeSpecialChars($field['default'])."</default>$eol";
|
||||
}
|
||||
if (!empty($field['notnull'])) {
|
||||
$buffer .= " <notnull>".$this->_dumpBoolean($field['notnull'])."</notnull>$eol";
|
||||
} else {
|
||||
$buffer .= " <notnull>false</notnull>$eol";
|
||||
}
|
||||
if (!empty($field['autoincrement'])) {
|
||||
$buffer .= " <autoincrement>" . $field['autoincrement'] ."</autoincrement>$eol";
|
||||
}
|
||||
if (!empty($field['unsigned'])) {
|
||||
$buffer .= " <unsigned>".$this->_dumpBoolean($field['unsigned'])."</unsigned>$eol";
|
||||
}
|
||||
if (!empty($field['length'])) {
|
||||
$buffer .= ' <length>'.$field['length']."</length>$eol";
|
||||
}
|
||||
$buffer .= " </field>$eol";
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($table['indexes']) && is_array($table['indexes'])) {
|
||||
foreach ($table['indexes'] as $index_name => $index) {
|
||||
if (strtolower($index_name) === 'primary') {
|
||||
$index_name = $table_name . '_pKey';
|
||||
}
|
||||
$buffer .= "$eol <index>$eol <name>$index_name</name>$eol";
|
||||
if (!empty($index['unique'])) {
|
||||
$buffer .= " <unique>".$this->_dumpBoolean($index['unique'])."</unique>$eol";
|
||||
}
|
||||
|
||||
if (!empty($index['primary'])) {
|
||||
$buffer .= " <primary>".$this->_dumpBoolean($index['primary'])."</primary>$eol";
|
||||
}
|
||||
|
||||
foreach ($index['fields'] as $field_name => $field) {
|
||||
$buffer .= " <field>$eol <name>$field_name</name>$eol";
|
||||
if (!empty($field) && is_array($field)) {
|
||||
$buffer .= ' <sorting>'.$field['sorting']."</sorting>$eol";
|
||||
}
|
||||
$buffer .= " </field>$eol";
|
||||
}
|
||||
$buffer .= " </index>$eol";
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($table['constraints']) && is_array($table['constraints'])) {
|
||||
foreach ($table['constraints'] as $constraint_name => $constraint) {
|
||||
$buffer .= "$eol <foreign>$eol <name>$constraint_name</name>$eol";
|
||||
if (empty($constraint['fields']) || !is_array($constraint['fields'])) {
|
||||
return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE, null, null,
|
||||
'it was not specified a field for the foreign key "'.
|
||||
$constraint_name.'" of the table "'.$table_name.'"');
|
||||
}
|
||||
if (!is_array($constraint['references']) || empty($constraint['references']['table'])) {
|
||||
return $this->raiseError(MDB2_SCHEMA_ERROR_VALIDATE, null, null,
|
||||
'it was not specified the referenced table of the foreign key "'.
|
||||
$constraint_name.'" of the table "'.$table_name.'"');
|
||||
}
|
||||
if (!empty($constraint['match'])) {
|
||||
$buffer .= " <match>".$constraint['match']."</match>$eol";
|
||||
}
|
||||
if (!empty($constraint['ondelete'])) {
|
||||
$buffer .= " <ondelete>".$constraint['ondelete']."</ondelete>$eol";
|
||||
}
|
||||
if (!empty($constraint['onupdate'])) {
|
||||
$buffer .= " <onupdate>".$constraint['onupdate']."</onupdate>$eol";
|
||||
}
|
||||
if (!empty($constraint['deferrable'])) {
|
||||
$buffer .= " <deferrable>".$constraint['deferrable']."</deferrable>$eol";
|
||||
}
|
||||
if (!empty($constraint['initiallydeferred'])) {
|
||||
$buffer .= " <initiallydeferred>".$constraint['initiallydeferred']."</initiallydeferred>$eol";
|
||||
}
|
||||
foreach ($constraint['fields'] as $field_name => $field) {
|
||||
$buffer .= " <field>$field_name</field>$eol";
|
||||
}
|
||||
$buffer .= " <references>$eol <table>".$constraint['references']['table']."</table>$eol";
|
||||
foreach ($constraint['references']['fields'] as $field_name => $field) {
|
||||
$buffer .= " <field>$field_name</field>$eol";
|
||||
}
|
||||
$buffer .= " </references>$eol";
|
||||
|
||||
$buffer .= " </foreign>$eol";
|
||||
}
|
||||
}
|
||||
|
||||
$buffer .= "$eol </declaration>$eol";
|
||||
}
|
||||
|
||||
if ($output) {
|
||||
call_user_func($output, $buffer);
|
||||
} else {
|
||||
fwrite($fp, $buffer);
|
||||
}
|
||||
|
||||
$buffer = '';
|
||||
if ($dump == MDB2_SCHEMA_DUMP_ALL || $dump == MDB2_SCHEMA_DUMP_CONTENT) {
|
||||
if (!empty($table['initialization']) && is_array($table['initialization'])) {
|
||||
$buffer = "$eol <initialization>$eol";
|
||||
foreach ($table['initialization'] as $instruction) {
|
||||
switch ($instruction['type']) {
|
||||
case 'insert':
|
||||
$buffer .= "$eol <insert>$eol";
|
||||
foreach ($instruction['data']['field'] as $field) {
|
||||
$field_name = $field['name'];
|
||||
|
||||
$buffer .= "$eol <field>$eol <name>$field_name</name>$eol";
|
||||
$buffer .= $this->writeExpression($field['group'], 5, $arguments);
|
||||
$buffer .= " </field>$eol";
|
||||
}
|
||||
$buffer .= "$eol </insert>$eol";
|
||||
break;
|
||||
case 'update':
|
||||
$buffer .= "$eol <update>$eol";
|
||||
foreach ($instruction['data']['field'] as $field) {
|
||||
$field_name = $field['name'];
|
||||
|
||||
$buffer .= "$eol <field>$eol <name>$field_name</name>$eol";
|
||||
$buffer .= $this->writeExpression($field['group'], 5, $arguments);
|
||||
$buffer .= " </field>$eol";
|
||||
}
|
||||
|
||||
if (!empty($instruction['data']['where'])
|
||||
&& is_array($instruction['data']['where'])
|
||||
) {
|
||||
$buffer .= " <where>$eol";
|
||||
$buffer .= $this->writeExpression($instruction['data']['where'], 5, $arguments);
|
||||
$buffer .= " </where>$eol";
|
||||
}
|
||||
|
||||
$buffer .= "$eol </update>$eol";
|
||||
break;
|
||||
case 'delete':
|
||||
$buffer .= "$eol <delete>$eol$eol";
|
||||
if (!empty($instruction['data']['where'])
|
||||
&& is_array($instruction['data']['where'])
|
||||
) {
|
||||
$buffer .= " <where>$eol";
|
||||
$buffer .= $this->writeExpression($instruction['data']['where'], 5, $arguments);
|
||||
$buffer .= " </where>$eol";
|
||||
}
|
||||
$buffer .= "$eol </delete>$eol";
|
||||
break;
|
||||
}
|
||||
}
|
||||
$buffer .= "$eol </initialization>$eol";
|
||||
}
|
||||
}
|
||||
$buffer .= "$eol </table>$eol";
|
||||
if ($output) {
|
||||
call_user_func($output, $buffer);
|
||||
} else {
|
||||
fwrite($fp, $buffer);
|
||||
}
|
||||
|
||||
if (isset($sequences[$table_name])) {
|
||||
foreach ($sequences[$table_name] as $sequence) {
|
||||
$result = $this->dumpSequence($database_definition['sequences'][$sequence],
|
||||
$sequence, $eol, $dump);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
if ($output) {
|
||||
call_user_func($output, $result);
|
||||
} else {
|
||||
fwrite($fp, $result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($sequences[''])) {
|
||||
foreach ($sequences[''] as $sequence) {
|
||||
$result = $this->dumpSequence($database_definition['sequences'][$sequence],
|
||||
$sequence, $eol, $dump);
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
if ($output) {
|
||||
call_user_func($output, $result);
|
||||
} else {
|
||||
fwrite($fp, $result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$buffer = "$eol</database>$eol";
|
||||
if ($output) {
|
||||
call_user_func($output, $buffer);
|
||||
} else {
|
||||
fwrite($fp, $buffer);
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ writeExpression()
|
||||
|
||||
/**
|
||||
* Dumps the structure of an element. Elements can be value, column,
|
||||
* function or expression.
|
||||
*
|
||||
* @param array $element multi dimensional array that represents the parsed element
|
||||
* of a DML instruction.
|
||||
* @param integer $offset base indentation width
|
||||
* @param array $arguments associative array that takes pairs of tag
|
||||
* names and values that define dump options.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @access public
|
||||
* @see MDB2_Schema_Writer::dumpDatabase()
|
||||
*/
|
||||
function writeExpression($element, $offset = 0, $arguments = null)
|
||||
{
|
||||
$eol = isset($arguments['end_of_line']) ? $arguments['end_of_line'] : "\n";
|
||||
$str = '';
|
||||
|
||||
$indent = str_repeat(' ', $offset);
|
||||
$noffset = $offset + 1;
|
||||
|
||||
switch ($element['type']) {
|
||||
case 'value':
|
||||
$str .= "$indent<value>".$this->_escapeSpecialChars($element['data'])."</value>$eol";
|
||||
break;
|
||||
case 'column':
|
||||
$str .= "$indent<column>".$this->_escapeSpecialChars($element['data'])."</column>$eol";
|
||||
break;
|
||||
case 'function':
|
||||
$str .= "$indent<function>$eol$indent <name>".$this->_escapeSpecialChars($element['data']['name'])."</name>$eol";
|
||||
|
||||
if (!empty($element['data']['arguments'])
|
||||
&& is_array($element['data']['arguments'])
|
||||
) {
|
||||
foreach ($element['data']['arguments'] as $v) {
|
||||
$str .= $this->writeExpression($v, $noffset, $arguments);
|
||||
}
|
||||
}
|
||||
|
||||
$str .= "$indent</function>$eol";
|
||||
break;
|
||||
case 'expression':
|
||||
$str .= "$indent<expression>$eol";
|
||||
$str .= $this->writeExpression($element['data']['operants'][0], $noffset, $arguments);
|
||||
$str .= "$indent <operator>".$element['data']['operator']."</operator>$eol";
|
||||
$str .= $this->writeExpression($element['data']['operants'][1], $noffset, $arguments);
|
||||
$str .= "$indent</expression>$eol";
|
||||
break;
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
Vendored
+338
@@ -0,0 +1,338 @@
|
||||
<?php
|
||||
/**
|
||||
* The OS_Guess class
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* @category pear
|
||||
* @package PEAR
|
||||
* @author Stig Bakken <ssb@php.net>
|
||||
* @author Gregory Beaver <cellog@php.net>
|
||||
* @copyright 1997-2009 The Authors
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: Guess.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||
* @link http://pear.php.net/package/PEAR
|
||||
* @since File available since PEAR 0.1
|
||||
*/
|
||||
|
||||
// {{{ uname examples
|
||||
|
||||
// php_uname() without args returns the same as 'uname -a', or a PHP-custom
|
||||
// string for Windows.
|
||||
// PHP versions prior to 4.3 return the uname of the host where PHP was built,
|
||||
// as of 4.3 it returns the uname of the host running the PHP code.
|
||||
//
|
||||
// PC RedHat Linux 7.1:
|
||||
// Linux host.example.com 2.4.2-2 #1 Sun Apr 8 20:41:30 EDT 2001 i686 unknown
|
||||
//
|
||||
// PC Debian Potato:
|
||||
// Linux host 2.4.17 #2 SMP Tue Feb 12 15:10:04 CET 2002 i686 unknown
|
||||
//
|
||||
// PC FreeBSD 3.3:
|
||||
// FreeBSD host.example.com 3.3-STABLE FreeBSD 3.3-STABLE #0: Mon Feb 21 00:42:31 CET 2000 root@example.com:/usr/src/sys/compile/CONFIG i386
|
||||
//
|
||||
// PC FreeBSD 4.3:
|
||||
// FreeBSD host.example.com 4.3-RELEASE FreeBSD 4.3-RELEASE #1: Mon Jun 25 11:19:43 EDT 2001 root@example.com:/usr/src/sys/compile/CONFIG i386
|
||||
//
|
||||
// PC FreeBSD 4.5:
|
||||
// FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb 6 23:59:23 CET 2002 root@example.com:/usr/src/sys/compile/CONFIG i386
|
||||
//
|
||||
// PC FreeBSD 4.5 w/uname from GNU shellutils:
|
||||
// FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb i386 unknown
|
||||
//
|
||||
// HP 9000/712 HP-UX 10:
|
||||
// HP-UX iq B.10.10 A 9000/712 2008429113 two-user license
|
||||
//
|
||||
// HP 9000/712 HP-UX 10 w/uname from GNU shellutils:
|
||||
// HP-UX host B.10.10 A 9000/712 unknown
|
||||
//
|
||||
// IBM RS6000/550 AIX 4.3:
|
||||
// AIX host 3 4 000003531C00
|
||||
//
|
||||
// AIX 4.3 w/uname from GNU shellutils:
|
||||
// AIX host 3 4 000003531C00 unknown
|
||||
//
|
||||
// SGI Onyx IRIX 6.5 w/uname from GNU shellutils:
|
||||
// IRIX64 host 6.5 01091820 IP19 mips
|
||||
//
|
||||
// SGI Onyx IRIX 6.5:
|
||||
// IRIX64 host 6.5 01091820 IP19
|
||||
//
|
||||
// SparcStation 20 Solaris 8 w/uname from GNU shellutils:
|
||||
// SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc
|
||||
//
|
||||
// SparcStation 20 Solaris 8:
|
||||
// SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc SUNW,SPARCstation-20
|
||||
//
|
||||
// Mac OS X (Darwin)
|
||||
// Darwin home-eden.local 7.5.0 Darwin Kernel Version 7.5.0: Thu Aug 5 19:26:16 PDT 2004; root:xnu/xnu-517.7.21.obj~3/RELEASE_PPC Power Macintosh
|
||||
//
|
||||
// Mac OS X early versions
|
||||
//
|
||||
|
||||
// }}}
|
||||
|
||||
/* TODO:
|
||||
* - define endianness, to allow matchSignature("bigend") etc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieves information about the current operating system
|
||||
*
|
||||
* This class uses php_uname() to grok information about the current OS
|
||||
*
|
||||
* @category pear
|
||||
* @package PEAR
|
||||
* @author Stig Bakken <ssb@php.net>
|
||||
* @author Gregory Beaver <cellog@php.net>
|
||||
* @copyright 1997-2009 The Authors
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version Release: 1.9.4
|
||||
* @link http://pear.php.net/package/PEAR
|
||||
* @since Class available since Release 0.1
|
||||
*/
|
||||
class OS_Guess
|
||||
{
|
||||
var $sysname;
|
||||
var $nodename;
|
||||
var $cpu;
|
||||
var $release;
|
||||
var $extra;
|
||||
|
||||
function OS_Guess($uname = null)
|
||||
{
|
||||
list($this->sysname,
|
||||
$this->release,
|
||||
$this->cpu,
|
||||
$this->extra,
|
||||
$this->nodename) = $this->parseSignature($uname);
|
||||
}
|
||||
|
||||
function parseSignature($uname = null)
|
||||
{
|
||||
static $sysmap = array(
|
||||
'HP-UX' => 'hpux',
|
||||
'IRIX64' => 'irix',
|
||||
);
|
||||
static $cpumap = array(
|
||||
'i586' => 'i386',
|
||||
'i686' => 'i386',
|
||||
'ppc' => 'powerpc',
|
||||
);
|
||||
if ($uname === null) {
|
||||
$uname = php_uname();
|
||||
}
|
||||
$parts = preg_split('/\s+/', trim($uname));
|
||||
$n = count($parts);
|
||||
|
||||
$release = $machine = $cpu = '';
|
||||
$sysname = $parts[0];
|
||||
$nodename = $parts[1];
|
||||
$cpu = $parts[$n-1];
|
||||
$extra = '';
|
||||
if ($cpu == 'unknown') {
|
||||
$cpu = $parts[$n - 2];
|
||||
}
|
||||
|
||||
switch ($sysname) {
|
||||
case 'AIX' :
|
||||
$release = "$parts[3].$parts[2]";
|
||||
break;
|
||||
case 'Windows' :
|
||||
switch ($parts[1]) {
|
||||
case '95/98':
|
||||
$release = '9x';
|
||||
break;
|
||||
default:
|
||||
$release = $parts[1];
|
||||
break;
|
||||
}
|
||||
$cpu = 'i386';
|
||||
break;
|
||||
case 'Linux' :
|
||||
$extra = $this->_detectGlibcVersion();
|
||||
// use only the first two digits from the kernel version
|
||||
$release = preg_replace('/^([0-9]+\.[0-9]+).*/', '\1', $parts[2]);
|
||||
break;
|
||||
case 'Mac' :
|
||||
$sysname = 'darwin';
|
||||
$nodename = $parts[2];
|
||||
$release = $parts[3];
|
||||
if ($cpu == 'Macintosh') {
|
||||
if ($parts[$n - 2] == 'Power') {
|
||||
$cpu = 'powerpc';
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'Darwin' :
|
||||
if ($cpu == 'Macintosh') {
|
||||
if ($parts[$n - 2] == 'Power') {
|
||||
$cpu = 'powerpc';
|
||||
}
|
||||
}
|
||||
$release = preg_replace('/^([0-9]+\.[0-9]+).*/', '\1', $parts[2]);
|
||||
break;
|
||||
default:
|
||||
$release = preg_replace('/-.*/', '', $parts[2]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (isset($sysmap[$sysname])) {
|
||||
$sysname = $sysmap[$sysname];
|
||||
} else {
|
||||
$sysname = strtolower($sysname);
|
||||
}
|
||||
if (isset($cpumap[$cpu])) {
|
||||
$cpu = $cpumap[$cpu];
|
||||
}
|
||||
return array($sysname, $release, $cpu, $extra, $nodename);
|
||||
}
|
||||
|
||||
function _detectGlibcVersion()
|
||||
{
|
||||
static $glibc = false;
|
||||
if ($glibc !== false) {
|
||||
return $glibc; // no need to run this multiple times
|
||||
}
|
||||
$major = $minor = 0;
|
||||
include_once "System.php";
|
||||
// Use glibc's <features.h> header file to
|
||||
// get major and minor version number:
|
||||
if (@file_exists('/usr/include/features.h') &&
|
||||
@is_readable('/usr/include/features.h')) {
|
||||
if (!@file_exists('/usr/bin/cpp') || !@is_executable('/usr/bin/cpp')) {
|
||||
$features_file = fopen('/usr/include/features.h', 'rb');
|
||||
while (!feof($features_file)) {
|
||||
$line = fgets($features_file, 8192);
|
||||
if (!$line || (strpos($line, '#define') === false)) {
|
||||
continue;
|
||||
}
|
||||
if (strpos($line, '__GLIBC__')) {
|
||||
// major version number #define __GLIBC__ version
|
||||
$line = preg_split('/\s+/', $line);
|
||||
$glibc_major = trim($line[2]);
|
||||
if (isset($glibc_minor)) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strpos($line, '__GLIBC_MINOR__')) {
|
||||
// got the minor version number
|
||||
// #define __GLIBC_MINOR__ version
|
||||
$line = preg_split('/\s+/', $line);
|
||||
$glibc_minor = trim($line[2]);
|
||||
if (isset($glibc_major)) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
fclose($features_file);
|
||||
if (!isset($glibc_major) || !isset($glibc_minor)) {
|
||||
return $glibc = '';
|
||||
}
|
||||
return $glibc = 'glibc' . trim($glibc_major) . "." . trim($glibc_minor) ;
|
||||
} // no cpp
|
||||
|
||||
$tmpfile = System::mktemp("glibctest");
|
||||
$fp = fopen($tmpfile, "w");
|
||||
fwrite($fp, "#include <features.h>\n__GLIBC__ __GLIBC_MINOR__\n");
|
||||
fclose($fp);
|
||||
$cpp = popen("/usr/bin/cpp $tmpfile", "r");
|
||||
while ($line = fgets($cpp, 1024)) {
|
||||
if ($line{0} == '#' || trim($line) == '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (list($major, $minor) = explode(' ', trim($line))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
pclose($cpp);
|
||||
unlink($tmpfile);
|
||||
} // features.h
|
||||
|
||||
if (!($major && $minor) && @is_link('/lib/libc.so.6')) {
|
||||
// Let's try reading the libc.so.6 symlink
|
||||
if (preg_match('/^libc-(.*)\.so$/', basename(readlink('/lib/libc.so.6')), $matches)) {
|
||||
list($major, $minor) = explode('.', $matches[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!($major && $minor)) {
|
||||
return $glibc = '';
|
||||
}
|
||||
|
||||
return $glibc = "glibc{$major}.{$minor}";
|
||||
}
|
||||
|
||||
function getSignature()
|
||||
{
|
||||
if (empty($this->extra)) {
|
||||
return "{$this->sysname}-{$this->release}-{$this->cpu}";
|
||||
}
|
||||
return "{$this->sysname}-{$this->release}-{$this->cpu}-{$this->extra}";
|
||||
}
|
||||
|
||||
function getSysname()
|
||||
{
|
||||
return $this->sysname;
|
||||
}
|
||||
|
||||
function getNodename()
|
||||
{
|
||||
return $this->nodename;
|
||||
}
|
||||
|
||||
function getCpu()
|
||||
{
|
||||
return $this->cpu;
|
||||
}
|
||||
|
||||
function getRelease()
|
||||
{
|
||||
return $this->release;
|
||||
}
|
||||
|
||||
function getExtra()
|
||||
{
|
||||
return $this->extra;
|
||||
}
|
||||
|
||||
function matchSignature($match)
|
||||
{
|
||||
$fragments = is_array($match) ? $match : explode('-', $match);
|
||||
$n = count($fragments);
|
||||
$matches = 0;
|
||||
if ($n > 0) {
|
||||
$matches += $this->_matchFragment($fragments[0], $this->sysname);
|
||||
}
|
||||
if ($n > 1) {
|
||||
$matches += $this->_matchFragment($fragments[1], $this->release);
|
||||
}
|
||||
if ($n > 2) {
|
||||
$matches += $this->_matchFragment($fragments[2], $this->cpu);
|
||||
}
|
||||
if ($n > 3) {
|
||||
$matches += $this->_matchFragment($fragments[3], $this->extra);
|
||||
}
|
||||
return ($matches == $n);
|
||||
}
|
||||
|
||||
function _matchFragment($fragment, $value)
|
||||
{
|
||||
if (strcspn($fragment, '*?') < strlen($fragment)) {
|
||||
$reg = '/^' . str_replace(array('*', '?', '/'), array('.*', '.', '\\/'), $fragment) . '\\z/';
|
||||
return preg_match($reg, $value);
|
||||
}
|
||||
return ($fragment == '*' || !strcasecmp($fragment, $value));
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Local Variables:
|
||||
* indent-tabs-mode: nil
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
Vendored
+27
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 1997-2009,
|
||||
Stig Bakken <ssb@php.net>,
|
||||
Gregory Beaver <cellog@php.net>,
|
||||
Helgi Þormar Þorbjörnsson <helgi@php.net>,
|
||||
Tomas V.V.Cox <cox@idecnet.com>,
|
||||
Martin Jansen <mj@php.net>.
|
||||
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.
|
||||
|
||||
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.
|
||||
Vendored
+1063
File diff suppressed because it is too large
Load Diff
Vendored
+218
@@ -0,0 +1,218 @@
|
||||
<?php
|
||||
/**
|
||||
* Class auto-loader
|
||||
*
|
||||
* PHP versions 4
|
||||
|
||||
*
|
||||
* @category pear
|
||||
* @package PEAR
|
||||
* @author Stig Bakken <ssb@php.net>
|
||||
* @copyright 1997-2009 The Authors
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: Autoloader.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||
* @link http://pear.php.net/manual/en/core.ppm.php#core.ppm.pear-autoloader
|
||||
* @since File available since Release 0.1
|
||||
* @deprecated File deprecated in Release 1.4.0a1
|
||||
*/
|
||||
|
||||
// /* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||
|
||||
if (!extension_loaded("overload")) {
|
||||
// die hard without ext/overload
|
||||
die("Rebuild PHP with the `overload' extension to use PEAR_Autoloader");
|
||||
}
|
||||
|
||||
/**
|
||||
* Include for PEAR_Error and PEAR classes
|
||||
*/
|
||||
require_once "PEAR.php";
|
||||
|
||||
/**
|
||||
* This class is for objects where you want to separate the code for
|
||||
* some methods into separate classes. This is useful if you have a
|
||||
* class with not-frequently-used methods that contain lots of code
|
||||
* that you would like to avoid always parsing.
|
||||
*
|
||||
* The PEAR_Autoloader class provides autoloading and aggregation.
|
||||
* The autoloading lets you set up in which classes the separated
|
||||
* methods are found. Aggregation is the technique used to import new
|
||||
* methods, an instance of each class providing separated methods is
|
||||
* stored and called every time the aggregated method is called.
|
||||
*
|
||||
* @category pear
|
||||
* @package PEAR
|
||||
* @author Stig Bakken <ssb@php.net>
|
||||
* @copyright 1997-2009 The Authors
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version Release: 1.9.4
|
||||
* @link http://pear.php.net/manual/en/core.ppm.php#core.ppm.pear-autoloader
|
||||
* @since File available since Release 0.1
|
||||
* @deprecated File deprecated in Release 1.4.0a1
|
||||
*/
|
||||
class PEAR_Autoloader extends PEAR
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* Map of methods and classes where they are defined
|
||||
*
|
||||
* @var array
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
var $_autoload_map = array();
|
||||
|
||||
/**
|
||||
* Map of methods and aggregate objects
|
||||
*
|
||||
* @var array
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
var $_method_map = array();
|
||||
|
||||
// }}}
|
||||
// {{{ addAutoload()
|
||||
|
||||
/**
|
||||
* Add one or more autoload entries.
|
||||
*
|
||||
* @param string $method which method to autoload
|
||||
*
|
||||
* @param string $classname (optional) which class to find the method in.
|
||||
* If the $method parameter is an array, this
|
||||
* parameter may be omitted (and will be ignored
|
||||
* if not), and the $method parameter will be
|
||||
* treated as an associative array with method
|
||||
* names as keys and class names as values.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function addAutoload($method, $classname = null)
|
||||
{
|
||||
if (is_array($method)) {
|
||||
array_walk($method, create_function('$a,&$b', '$b = strtolower($b);'));
|
||||
$this->_autoload_map = array_merge($this->_autoload_map, $method);
|
||||
} else {
|
||||
$this->_autoload_map[strtolower($method)] = $classname;
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ removeAutoload()
|
||||
|
||||
/**
|
||||
* Remove an autoload entry.
|
||||
*
|
||||
* @param string $method which method to remove the autoload entry for
|
||||
*
|
||||
* @return bool TRUE if an entry was removed, FALSE if not
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function removeAutoload($method)
|
||||
{
|
||||
$method = strtolower($method);
|
||||
$ok = isset($this->_autoload_map[$method]);
|
||||
unset($this->_autoload_map[$method]);
|
||||
return $ok;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ addAggregateObject()
|
||||
|
||||
/**
|
||||
* Add an aggregate object to this object. If the specified class
|
||||
* is not defined, loading it will be attempted following PEAR's
|
||||
* file naming scheme. All the methods in the class will be
|
||||
* aggregated, except private ones (name starting with an
|
||||
* underscore) and constructors.
|
||||
*
|
||||
* @param string $classname what class to instantiate for the object.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function addAggregateObject($classname)
|
||||
{
|
||||
$classname = strtolower($classname);
|
||||
if (!class_exists($classname)) {
|
||||
$include_file = preg_replace('/[^a-z0-9]/i', '_', $classname);
|
||||
include_once $include_file;
|
||||
}
|
||||
$obj = new $classname;
|
||||
$methods = get_class_methods($classname);
|
||||
foreach ($methods as $method) {
|
||||
// don't import priviate methods and constructors
|
||||
if ($method{0} != '_' && $method != $classname) {
|
||||
$this->_method_map[$method] = $obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ removeAggregateObject()
|
||||
|
||||
/**
|
||||
* Remove an aggregate object.
|
||||
*
|
||||
* @param string $classname the class of the object to remove
|
||||
*
|
||||
* @return bool TRUE if an object was removed, FALSE if not
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function removeAggregateObject($classname)
|
||||
{
|
||||
$ok = false;
|
||||
$classname = strtolower($classname);
|
||||
reset($this->_method_map);
|
||||
while (list($method, $obj) = each($this->_method_map)) {
|
||||
if (is_a($obj, $classname)) {
|
||||
unset($this->_method_map[$method]);
|
||||
$ok = true;
|
||||
}
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ __call()
|
||||
|
||||
/**
|
||||
* Overloaded object call handler, called each time an
|
||||
* undefined/aggregated method is invoked. This method repeats
|
||||
* the call in the right aggregate object and passes on the return
|
||||
* value.
|
||||
*
|
||||
* @param string $method which method that was called
|
||||
*
|
||||
* @param string $args An array of the parameters passed in the
|
||||
* original call
|
||||
*
|
||||
* @return mixed The return value from the aggregated method, or a PEAR
|
||||
* error if the called method was unknown.
|
||||
*/
|
||||
function __call($method, $args, &$retval)
|
||||
{
|
||||
$method = strtolower($method);
|
||||
if (empty($this->_method_map[$method]) && isset($this->_autoload_map[$method])) {
|
||||
$this->addAggregateObject($this->_autoload_map[$method]);
|
||||
}
|
||||
if (isset($this->_method_map[$method])) {
|
||||
$retval = call_user_func_array(array($this->_method_map[$method], $method), $args);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
overload("PEAR_Autoloader");
|
||||
|
||||
?>
|
||||
Vendored
+489
@@ -0,0 +1,489 @@
|
||||
<?php
|
||||
/**
|
||||
* PEAR_Builder for building PHP extensions (PECL packages)
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* @category pear
|
||||
* @package PEAR
|
||||
* @author Stig Bakken <ssb@php.net>
|
||||
* @author Greg Beaver <cellog@php.net>
|
||||
* @copyright 1997-2009 The Authors
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: Builder.php 313024 2011-07-06 19:51:24Z dufuz $
|
||||
* @link http://pear.php.net/package/PEAR
|
||||
* @since File available since Release 0.1
|
||||
*
|
||||
* TODO: log output parameters in PECL command line
|
||||
* TODO: msdev path in configuration
|
||||
*/
|
||||
|
||||
/**
|
||||
* Needed for extending PEAR_Builder
|
||||
*/
|
||||
require_once 'PEAR/Common.php';
|
||||
require_once 'PEAR/PackageFile.php';
|
||||
|
||||
/**
|
||||
* Class to handle building (compiling) extensions.
|
||||
*
|
||||
* @category pear
|
||||
* @package PEAR
|
||||
* @author Stig Bakken <ssb@php.net>
|
||||
* @author Greg Beaver <cellog@php.net>
|
||||
* @copyright 1997-2009 The Authors
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version Release: 1.9.4
|
||||
* @link http://pear.php.net/package/PEAR
|
||||
* @since Class available since PHP 4.0.2
|
||||
* @see http://pear.php.net/manual/en/core.ppm.pear-builder.php
|
||||
*/
|
||||
class PEAR_Builder extends PEAR_Common
|
||||
{
|
||||
var $php_api_version = 0;
|
||||
var $zend_module_api_no = 0;
|
||||
var $zend_extension_api_no = 0;
|
||||
|
||||
var $extensions_built = array();
|
||||
|
||||
/**
|
||||
* @var string Used for reporting when it is not possible to pass function
|
||||
* via extra parameter, e.g. log, msdevCallback
|
||||
*/
|
||||
var $current_callback = null;
|
||||
|
||||
// used for msdev builds
|
||||
var $_lastline = null;
|
||||
var $_firstline = null;
|
||||
|
||||
/**
|
||||
* PEAR_Builder constructor.
|
||||
*
|
||||
* @param object $ui user interface object (instance of PEAR_Frontend_*)
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function PEAR_Builder(&$ui)
|
||||
{
|
||||
parent::PEAR_Common();
|
||||
$this->setFrontendObject($ui);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an extension from source on windows.
|
||||
* requires msdev
|
||||
*/
|
||||
function _build_win32($descfile, $callback = null)
|
||||
{
|
||||
if (is_object($descfile)) {
|
||||
$pkg = $descfile;
|
||||
$descfile = $pkg->getPackageFile();
|
||||
} else {
|
||||
$pf = &new PEAR_PackageFile($this->config, $this->debug);
|
||||
$pkg = &$pf->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL);
|
||||
if (PEAR::isError($pkg)) {
|
||||
return $pkg;
|
||||
}
|
||||
}
|
||||
$dir = dirname($descfile);
|
||||
$old_cwd = getcwd();
|
||||
|
||||
if (!file_exists($dir) || !is_dir($dir) || !chdir($dir)) {
|
||||
return $this->raiseError("could not chdir to $dir");
|
||||
}
|
||||
|
||||
// packages that were in a .tar have the packagefile in this directory
|
||||
$vdir = $pkg->getPackage() . '-' . $pkg->getVersion();
|
||||
if (file_exists($dir) && is_dir($vdir)) {
|
||||
if (!chdir($vdir)) {
|
||||
return $this->raiseError("could not chdir to " . realpath($vdir));
|
||||
}
|
||||
|
||||
$dir = getcwd();
|
||||
}
|
||||
|
||||
$this->log(2, "building in $dir");
|
||||
|
||||
$dsp = $pkg->getPackage().'.dsp';
|
||||
if (!file_exists("$dir/$dsp")) {
|
||||
return $this->raiseError("The DSP $dsp does not exist.");
|
||||
}
|
||||
// XXX TODO: make release build type configurable
|
||||
$command = 'msdev '.$dsp.' /MAKE "'.$pkg->getPackage(). ' - Release"';
|
||||
|
||||
$err = $this->_runCommand($command, array(&$this, 'msdevCallback'));
|
||||
if (PEAR::isError($err)) {
|
||||
return $err;
|
||||
}
|
||||
|
||||
// figure out the build platform and type
|
||||
$platform = 'Win32';
|
||||
$buildtype = 'Release';
|
||||
if (preg_match('/.*?'.$pkg->getPackage().'\s-\s(\w+)\s(.*?)-+/i',$this->_firstline,$matches)) {
|
||||
$platform = $matches[1];
|
||||
$buildtype = $matches[2];
|
||||
}
|
||||
|
||||
if (preg_match('/(.*)?\s-\s(\d+).*?(\d+)/', $this->_lastline, $matches)) {
|
||||
if ($matches[2]) {
|
||||
// there were errors in the build
|
||||
return $this->raiseError("There were errors during compilation.");
|
||||
}
|
||||
$out = $matches[1];
|
||||
} else {
|
||||
return $this->raiseError("Did not understand the completion status returned from msdev.exe.");
|
||||
}
|
||||
|
||||
// msdev doesn't tell us the output directory :/
|
||||
// open the dsp, find /out and use that directory
|
||||
$dsptext = join(file($dsp),'');
|
||||
|
||||
// this regex depends on the build platform and type having been
|
||||
// correctly identified above.
|
||||
$regex ='/.*?!IF\s+"\$\(CFG\)"\s+==\s+("'.
|
||||
$pkg->getPackage().'\s-\s'.
|
||||
$platform.'\s'.
|
||||
$buildtype.'").*?'.
|
||||
'\/out:"(.*?)"/is';
|
||||
|
||||
if ($dsptext && preg_match($regex, $dsptext, $matches)) {
|
||||
// what we get back is a relative path to the output file itself.
|
||||
$outfile = realpath($matches[2]);
|
||||
} else {
|
||||
return $this->raiseError("Could not retrieve output information from $dsp.");
|
||||
}
|
||||
// realpath returns false if the file doesn't exist
|
||||
if ($outfile && copy($outfile, "$dir/$out")) {
|
||||
$outfile = "$dir/$out";
|
||||
}
|
||||
|
||||
$built_files[] = array(
|
||||
'file' => "$outfile",
|
||||
'php_api' => $this->php_api_version,
|
||||
'zend_mod_api' => $this->zend_module_api_no,
|
||||
'zend_ext_api' => $this->zend_extension_api_no,
|
||||
);
|
||||
|
||||
return $built_files;
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ msdevCallback()
|
||||
function msdevCallback($what, $data)
|
||||
{
|
||||
if (!$this->_firstline)
|
||||
$this->_firstline = $data;
|
||||
$this->_lastline = $data;
|
||||
call_user_func($this->current_callback, $what, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string
|
||||
* @param string
|
||||
* @param array
|
||||
* @access private
|
||||
*/
|
||||
function _harvestInstDir($dest_prefix, $dirname, &$built_files)
|
||||
{
|
||||
$d = opendir($dirname);
|
||||
if (!$d)
|
||||
return false;
|
||||
|
||||
$ret = true;
|
||||
while (($ent = readdir($d)) !== false) {
|
||||
if ($ent{0} == '.')
|
||||
continue;
|
||||
|
||||
$full = $dirname . DIRECTORY_SEPARATOR . $ent;
|
||||
if (is_dir($full)) {
|
||||
if (!$this->_harvestInstDir(
|
||||
$dest_prefix . DIRECTORY_SEPARATOR . $ent,
|
||||
$full, $built_files)) {
|
||||
$ret = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$dest = $dest_prefix . DIRECTORY_SEPARATOR . $ent;
|
||||
$built_files[] = array(
|
||||
'file' => $full,
|
||||
'dest' => $dest,
|
||||
'php_api' => $this->php_api_version,
|
||||
'zend_mod_api' => $this->zend_module_api_no,
|
||||
'zend_ext_api' => $this->zend_extension_api_no,
|
||||
);
|
||||
}
|
||||
}
|
||||
closedir($d);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an extension from source. Runs "phpize" in the source
|
||||
* directory, but compiles in a temporary directory
|
||||
* (TMPDIR/pear-build-USER/PACKAGE-VERSION).
|
||||
*
|
||||
* @param string|PEAR_PackageFile_v* $descfile path to XML package description file, or
|
||||
* a PEAR_PackageFile object
|
||||
*
|
||||
* @param mixed $callback callback function used to report output,
|
||||
* see PEAR_Builder::_runCommand for details
|
||||
*
|
||||
* @return array an array of associative arrays with built files,
|
||||
* format:
|
||||
* array( array( 'file' => '/path/to/ext.so',
|
||||
* 'php_api' => YYYYMMDD,
|
||||
* 'zend_mod_api' => YYYYMMDD,
|
||||
* 'zend_ext_api' => YYYYMMDD ),
|
||||
* ... )
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @see PEAR_Builder::_runCommand
|
||||
*/
|
||||
function build($descfile, $callback = null)
|
||||
{
|
||||
if (preg_match('/(\\/|\\\\|^)([^\\/\\\\]+)?php(.+)?$/',
|
||||
$this->config->get('php_bin'), $matches)) {
|
||||
if (isset($matches[2]) && strlen($matches[2]) &&
|
||||
trim($matches[2]) != trim($this->config->get('php_prefix'))) {
|
||||
$this->log(0, 'WARNING: php_bin ' . $this->config->get('php_bin') .
|
||||
' appears to have a prefix ' . $matches[2] . ', but' .
|
||||
' config variable php_prefix does not match');
|
||||
}
|
||||
|
||||
if (isset($matches[3]) && strlen($matches[3]) &&
|
||||
trim($matches[3]) != trim($this->config->get('php_suffix'))) {
|
||||
$this->log(0, 'WARNING: php_bin ' . $this->config->get('php_bin') .
|
||||
' appears to have a suffix ' . $matches[3] . ', but' .
|
||||
' config variable php_suffix does not match');
|
||||
}
|
||||
}
|
||||
|
||||
$this->current_callback = $callback;
|
||||
if (PEAR_OS == "Windows") {
|
||||
return $this->_build_win32($descfile, $callback);
|
||||
}
|
||||
|
||||
if (PEAR_OS != 'Unix') {
|
||||
return $this->raiseError("building extensions not supported on this platform");
|
||||
}
|
||||
|
||||
if (is_object($descfile)) {
|
||||
$pkg = $descfile;
|
||||
$descfile = $pkg->getPackageFile();
|
||||
if (is_a($pkg, 'PEAR_PackageFile_v1')) {
|
||||
$dir = dirname($descfile);
|
||||
} else {
|
||||
$dir = $pkg->_config->get('temp_dir') . '/' . $pkg->getName();
|
||||
// automatically delete at session end
|
||||
$this->addTempFile($dir);
|
||||
}
|
||||
} else {
|
||||
$pf = &new PEAR_PackageFile($this->config);
|
||||
$pkg = &$pf->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL);
|
||||
if (PEAR::isError($pkg)) {
|
||||
return $pkg;
|
||||
}
|
||||
$dir = dirname($descfile);
|
||||
}
|
||||
|
||||
// Find config. outside of normal path - e.g. config.m4
|
||||
foreach (array_keys($pkg->getInstallationFileList()) as $item) {
|
||||
if (stristr(basename($item), 'config.m4') && dirname($item) != '.') {
|
||||
$dir .= DIRECTORY_SEPARATOR . dirname($item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$old_cwd = getcwd();
|
||||
if (!file_exists($dir) || !is_dir($dir) || !chdir($dir)) {
|
||||
return $this->raiseError("could not chdir to $dir");
|
||||
}
|
||||
|
||||
$vdir = $pkg->getPackage() . '-' . $pkg->getVersion();
|
||||
if (is_dir($vdir)) {
|
||||
chdir($vdir);
|
||||
}
|
||||
|
||||
$dir = getcwd();
|
||||
$this->log(2, "building in $dir");
|
||||
putenv('PATH=' . $this->config->get('bin_dir') . ':' . getenv('PATH'));
|
||||
$err = $this->_runCommand($this->config->get('php_prefix')
|
||||
. "phpize" .
|
||||
$this->config->get('php_suffix'),
|
||||
array(&$this, 'phpizeCallback'));
|
||||
if (PEAR::isError($err)) {
|
||||
return $err;
|
||||
}
|
||||
|
||||
if (!$err) {
|
||||
return $this->raiseError("`phpize' failed");
|
||||
}
|
||||
|
||||
// {{{ start of interactive part
|
||||
$configure_command = "$dir/configure";
|
||||
$configure_options = $pkg->getConfigureOptions();
|
||||
if ($configure_options) {
|
||||
foreach ($configure_options as $o) {
|
||||
$default = array_key_exists('default', $o) ? $o['default'] : null;
|
||||
list($r) = $this->ui->userDialog('build',
|
||||
array($o['prompt']),
|
||||
array('text'),
|
||||
array($default));
|
||||
if (substr($o['name'], 0, 5) == 'with-' &&
|
||||
($r == 'yes' || $r == 'autodetect')) {
|
||||
$configure_command .= " --$o[name]";
|
||||
} else {
|
||||
$configure_command .= " --$o[name]=".trim($r);
|
||||
}
|
||||
}
|
||||
}
|
||||
// }}} end of interactive part
|
||||
|
||||
// FIXME make configurable
|
||||
if (!$user=getenv('USER')) {
|
||||
$user='defaultuser';
|
||||
}
|
||||
|
||||
$tmpdir = $this->config->get('temp_dir');
|
||||
$build_basedir = System::mktemp(' -t "' . $tmpdir . '" -d "pear-build-' . $user . '"');
|
||||
$build_dir = "$build_basedir/$vdir";
|
||||
$inst_dir = "$build_basedir/install-$vdir";
|
||||
$this->log(1, "building in $build_dir");
|
||||
if (is_dir($build_dir)) {
|
||||
System::rm(array('-rf', $build_dir));
|
||||
}
|
||||
|
||||
if (!System::mkDir(array('-p', $build_dir))) {
|
||||
return $this->raiseError("could not create build dir: $build_dir");
|
||||
}
|
||||
|
||||
$this->addTempFile($build_dir);
|
||||
if (!System::mkDir(array('-p', $inst_dir))) {
|
||||
return $this->raiseError("could not create temporary install dir: $inst_dir");
|
||||
}
|
||||
$this->addTempFile($inst_dir);
|
||||
|
||||
$make_command = getenv('MAKE') ? getenv('MAKE') : 'make';
|
||||
|
||||
$to_run = array(
|
||||
$configure_command,
|
||||
$make_command,
|
||||
"$make_command INSTALL_ROOT=\"$inst_dir\" install",
|
||||
"find \"$inst_dir\" | xargs ls -dils"
|
||||
);
|
||||
if (!file_exists($build_dir) || !is_dir($build_dir) || !chdir($build_dir)) {
|
||||
return $this->raiseError("could not chdir to $build_dir");
|
||||
}
|
||||
putenv('PHP_PEAR_VERSION=1.9.4');
|
||||
foreach ($to_run as $cmd) {
|
||||
$err = $this->_runCommand($cmd, $callback);
|
||||
if (PEAR::isError($err)) {
|
||||
chdir($old_cwd);
|
||||
return $err;
|
||||
}
|
||||
if (!$err) {
|
||||
chdir($old_cwd);
|
||||
return $this->raiseError("`$cmd' failed");
|
||||
}
|
||||
}
|
||||
if (!($dp = opendir("modules"))) {
|
||||
chdir($old_cwd);
|
||||
return $this->raiseError("no `modules' directory found");
|
||||
}
|
||||
$built_files = array();
|
||||
$prefix = exec($this->config->get('php_prefix')
|
||||
. "php-config" .
|
||||
$this->config->get('php_suffix') . " --prefix");
|
||||
$this->_harvestInstDir($prefix, $inst_dir . DIRECTORY_SEPARATOR . $prefix, $built_files);
|
||||
chdir($old_cwd);
|
||||
return $built_files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Message callback function used when running the "phpize"
|
||||
* program. Extracts the API numbers used. Ignores other message
|
||||
* types than "cmdoutput".
|
||||
*
|
||||
* @param string $what the type of message
|
||||
* @param mixed $data the message
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function phpizeCallback($what, $data)
|
||||
{
|
||||
if ($what != 'cmdoutput') {
|
||||
return;
|
||||
}
|
||||
$this->log(1, rtrim($data));
|
||||
if (preg_match('/You should update your .aclocal.m4/', $data)) {
|
||||
return;
|
||||
}
|
||||
$matches = array();
|
||||
if (preg_match('/^\s+(\S[^:]+):\s+(\d{8})/', $data, $matches)) {
|
||||
$member = preg_replace('/[^a-z]/', '_', strtolower($matches[1]));
|
||||
$apino = (int)$matches[2];
|
||||
if (isset($this->$member)) {
|
||||
$this->$member = $apino;
|
||||
//$msg = sprintf("%-22s : %d", $matches[1], $apino);
|
||||
//$this->log(1, $msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run an external command, using a message callback to report
|
||||
* output. The command will be run through popen and output is
|
||||
* reported for every line with a "cmdoutput" message with the
|
||||
* line string, including newlines, as payload.
|
||||
*
|
||||
* @param string $command the command to run
|
||||
*
|
||||
* @param mixed $callback (optional) function to use as message
|
||||
* callback
|
||||
*
|
||||
* @return bool whether the command was successful (exit code 0
|
||||
* means success, any other means failure)
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _runCommand($command, $callback = null)
|
||||
{
|
||||
$this->log(1, "running: $command");
|
||||
$pp = popen("$command 2>&1", "r");
|
||||
if (!$pp) {
|
||||
return $this->raiseError("failed to run `$command'");
|
||||
}
|
||||
if ($callback && $callback[0]->debug == 1) {
|
||||
$olddbg = $callback[0]->debug;
|
||||
$callback[0]->debug = 2;
|
||||
}
|
||||
|
||||
while ($line = fgets($pp, 1024)) {
|
||||
if ($callback) {
|
||||
call_user_func($callback, 'cmdoutput', $line);
|
||||
} else {
|
||||
$this->log(2, rtrim($line));
|
||||
}
|
||||
}
|
||||
if ($callback && isset($olddbg)) {
|
||||
$callback[0]->debug = $olddbg;
|
||||
}
|
||||
|
||||
$exitcode = is_resource($pp) ? pclose($pp) : -1;
|
||||
return ($exitcode == 0);
|
||||
}
|
||||
|
||||
function log($level, $msg)
|
||||
{
|
||||
if ($this->current_callback) {
|
||||
if ($this->debug >= $level) {
|
||||
call_user_func($this->current_callback, 'output', $msg);
|
||||
}
|
||||
return;
|
||||
}
|
||||
return PEAR_Common::log($level, $msg);
|
||||
}
|
||||
}
|
||||
Vendored
+1559
File diff suppressed because it is too large
Load Diff
Vendored
+68
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* PEAR_ChannelFile_Parser for parsing channel.xml
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* @category pear
|
||||
* @package PEAR
|
||||
* @author Greg Beaver <cellog@php.net>
|
||||
* @copyright 1997-2009 The Authors
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: Parser.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||
* @link http://pear.php.net/package/PEAR
|
||||
* @since File available since Release 1.4.0a1
|
||||
*/
|
||||
|
||||
/**
|
||||
* base xml parser class
|
||||
*/
|
||||
require_once 'PEAR/XMLParser.php';
|
||||
require_once 'PEAR/ChannelFile.php';
|
||||
/**
|
||||
* Parser for channel.xml
|
||||
* @category pear
|
||||
* @package PEAR
|
||||
* @author Greg Beaver <cellog@php.net>
|
||||
* @copyright 1997-2009 The Authors
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version Release: 1.9.4
|
||||
* @link http://pear.php.net/package/PEAR
|
||||
* @since Class available since Release 1.4.0a1
|
||||
*/
|
||||
class PEAR_ChannelFile_Parser extends PEAR_XMLParser
|
||||
{
|
||||
var $_config;
|
||||
var $_logger;
|
||||
var $_registry;
|
||||
|
||||
function setConfig(&$c)
|
||||
{
|
||||
$this->_config = &$c;
|
||||
$this->_registry = &$c->getRegistry();
|
||||
}
|
||||
|
||||
function setLogger(&$l)
|
||||
{
|
||||
$this->_logger = &$l;
|
||||
}
|
||||
|
||||
function parse($data, $file)
|
||||
{
|
||||
if (PEAR::isError($err = parent::parse($data, $file))) {
|
||||
return $err;
|
||||
}
|
||||
|
||||
$ret = new PEAR_ChannelFile;
|
||||
$ret->setConfig($this->_config);
|
||||
if (isset($this->_logger)) {
|
||||
$ret->setLogger($this->_logger);
|
||||
}
|
||||
|
||||
$ret->fromArray($this->_unserializedData);
|
||||
// make sure the filelist is in the easy to read format needed
|
||||
$ret->flattenFilelist();
|
||||
$ret->setPackagefile($file, $archive);
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
Vendored
+414
@@ -0,0 +1,414 @@
|
||||
<?php
|
||||
/**
|
||||
* PEAR_Command, command pattern class
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* @category pear
|
||||
* @package PEAR
|
||||
* @author Stig Bakken <ssb@php.net>
|
||||
* @author Greg Beaver <cellog@php.net>
|
||||
* @copyright 1997-2009 The Authors
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: Command.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||
* @link http://pear.php.net/package/PEAR
|
||||
* @since File available since Release 0.1
|
||||
*/
|
||||
|
||||
/**
|
||||
* Needed for error handling
|
||||
*/
|
||||
require_once 'PEAR.php';
|
||||
require_once 'PEAR/Frontend.php';
|
||||
require_once 'PEAR/XMLParser.php';
|
||||
|
||||
/**
|
||||
* List of commands and what classes they are implemented in.
|
||||
* @var array command => implementing class
|
||||
*/
|
||||
$GLOBALS['_PEAR_Command_commandlist'] = array();
|
||||
|
||||
/**
|
||||
* List of commands and their descriptions
|
||||
* @var array command => description
|
||||
*/
|
||||
$GLOBALS['_PEAR_Command_commanddesc'] = array();
|
||||
|
||||
/**
|
||||
* List of shortcuts to common commands.
|
||||
* @var array shortcut => command
|
||||
*/
|
||||
$GLOBALS['_PEAR_Command_shortcuts'] = array();
|
||||
|
||||
/**
|
||||
* Array of command objects
|
||||
* @var array class => object
|
||||
*/
|
||||
$GLOBALS['_PEAR_Command_objects'] = array();
|
||||
|
||||
/**
|
||||
* PEAR command class, a simple factory class for administrative
|
||||
* commands.
|
||||
*
|
||||
* How to implement command classes:
|
||||
*
|
||||
* - The class must be called PEAR_Command_Nnn, installed in the
|
||||
* "PEAR/Common" subdir, with a method called getCommands() that
|
||||
* returns an array of the commands implemented by the class (see
|
||||
* PEAR/Command/Install.php for an example).
|
||||
*
|
||||
* - The class must implement a run() function that is called with three
|
||||
* params:
|
||||
*
|
||||
* (string) command name
|
||||
* (array) assoc array with options, freely defined by each
|
||||
* command, for example:
|
||||
* array('force' => true)
|
||||
* (array) list of the other parameters
|
||||
*
|
||||
* The run() function returns a PEAR_CommandResponse object. Use
|
||||
* these methods to get information:
|
||||
*
|
||||
* int getStatus() Returns PEAR_COMMAND_(SUCCESS|FAILURE|PARTIAL)
|
||||
* *_PARTIAL means that you need to issue at least
|
||||
* one more command to complete the operation
|
||||
* (used for example for validation steps).
|
||||
*
|
||||
* string getMessage() Returns a message for the user. Remember,
|
||||
* no HTML or other interface-specific markup.
|
||||
*
|
||||
* If something unexpected happens, run() returns a PEAR error.
|
||||
*
|
||||
* - DON'T OUTPUT ANYTHING! Return text for output instead.
|
||||
*
|
||||
* - DON'T USE HTML! The text you return will be used from both Gtk,
|
||||
* web and command-line interfaces, so for now, keep everything to
|
||||
* plain text.
|
||||
*
|
||||
* - DON'T USE EXIT OR DIE! Always use pear errors. From static
|
||||
* classes do PEAR::raiseError(), from other classes do
|
||||
* $this->raiseError().
|
||||
* @category pear
|
||||
* @package PEAR
|
||||
* @author Stig Bakken <ssb@php.net>
|
||||
* @author Greg Beaver <cellog@php.net>
|
||||
* @copyright 1997-2009 The Authors
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version Release: 1.9.4
|
||||
* @link http://pear.php.net/package/PEAR
|
||||
* @since Class available since Release 0.1
|
||||
*/
|
||||
class PEAR_Command
|
||||
{
|
||||
// {{{ factory()
|
||||
|
||||
/**
|
||||
* Get the right object for executing a command.
|
||||
*
|
||||
* @param string $command The name of the command
|
||||
* @param object $config Instance of PEAR_Config object
|
||||
*
|
||||
* @return object the command object or a PEAR error
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function &factory($command, &$config)
|
||||
{
|
||||
if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
|
||||
PEAR_Command::registerCommands();
|
||||
}
|
||||
if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
|
||||
$command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
|
||||
}
|
||||
if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
|
||||
$a = PEAR::raiseError("unknown command `$command'");
|
||||
return $a;
|
||||
}
|
||||
$class = $GLOBALS['_PEAR_Command_commandlist'][$command];
|
||||
if (!class_exists($class)) {
|
||||
require_once $GLOBALS['_PEAR_Command_objects'][$class];
|
||||
}
|
||||
if (!class_exists($class)) {
|
||||
$a = PEAR::raiseError("unknown command `$command'");
|
||||
return $a;
|
||||
}
|
||||
$ui = PEAR_Command::getFrontendObject();
|
||||
$obj = new $class($ui, $config);
|
||||
return $obj;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ & getObject()
|
||||
function &getObject($command)
|
||||
{
|
||||
$class = $GLOBALS['_PEAR_Command_commandlist'][$command];
|
||||
if (!class_exists($class)) {
|
||||
require_once $GLOBALS['_PEAR_Command_objects'][$class];
|
||||
}
|
||||
if (!class_exists($class)) {
|
||||
return PEAR::raiseError("unknown command `$command'");
|
||||
}
|
||||
$ui = PEAR_Command::getFrontendObject();
|
||||
$config = &PEAR_Config::singleton();
|
||||
$obj = &new $class($ui, $config);
|
||||
return $obj;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ & getFrontendObject()
|
||||
|
||||
/**
|
||||
* Get instance of frontend object.
|
||||
*
|
||||
* @return object|PEAR_Error
|
||||
* @static
|
||||
*/
|
||||
function &getFrontendObject()
|
||||
{
|
||||
$a = &PEAR_Frontend::singleton();
|
||||
return $a;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ & setFrontendClass()
|
||||
|
||||
/**
|
||||
* Load current frontend class.
|
||||
*
|
||||
* @param string $uiclass Name of class implementing the frontend
|
||||
*
|
||||
* @return object the frontend object, or a PEAR error
|
||||
* @static
|
||||
*/
|
||||
function &setFrontendClass($uiclass)
|
||||
{
|
||||
$a = &PEAR_Frontend::setFrontendClass($uiclass);
|
||||
return $a;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ setFrontendType()
|
||||
|
||||
/**
|
||||
* Set current frontend.
|
||||
*
|
||||
* @param string $uitype Name of the frontend type (for example "CLI")
|
||||
*
|
||||
* @return object the frontend object, or a PEAR error
|
||||
* @static
|
||||
*/
|
||||
function setFrontendType($uitype)
|
||||
{
|
||||
$uiclass = 'PEAR_Frontend_' . $uitype;
|
||||
return PEAR_Command::setFrontendClass($uiclass);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ registerCommands()
|
||||
|
||||
/**
|
||||
* Scan through the Command directory looking for classes
|
||||
* and see what commands they implement.
|
||||
*
|
||||
* @param bool (optional) if FALSE (default), the new list of
|
||||
* commands should replace the current one. If TRUE,
|
||||
* new entries will be merged with old.
|
||||
*
|
||||
* @param string (optional) where (what directory) to look for
|
||||
* classes, defaults to the Command subdirectory of
|
||||
* the directory from where this file (__FILE__) is
|
||||
* included.
|
||||
*
|
||||
* @return bool TRUE on success, a PEAR error on failure
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function registerCommands($merge = false, $dir = null)
|
||||
{
|
||||
$parser = new PEAR_XMLParser;
|
||||
if ($dir === null) {
|
||||
$dir = dirname(__FILE__) . '/Command';
|
||||
}
|
||||
if (!is_dir($dir)) {
|
||||
return PEAR::raiseError("registerCommands: opendir($dir) '$dir' does not exist or is not a directory");
|
||||
}
|
||||
$dp = @opendir($dir);
|
||||
if (empty($dp)) {
|
||||
return PEAR::raiseError("registerCommands: opendir($dir) failed");
|
||||
}
|
||||
if (!$merge) {
|
||||
$GLOBALS['_PEAR_Command_commandlist'] = array();
|
||||
}
|
||||
|
||||
while ($file = readdir($dp)) {
|
||||
if ($file{0} == '.' || substr($file, -4) != '.xml') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$f = substr($file, 0, -4);
|
||||
$class = "PEAR_Command_" . $f;
|
||||
// List of commands
|
||||
if (empty($GLOBALS['_PEAR_Command_objects'][$class])) {
|
||||
$GLOBALS['_PEAR_Command_objects'][$class] = "$dir/" . $f . '.php';
|
||||
}
|
||||
|
||||
$parser->parse(file_get_contents("$dir/$file"));
|
||||
$implements = $parser->getData();
|
||||
foreach ($implements as $command => $desc) {
|
||||
if ($command == 'attribs') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
|
||||
return PEAR::raiseError('Command "' . $command . '" already registered in ' .
|
||||
'class "' . $GLOBALS['_PEAR_Command_commandlist'][$command] . '"');
|
||||
}
|
||||
|
||||
$GLOBALS['_PEAR_Command_commandlist'][$command] = $class;
|
||||
$GLOBALS['_PEAR_Command_commanddesc'][$command] = $desc['summary'];
|
||||
if (isset($desc['shortcut'])) {
|
||||
$shortcut = $desc['shortcut'];
|
||||
if (isset($GLOBALS['_PEAR_Command_shortcuts'][$shortcut])) {
|
||||
return PEAR::raiseError('Command shortcut "' . $shortcut . '" already ' .
|
||||
'registered to command "' . $command . '" in class "' .
|
||||
$GLOBALS['_PEAR_Command_commandlist'][$command] . '"');
|
||||
}
|
||||
$GLOBALS['_PEAR_Command_shortcuts'][$shortcut] = $command;
|
||||
}
|
||||
|
||||
if (isset($desc['options']) && $desc['options']) {
|
||||
foreach ($desc['options'] as $oname => $option) {
|
||||
if (isset($option['shortopt']) && strlen($option['shortopt']) > 1) {
|
||||
return PEAR::raiseError('Option "' . $oname . '" short option "' .
|
||||
$option['shortopt'] . '" must be ' .
|
||||
'only 1 character in Command "' . $command . '" in class "' .
|
||||
$class . '"');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ksort($GLOBALS['_PEAR_Command_shortcuts']);
|
||||
ksort($GLOBALS['_PEAR_Command_commandlist']);
|
||||
@closedir($dp);
|
||||
return true;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getCommands()
|
||||
|
||||
/**
|
||||
* Get the list of currently supported commands, and what
|
||||
* classes implement them.
|
||||
*
|
||||
* @return array command => implementing class
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function getCommands()
|
||||
{
|
||||
if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
|
||||
PEAR_Command::registerCommands();
|
||||
}
|
||||
return $GLOBALS['_PEAR_Command_commandlist'];
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getShortcuts()
|
||||
|
||||
/**
|
||||
* Get the list of command shortcuts.
|
||||
*
|
||||
* @return array shortcut => command
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function getShortcuts()
|
||||
{
|
||||
if (empty($GLOBALS['_PEAR_Command_shortcuts'])) {
|
||||
PEAR_Command::registerCommands();
|
||||
}
|
||||
return $GLOBALS['_PEAR_Command_shortcuts'];
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getGetoptArgs()
|
||||
|
||||
/**
|
||||
* Compiles arguments for getopt.
|
||||
*
|
||||
* @param string $command command to get optstring for
|
||||
* @param string $short_args (reference) short getopt format
|
||||
* @param array $long_args (reference) long getopt format
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function getGetoptArgs($command, &$short_args, &$long_args)
|
||||
{
|
||||
if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
|
||||
PEAR_Command::registerCommands();
|
||||
}
|
||||
if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
|
||||
$command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
|
||||
}
|
||||
if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
|
||||
return null;
|
||||
}
|
||||
$obj = &PEAR_Command::getObject($command);
|
||||
return $obj->getGetoptArgs($command, $short_args, $long_args);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getDescription()
|
||||
|
||||
/**
|
||||
* Get description for a command.
|
||||
*
|
||||
* @param string $command Name of the command
|
||||
*
|
||||
* @return string command description
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function getDescription($command)
|
||||
{
|
||||
if (!isset($GLOBALS['_PEAR_Command_commanddesc'][$command])) {
|
||||
return null;
|
||||
}
|
||||
return $GLOBALS['_PEAR_Command_commanddesc'][$command];
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getHelp()
|
||||
|
||||
/**
|
||||
* Get help for command.
|
||||
*
|
||||
* @param string $command Name of the command to return help for
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function getHelp($command)
|
||||
{
|
||||
$cmds = PEAR_Command::getCommands();
|
||||
if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
|
||||
$command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
|
||||
}
|
||||
if (isset($cmds[$command])) {
|
||||
$obj = &PEAR_Command::getObject($command);
|
||||
return $obj->getHelp($command);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
Vendored
+81
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/**
|
||||
* PEAR_Command_Auth (login, logout commands)
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* @category pear
|
||||
* @package PEAR
|
||||
* @author Stig Bakken <ssb@php.net>
|
||||
* @author Greg Beaver <cellog@php.net>
|
||||
* @copyright 1997-2009 The Authors
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: Auth.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||
* @link http://pear.php.net/package/PEAR
|
||||
* @since File available since Release 0.1
|
||||
* @deprecated since 1.8.0alpha1
|
||||
*/
|
||||
|
||||
/**
|
||||
* base class
|
||||
*/
|
||||
require_once 'PEAR/Command/Channels.php';
|
||||
|
||||
/**
|
||||
* PEAR commands for login/logout
|
||||
*
|
||||
* @category pear
|
||||
* @package PEAR
|
||||
* @author Stig Bakken <ssb@php.net>
|
||||
* @author Greg Beaver <cellog@php.net>
|
||||
* @copyright 1997-2009 The Authors
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version Release: 1.9.4
|
||||
* @link http://pear.php.net/package/PEAR
|
||||
* @since Class available since Release 0.1
|
||||
* @deprecated since 1.8.0alpha1
|
||||
*/
|
||||
class PEAR_Command_Auth extends PEAR_Command_Channels
|
||||
{
|
||||
var $commands = array(
|
||||
'login' => array(
|
||||
'summary' => 'Connects and authenticates to remote server [Deprecated in favor of channel-login]',
|
||||
'shortcut' => 'li',
|
||||
'function' => 'doLogin',
|
||||
'options' => array(),
|
||||
'doc' => '<channel name>
|
||||
WARNING: This function is deprecated in favor of using channel-login
|
||||
|
||||
Log in to a remote channel server. If <channel name> is not supplied,
|
||||
the default channel is used. To use remote functions in the installer
|
||||
that require any kind of privileges, you need to log in first. The
|
||||
username and password you enter here will be stored in your per-user
|
||||
PEAR configuration (~/.pearrc on Unix-like systems). After logging
|
||||
in, your username and password will be sent along in subsequent
|
||||
operations on the remote server.',
|
||||
),
|
||||
'logout' => array(
|
||||
'summary' => 'Logs out from the remote server [Deprecated in favor of channel-logout]',
|
||||
'shortcut' => 'lo',
|
||||
'function' => 'doLogout',
|
||||
'options' => array(),
|
||||
'doc' => '
|
||||
WARNING: This function is deprecated in favor of using channel-logout
|
||||
|
||||
Logs out from the remote server. This command does not actually
|
||||
connect to the remote server, it only deletes the stored username and
|
||||
password from your user configuration.',
|
||||
)
|
||||
|
||||
);
|
||||
|
||||
/**
|
||||
* PEAR_Command_Auth constructor.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function PEAR_Command_Auth(&$ui, &$config)
|
||||
{
|
||||
parent::PEAR_Command_Channels($ui, $config);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user