v1.1
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
# Custom for Visual Studio
|
||||
*.cs diff=csharp
|
||||
*.sln merge=union
|
||||
*.csproj merge=union
|
||||
*.vbproj merge=union
|
||||
*.fsproj merge=union
|
||||
*.dbproj merge=union
|
||||
|
||||
# Standard to msysgit
|
||||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
*.docx diff=astextplain
|
||||
*.DOCX diff=astextplain
|
||||
*.dot diff=astextplain
|
||||
*.DOT diff=astextplain
|
||||
*.pdf diff=astextplain
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
open_collective: medoo
|
||||
custom: ["https://paypal.me/AngelaonLai"]
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
---
|
||||
|
||||
**Information**
|
||||
- **Version of Medoo:** [Enter the version number]
|
||||
- **Version of PHP:** [Enter the version number]
|
||||
- **Type of Database:** [MySQL, MSSQL, SQLite, etc.]
|
||||
- **System:** [Linux|Windows|Mac]
|
||||
|
||||
**Describe the Problem**
|
||||
A clear and concise description of what the problem is.
|
||||
|
||||
**Code Snippet**
|
||||
The detail code you are using that causes the problem:
|
||||
```php
|
||||
// Write your PHP code here
|
||||
|
||||
```
|
||||
|
||||
**Expected Behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Actual Behavior**
|
||||
A clear and concise description of what actually happened.
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
name: build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php: ['7.3', '7.4', '8.2', '8.3']
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
|
||||
- name: Validate composer.json and composer.lock
|
||||
run: composer validate --strict
|
||||
|
||||
- name: Cache Composer packages
|
||||
id: composer-cache
|
||||
uses: actions/cache@v3.2.2
|
||||
with:
|
||||
path: vendor
|
||||
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-php-
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer install --prefer-dist --no-progress
|
||||
|
||||
- name: Run test suite
|
||||
run: composer run-script test
|
||||
@@ -0,0 +1,225 @@
|
||||
#################
|
||||
## Eclipse
|
||||
#################
|
||||
|
||||
*.pydevproject
|
||||
.project
|
||||
.metadata
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.classpath
|
||||
.settings/
|
||||
.loadpath
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
|
||||
#################
|
||||
## Visual Studio
|
||||
#################
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.sln.docstates
|
||||
|
||||
# Build results
|
||||
|
||||
[Dd]ebug/
|
||||
[Rr]elease/
|
||||
x64/
|
||||
build/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.log
|
||||
*.scc
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
*.ncrunch*
|
||||
.*crunch*.local.xml
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.Publish.xml
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# NuGet Packages Directory
|
||||
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
|
||||
#packages/
|
||||
|
||||
# Windows Azure Build Output
|
||||
csx
|
||||
*.build.csdef
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
|
||||
# Others
|
||||
sql/
|
||||
*.Cache
|
||||
ClientBin/
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.[Pp]ublish.xml
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file to a newer
|
||||
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
App_Data/*.mdf
|
||||
App_Data/*.ldf
|
||||
|
||||
#############
|
||||
## Windows detritus
|
||||
#############
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Mac crap
|
||||
.DS_Store
|
||||
|
||||
|
||||
#############
|
||||
## Python
|
||||
#############
|
||||
|
||||
*.py[cod]
|
||||
|
||||
# Packages
|
||||
*.egg
|
||||
*.egg-info
|
||||
dist/
|
||||
build/
|
||||
eggs/
|
||||
parts/
|
||||
var/
|
||||
sdist/
|
||||
develop-eggs/
|
||||
.installed.cfg
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
.coverage
|
||||
.tox
|
||||
|
||||
#Translations
|
||||
*.mo
|
||||
|
||||
#Mr Developer
|
||||
.mr.developer.cfg
|
||||
|
||||
#php-cs-fixer
|
||||
/.php_cs
|
||||
|
||||
#PHPUnit
|
||||
/.phpunit.cache
|
||||
|
||||
/composer.lock
|
||||
/vendor
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
$config = new PhpCsFixer\Config();
|
||||
|
||||
$config
|
||||
->setRules([
|
||||
'@PSR2' => true,
|
||||
'@PSR12' => true,
|
||||
'array_syntax' => ['syntax' => 'short'],
|
||||
'nullable_type_declaration_for_default_null_value' => true
|
||||
])
|
||||
->setFinder(
|
||||
PhpCsFixer\Finder::create()
|
||||
->in(__DIR__ . '/src')
|
||||
->in(__DIR__ . '/tests')
|
||||
)
|
||||
;
|
||||
|
||||
return $config;
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Angel Lai
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
Vendored
+120
@@ -0,0 +1,120 @@
|
||||
<p align="center">
|
||||
<a href="https://medoo.in" target="_blank"><img src="https://cloud.githubusercontent.com/assets/1467904/19835326/ca62bc36-9ebd-11e6-8b37-7240d76319cd.png"></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/catfan/Medoo/actions"><img alt="Build Status" src="https://github.com/catfan/Medoo/actions/workflows/php.yml/badge.svg"></a>
|
||||
<a href="https://packagist.org/packages/catfan/medoo"><img alt="Total Downloads" src="https://poser.pugx.org/catfan/medoo/downloads"></a>
|
||||
<a href="https://packagist.org/packages/catfan/medoo"><img alt="Latest Stable Version" src="https://poser.pugx.org/catfan/medoo/v/stable"></a>
|
||||
<a href="https://packagist.org/packages/catfan/medoo"><img alt="License" src="https://poser.pugx.org/catfan/medoo/license"></a>
|
||||
<a href="https://opencollective.com/medoo"><img alt="Backers on Open Collective" src="https://opencollective.com/Medoo/backers/badge.svg"></a>
|
||||
<a href="https://opencollective.com/medoo"><img alt="Sponsors on Open Collective" src="https://opencollective.com/Medoo/sponsors/badge.svg"> </a>
|
||||
</p>
|
||||
|
||||
> The lightweight PHP database framework to accelerate development.
|
||||
|
||||
## Features
|
||||
|
||||
* **Lightweight** - Single-file framework with minimal dependencies.
|
||||
|
||||
* **Easy** - Simple and intuitive API for quick integration.
|
||||
|
||||
* **Powerful** - Supports complex SQL queries, data mapping, and SQL injection prevention.
|
||||
|
||||
* **Compatible** - Works with MySQL, MariaDB, PostgreSQL, SQLite, MSSQL, Oracle, Sybase, and more.
|
||||
|
||||
* **Friendly** - Integrates seamlessly with Laravel, CodeIgniter, Yii, Slim, and other PHP frameworks.
|
||||
|
||||
* **Free** - Licensed under MIT, free to use for any purpose.
|
||||
|
||||
## Requirements
|
||||
|
||||
- PHP 7.3 or later
|
||||
- PDO extension enabled
|
||||
|
||||
## Get Started
|
||||
|
||||
### Install via composer
|
||||
|
||||
Add Medoo to the `composer.json` configuration file.
|
||||
```bash
|
||||
$ composer require catfan/medoo
|
||||
```
|
||||
|
||||
Then update Composer
|
||||
```bash
|
||||
$ composer update
|
||||
```
|
||||
|
||||
```php
|
||||
// Require Composer's autoloader
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
// Import Medoo namespace
|
||||
use Medoo\Medoo;
|
||||
|
||||
// Initialize database connection
|
||||
$database = new Medoo([
|
||||
'type' => 'mysql',
|
||||
'host' => 'localhost',
|
||||
'database' => 'name',
|
||||
'username' => 'your_username',
|
||||
'password' => 'your_password'
|
||||
]);
|
||||
|
||||
// Insert data
|
||||
$database->insert('account', [
|
||||
'user_name' => 'foo',
|
||||
'email' => 'foo@bar.com'
|
||||
]);
|
||||
|
||||
// Retrieve data
|
||||
$data = $database->select('account', [
|
||||
'user_name',
|
||||
'email'
|
||||
], [
|
||||
'user_id' => 50
|
||||
]);
|
||||
|
||||
echo json_encode($data);
|
||||
|
||||
// [{
|
||||
// "user_name" : "foo",
|
||||
// "email" : "foo@bar.com",
|
||||
// }]
|
||||
```
|
||||
|
||||
## Contribution Guidelines
|
||||
Before submitting a pull request, ensure compatibility with multiple database engines and include unit tests when possible.
|
||||
|
||||
### Testing & Code Style
|
||||
- Run `phpunit tests` to execute unit tests.
|
||||
- Use `php-cs-fixer fix` to enforce code style consistency.
|
||||
|
||||
### Commit Message Format
|
||||
Each commit should begin with a tag indicating the type of change:
|
||||
|
||||
- `[fix]` for bug fixes
|
||||
- `[feature]` for new features
|
||||
- `[update]` for improvements
|
||||
|
||||
Keep contributions simple and well-documented.
|
||||
|
||||
## License
|
||||
|
||||
Medoo is released under the MIT License.
|
||||
|
||||
## Links
|
||||
|
||||
* Official website: [https://medoo.in](https://medoo.in)
|
||||
|
||||
* Documentation: [https://medoo.in/doc](https://medoo.in/doc)
|
||||
|
||||
* Twitter: [https://twitter.com/MedooPHP](https://twitter.com/MedooPHP)
|
||||
|
||||
* Open Collective: [https://opencollective.com/medoo](https://opencollective.com/medoo)
|
||||
|
||||
## Support Our Other Product
|
||||
[Gear Browser - Web Browser for Geek](https://gear4.app)
|
||||
|
||||
[](https://gear4.app)
|
||||
Vendored
+43
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"name": "catfan/medoo",
|
||||
"type": "framework",
|
||||
"description": "The lightweight PHP database framework to accelerate development",
|
||||
"keywords": ["database", "database library", "lightweight", "PHP framework", "SQL", "MySQL", "MSSQL", "SQLite", "PostgreSQL", "MariaDB", "Oracle"],
|
||||
"homepage": "https://medoo.in",
|
||||
"license": "MIT",
|
||||
"support": {
|
||||
"issues": "https://github.com/catfan/Medoo/issues",
|
||||
"source": "https://github.com/catfan/Medoo"
|
||||
},
|
||||
"authors": [
|
||||
{"name": "Angel Lai", "email": "angel@medoo.in"}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.3",
|
||||
"ext-pdo": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-pdo_mysql": "For MySQL or MariaDB database",
|
||||
"ext-pdo_sqlsrv": "For MSSQL database on both Window/Liunx platform",
|
||||
"ext-pdo_dblib": "For MSSQL or Sybase database on Linux/UNIX platform",
|
||||
"ext-pdo_oci": "For Oracle database",
|
||||
"ext-pdo_pqsql": "For PostgreSQL database",
|
||||
"ext-pdo_sqlite": "For SQLite database"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Medoo\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Medoo\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": "vendor/bin/phpunit tests"
|
||||
}
|
||||
}
|
||||
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd"
|
||||
bootstrap="vendor/autoload.php"
|
||||
cacheResultFile=".phpunit.cache/test-results"
|
||||
executionOrder="depends,defects"
|
||||
failOnRisky="true"
|
||||
failOnWarning="true"
|
||||
verbose="true">
|
||||
<testsuites>
|
||||
<testsuite name="Medoo Test Suite">
|
||||
<directory suffix="Test.php">./tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<coverage cacheDirectory=".phpunit.cache/code-coverage"
|
||||
processUncoveredFiles="true">
|
||||
<include>
|
||||
<directory suffix=".php">src</directory>
|
||||
</include>
|
||||
</coverage>
|
||||
</phpunit>
|
||||
Vendored
+2310
File diff suppressed because it is too large
Load Diff
+117
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
namespace Medoo\Tests;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Medoo\Medoo
|
||||
*/
|
||||
class AggregateTest extends MedooTestCase
|
||||
{
|
||||
/**
|
||||
* @covers ::count()
|
||||
* @covers ::aggregate()
|
||||
* @covers ::selectContext()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testCount($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->count("account", [
|
||||
"gender" => "female"
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT COUNT(*)
|
||||
FROM "account"
|
||||
WHERE "gender" = 'female'
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::max()
|
||||
* @covers ::aggregate()
|
||||
* @covers ::selectContext()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testMax($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->max("account", "age");
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT MAX("age")
|
||||
FROM "account"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::min()
|
||||
* @covers ::aggregate()
|
||||
* @covers ::selectContext()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testMin($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->min("account", "age");
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT MIN("age")
|
||||
FROM "account"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::avg()
|
||||
* @covers ::aggregate()
|
||||
* @covers ::selectContext()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testAvg($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->avg("account", "age");
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT AVG("age")
|
||||
FROM "account"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::sum()
|
||||
* @covers ::aggregate()
|
||||
* @covers ::selectContext()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSum($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->sum("account", "money");
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT SUM("money")
|
||||
FROM "account"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
}
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
namespace Medoo\Tests;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Medoo\Medoo
|
||||
*/
|
||||
class CreateTest extends MedooTestCase
|
||||
{
|
||||
/**
|
||||
* @covers ::create()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testCreate($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->create("account", [
|
||||
"id" => [
|
||||
"INT",
|
||||
"NOT NULL",
|
||||
"AUTO_INCREMENT"
|
||||
],
|
||||
"email" => [
|
||||
"VARCHAR(70)",
|
||||
"NOT NULL",
|
||||
"UNIQUE"
|
||||
],
|
||||
"PRIMARY KEY (<id>)"
|
||||
], [
|
||||
"AUTO_INCREMENT" => 200
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
[
|
||||
'default' => <<<EOD
|
||||
CREATE TABLE IF NOT EXISTS "account"
|
||||
("id" INT NOT NULL AUTO_INCREMENT,
|
||||
"email" VARCHAR(70) NOT NULL UNIQUE,
|
||||
PRIMARY KEY ("id"))
|
||||
AUTO_INCREMENT = 200
|
||||
EOD,
|
||||
'mssql' => <<<EOD
|
||||
CREATE TABLE [account]
|
||||
([id] INT NOT NULL AUTO_INCREMENT,
|
||||
[email] VARCHAR(70) NOT NULL UNIQUE,
|
||||
PRIMARY KEY ([id]))
|
||||
AUTO_INCREMENT = 200
|
||||
EOD,
|
||||
'oracle' => <<<EOD
|
||||
CREATE TABLE "account"
|
||||
("id" INT NOT NULL AUTO_INCREMENT,
|
||||
"email" VARCHAR(70) NOT NULL UNIQUE,
|
||||
PRIMARY KEY ("id"))
|
||||
AUTO_INCREMENT = 200
|
||||
EOD
|
||||
],
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::create()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testCreateWithStringDefinition($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->create("account", [
|
||||
"id" => "INT NOT NULL AUTO_INCREMENT",
|
||||
"email" => "VARCHAR(70) NOT NULL UNIQUE"
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
[
|
||||
'default' => <<<EOD
|
||||
CREATE TABLE IF NOT EXISTS "account"
|
||||
("id" INT NOT NULL AUTO_INCREMENT,
|
||||
"email" VARCHAR(70) NOT NULL UNIQUE)
|
||||
EOD,
|
||||
'mssql' => <<<EOD
|
||||
CREATE TABLE [account]
|
||||
([id] INT NOT NULL AUTO_INCREMENT,
|
||||
[email] VARCHAR(70) NOT NULL UNIQUE)
|
||||
EOD,
|
||||
'oracle' => <<<EOD
|
||||
CREATE TABLE "account"
|
||||
("id" INT NOT NULL AUTO_INCREMENT,
|
||||
"email" VARCHAR(70) NOT NULL UNIQUE)
|
||||
EOD
|
||||
],
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::create()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testCreateWithSingleOption($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->create("account", [
|
||||
"id" => [
|
||||
"INT",
|
||||
"NOT NULL",
|
||||
"AUTO_INCREMENT"
|
||||
],
|
||||
"email" => [
|
||||
"VARCHAR(70)",
|
||||
"NOT NULL",
|
||||
"UNIQUE"
|
||||
]
|
||||
], "TABLESPACE tablespace_name");
|
||||
|
||||
$this->assertQuery(
|
||||
[
|
||||
'default' => <<<EOD
|
||||
CREATE TABLE IF NOT EXISTS "account"
|
||||
("id" INT NOT NULL AUTO_INCREMENT,
|
||||
"email" VARCHAR(70) NOT NULL UNIQUE)
|
||||
TABLESPACE tablespace_name
|
||||
EOD,
|
||||
'mssql' => <<<EOD
|
||||
CREATE TABLE [account]
|
||||
([id] INT NOT NULL AUTO_INCREMENT,
|
||||
[email] VARCHAR(70) NOT NULL UNIQUE)
|
||||
TABLESPACE tablespace_name
|
||||
EOD,
|
||||
'oracle' => <<<EOD
|
||||
CREATE TABLE "account"
|
||||
("id" INT NOT NULL AUTO_INCREMENT,
|
||||
"email" VARCHAR(70) NOT NULL UNIQUE)
|
||||
TABLESPACE tablespace_name
|
||||
EOD
|
||||
],
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace Medoo\Tests;
|
||||
|
||||
use Medoo\Medoo;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Medoo\Medoo
|
||||
*/
|
||||
class DeleteTest extends MedooTestCase
|
||||
{
|
||||
/**
|
||||
* @covers ::delete()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testDelete($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->delete("account", [
|
||||
"AND" => [
|
||||
"type" => "business",
|
||||
"age[<]" => 18
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
DELETE FROM "account"
|
||||
WHERE ("type" = 'business' AND "age" < 18)
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::delete()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testDeleteRaw($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$whereClause = Medoo::raw("WHERE (<type> = :type AND <age> < :age)", [
|
||||
':type' => 'business',
|
||||
':age' => 18,
|
||||
]);
|
||||
|
||||
$this->database->delete("account", $whereClause);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
DELETE FROM "account"
|
||||
WHERE ("type" = 'business' AND "age" < 18)
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Medoo\Tests;
|
||||
|
||||
use Medoo\Medoo;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Medoo\Medoo
|
||||
*/
|
||||
class DropTest extends MedooTestCase
|
||||
{
|
||||
/**
|
||||
* @covers ::drop()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testDrop($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->drop("account");
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
DROP TABLE IF EXISTS "account"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::drop()
|
||||
*/
|
||||
public function testDropWithPrefix()
|
||||
{
|
||||
$database = new Medoo([
|
||||
'testMode' => true,
|
||||
'prefix' => 'PREFIX_'
|
||||
]);
|
||||
|
||||
$database->type = "sqlite";
|
||||
|
||||
$database->drop("account");
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
DROP TABLE IF EXISTS "PREFIX_account"
|
||||
EOD,
|
||||
$database->queryString
|
||||
);
|
||||
}
|
||||
}
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
namespace Medoo\Tests;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Medoo\Medoo
|
||||
*/
|
||||
class GetTest extends MedooTestCase
|
||||
{
|
||||
/**
|
||||
* @covers ::get()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testGet($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->get("account", "email", [
|
||||
"user_id" => 1234
|
||||
]);
|
||||
|
||||
$this->assertQuery([
|
||||
'default' => <<<EOD
|
||||
SELECT "email"
|
||||
FROM "account"
|
||||
WHERE "user_id" = 1234
|
||||
LIMIT 1
|
||||
EOD,
|
||||
'mssql' => <<<EOD
|
||||
SELECT [email]
|
||||
FROM [account]
|
||||
WHERE [user_id] = 1234
|
||||
ORDER BY (SELECT 0)
|
||||
OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY
|
||||
EOD,
|
||||
'oracle' => <<<EOD
|
||||
SELECT "email"
|
||||
FROM "account"
|
||||
WHERE "user_id" = 1234
|
||||
OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY
|
||||
EOD,
|
||||
], $this->database->queryString);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::get()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testGetWithColumns($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->get("account", [
|
||||
"email",
|
||||
"location"
|
||||
], [
|
||||
"user_id" => 1234
|
||||
]);
|
||||
|
||||
$this->assertQuery([
|
||||
'default' => <<<EOD
|
||||
SELECT "email","location"
|
||||
FROM "account"
|
||||
WHERE "user_id" = 1234
|
||||
LIMIT 1
|
||||
EOD,
|
||||
'mssql' => <<<EOD
|
||||
SELECT [email],[location]
|
||||
FROM [account]
|
||||
WHERE [user_id] = 1234
|
||||
ORDER BY (SELECT 0)
|
||||
OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY
|
||||
EOD,
|
||||
'oracle' => <<<EOD
|
||||
SELECT "email","location"
|
||||
FROM "account"
|
||||
WHERE "user_id" = 1234
|
||||
OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY
|
||||
EOD,
|
||||
], $this->database->queryString);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::get()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testGetWithJoin($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->get("post", [
|
||||
"[>]account" => "user_id"
|
||||
], [
|
||||
"post.content",
|
||||
"account.user_name"
|
||||
]);
|
||||
|
||||
$this->assertQuery([
|
||||
'default' => <<<EOD
|
||||
SELECT "post"."content","account"."user_name"
|
||||
FROM "post"
|
||||
LEFT JOIN "account" USING ("user_id")
|
||||
LIMIT 1
|
||||
EOD,
|
||||
'mssql' => <<<EOD
|
||||
SELECT [post].[content],[account].[user_name]
|
||||
FROM [post]
|
||||
LEFT JOIN [account] USING ([user_id])
|
||||
ORDER BY (SELECT 0)
|
||||
OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY
|
||||
EOD,
|
||||
'oracle' => <<<EOD
|
||||
SELECT "post"."content","account"."user_name"
|
||||
FROM "post"
|
||||
LEFT JOIN "account" USING ("user_id")
|
||||
OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY
|
||||
EOD,
|
||||
], $this->database->queryString);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::get()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testGetWithJoinAndWhere($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->get("post", [
|
||||
"[>]account" => "user_id"
|
||||
], [
|
||||
"post.content",
|
||||
"account.user_name"
|
||||
], [
|
||||
'account.age[>]' => 18
|
||||
]);
|
||||
|
||||
$this->assertQuery([
|
||||
'default' => <<<EOD
|
||||
SELECT "post"."content","account"."user_name"
|
||||
FROM "post"
|
||||
LEFT JOIN "account" USING ("user_id")
|
||||
WHERE "account"."age" > 18
|
||||
LIMIT 1
|
||||
EOD,
|
||||
'mssql' => <<<EOD
|
||||
SELECT [post].[content],[account].[user_name]
|
||||
FROM [post]
|
||||
LEFT JOIN [account] USING ([user_id])
|
||||
WHERE [account].[age] > 18
|
||||
ORDER BY (SELECT 0)
|
||||
OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY
|
||||
EOD,
|
||||
'oracle' => <<<EOD
|
||||
SELECT "post"."content","account"."user_name"
|
||||
FROM "post"
|
||||
LEFT JOIN "account" USING ("user_id")
|
||||
WHERE "account"."age" > 18
|
||||
OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY
|
||||
EOD,
|
||||
], $this->database->queryString);
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Medoo\Tests;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Medoo\Medoo
|
||||
*/
|
||||
class HasTest extends MedooTestCase
|
||||
{
|
||||
/**
|
||||
* @covers ::has()
|
||||
* @covers ::selectContext()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testHas($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->has("account", [
|
||||
"user_name" => "foo"
|
||||
]);
|
||||
|
||||
$this->assertQuery([
|
||||
'default' => <<<EOD
|
||||
SELECT EXISTS(SELECT 1 FROM "account" WHERE "user_name" = 'foo')
|
||||
EOD,
|
||||
'mssql' => <<<EOD
|
||||
SELECT TOP 1 1 FROM [account] WHERE [user_name] = 'foo'
|
||||
EOD
|
||||
], $this->database->queryString);
|
||||
}
|
||||
}
|
||||
+242
@@ -0,0 +1,242 @@
|
||||
<?php
|
||||
|
||||
namespace Medoo\Tests;
|
||||
|
||||
use Medoo\Medoo;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Medoo\Medoo
|
||||
*/
|
||||
class InsertTest extends MedooTestCase
|
||||
{
|
||||
/**
|
||||
* @covers ::insert()
|
||||
* @covers ::typeMap()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testInsert($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->insert("account", [
|
||||
"user_name" => "foo",
|
||||
"email" => "foo@bar.com"
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
INSERT INTO "account" ("user_name", "email")
|
||||
VALUES ('foo', 'foo@bar.com')
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::insert()
|
||||
* @covers ::typeMap()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testInsertWithArray($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->insert("account", [
|
||||
"user_name" => "foo",
|
||||
"lang" => ["en", "fr"]
|
||||
]);
|
||||
|
||||
$this->assertQuery([
|
||||
'default' => <<<EOD
|
||||
INSERT INTO "account" ("user_name", "lang")
|
||||
VALUES ('foo', 'a:2:{i:0;s:2:"en";i:1;s:2:"fr";}')
|
||||
EOD,
|
||||
'mysql' => <<<EOD
|
||||
INSERT INTO "account" ("user_name", "lang")
|
||||
VALUES ('foo', 'a:2:{i:0;s:2:\"en\";i:1;s:2:\"fr\";}')
|
||||
EOD
|
||||
], $this->database->queryString);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::insert()
|
||||
* @covers ::typeMap()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testInsertWithJSON($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->insert("account", [
|
||||
"user_name" => "foo",
|
||||
"lang [JSON]" => ["en", "fr"]
|
||||
]);
|
||||
|
||||
$this->assertQuery([
|
||||
'default' => <<<EOD
|
||||
INSERT INTO "account" ("user_name", "lang")
|
||||
VALUES ('foo', '["en","fr"]')
|
||||
EOD,
|
||||
'mysql' => <<<EOD
|
||||
INSERT INTO `account` (`user_name`, `lang`)
|
||||
VALUES ('foo', '[\"en\",\"fr\"]')
|
||||
EOD
|
||||
], $this->database->queryString);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::insert()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testInsertWithRaw($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->insert("account", [
|
||||
"user_name" => Medoo::raw("UUID()")
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
INSERT INTO "account" ("user_name")
|
||||
VALUES (UUID())
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::insert()
|
||||
* @covers ::typeMap()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testInsertWithNull($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->insert("account", [
|
||||
"location" => null
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
INSERT INTO "account" ("location")
|
||||
VALUES (NULL)
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::insert()
|
||||
* @covers ::typeMap()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testInsertWithObject($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$objectData = new Foo();
|
||||
|
||||
$this->database->insert("account", [
|
||||
"object" => $objectData
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
INSERT INTO "account" ("object")
|
||||
VALUES (:MeD0_mK)
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::insert()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testMultiInsert($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->insert("account", [
|
||||
[
|
||||
"user_name" => "foo",
|
||||
"email" => "foo@bar.com"
|
||||
],
|
||||
[
|
||||
"user_name" => "bar",
|
||||
"email" => "bar@foo.com"
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
INSERT INTO "account" ("user_name", "email")
|
||||
VALUES ('foo', 'foo@bar.com'), ('bar', 'bar@foo.com')
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
public function testOracleWithPrimaryKeyInsert()
|
||||
{
|
||||
$this->setType("oracle");
|
||||
|
||||
$this->database->insert("ACCOUNT", [
|
||||
"NAME" => "foo",
|
||||
"EMAIL" => "foo@bar.com"
|
||||
], "ID");
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
INSERT INTO "ACCOUNT" ("NAME", "EMAIL")
|
||||
VALUES ('foo', 'foo@bar.com')
|
||||
RETURNING "ID" INTO :RETURNID
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
public function testOracleWithLOBsInsert()
|
||||
{
|
||||
$this->setType("oracle");
|
||||
|
||||
$fp = fopen('README.md', 'r');
|
||||
|
||||
$this->database->insert("ACCOUNT", [
|
||||
"NAME" => "foo",
|
||||
"DATA" => $fp
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
INSERT INTO "ACCOUNT" ("NAME", "DATA")
|
||||
VALUES ('foo', EMPTY_BLOB())
|
||||
RETURNING "DATA" INTO :MeD1_mK
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
public function testOracleWithLOBsAndIdInsert()
|
||||
{
|
||||
$this->setType("oracle");
|
||||
|
||||
$fp = fopen('README.md', 'r');
|
||||
|
||||
$this->database->insert("ACCOUNT", [
|
||||
"NAME" => "foo",
|
||||
"DATA" => $fp
|
||||
], "ID");
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
INSERT INTO "ACCOUNT" ("NAME", "DATA")
|
||||
VALUES ('foo', EMPTY_BLOB())
|
||||
RETURNING "DATA", "ID" INTO :MeD1_mK, :RETURNID
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace Medoo\Tests;
|
||||
|
||||
use Medoo\Medoo;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class MedooTestCase extends TestCase
|
||||
{
|
||||
protected $database;
|
||||
|
||||
public $tableAliasConnector = ' AS ';
|
||||
public $quotePattern = '"$1"';
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->database = new Medoo([
|
||||
'testMode' => true
|
||||
]);
|
||||
}
|
||||
|
||||
public function typesProvider(): array
|
||||
{
|
||||
return [
|
||||
'MySQL' => ['mysql'],
|
||||
'MSSQL' => ['mssql'],
|
||||
'SQLite' => ['sqlite'],
|
||||
'PostgreSQL' => ['pgsql'],
|
||||
'Oracle' => ['oracle']
|
||||
];
|
||||
}
|
||||
|
||||
public function setType($type): void
|
||||
{
|
||||
$this->database->setupType($type);
|
||||
|
||||
if ($type === 'oracle') {
|
||||
$this->tableAliasConnector = ' ';
|
||||
} elseif ($type === 'mysql') {
|
||||
$this->quotePattern = '`$1`';
|
||||
} elseif ($type === 'mssql') {
|
||||
$this->quotePattern = '[$1]';
|
||||
}
|
||||
}
|
||||
|
||||
public function expectedQuery($expected): string
|
||||
{
|
||||
$result = preg_replace(
|
||||
'/(?!\'[^\s]+\s?)"([\p{L}_][\p{L}\p{N}@$#\-_]*)"(?!\s?[^\s]+\')/u',
|
||||
$this->quotePattern,
|
||||
str_replace("\n", " ", $expected)
|
||||
);
|
||||
|
||||
return str_replace(
|
||||
' @AS ',
|
||||
$this->tableAliasConnector,
|
||||
$result
|
||||
);
|
||||
}
|
||||
|
||||
public function assertQuery($expected, $query): void
|
||||
{
|
||||
if (is_array($expected)) {
|
||||
$this->assertEquals(
|
||||
$this->expectedQuery($expected[$this->database->type] ?? $expected['default']),
|
||||
$query
|
||||
);
|
||||
} else {
|
||||
$this->assertEquals($this->expectedQuery($expected), $query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Foo
|
||||
{
|
||||
public $bar = "cat";
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
$this->bar = "dog";
|
||||
}
|
||||
}
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
namespace Medoo\Tests;
|
||||
|
||||
use Medoo\Medoo;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Medoo\Medoo
|
||||
*/
|
||||
class QueryTest extends MedooTestCase
|
||||
{
|
||||
/**
|
||||
* @covers ::query()
|
||||
* @covers ::isRaw()
|
||||
* @covers ::buildRaw()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testQuery($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->query("SELECT <account.email>,<account.nickname> FROM <account> WHERE <id> != 100");
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "account"."email","account"."nickname"
|
||||
FROM "account"
|
||||
WHERE "id" != 100
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::query()
|
||||
* @covers ::isRaw()
|
||||
* @covers ::buildRaw()
|
||||
*/
|
||||
public function testQueryWithPrefix()
|
||||
{
|
||||
$database = new Medoo([
|
||||
'testMode' => true,
|
||||
'prefix' => 'PREFIX_'
|
||||
]);
|
||||
|
||||
$database->query("SELECT <account.name> FROM <account>");
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "PREFIX_account"."name"
|
||||
FROM "PREFIX_account"
|
||||
EOD,
|
||||
$database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::query()
|
||||
* @covers ::isRaw()
|
||||
* @covers ::buildRaw()
|
||||
*/
|
||||
public function testQueryTableWithPrefix()
|
||||
{
|
||||
$database = new Medoo([
|
||||
'testMode' => true,
|
||||
'prefix' => 'PREFIX_'
|
||||
]);
|
||||
|
||||
$database->query("DROP TABLE IF EXISTS <account>");
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
DROP TABLE IF EXISTS "PREFIX_account"
|
||||
EOD,
|
||||
$database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::query()
|
||||
* @covers ::isRaw()
|
||||
* @covers ::buildRaw()
|
||||
*/
|
||||
public function testQueryShowTableWithPrefix()
|
||||
{
|
||||
$database = new Medoo([
|
||||
'testMode' => true,
|
||||
'prefix' => 'PREFIX_'
|
||||
]);
|
||||
|
||||
$database->query("SHOW TABLES LIKE <account>");
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SHOW TABLES LIKE "PREFIX_account"
|
||||
EOD,
|
||||
$database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::query()
|
||||
* @covers ::isRaw()
|
||||
* @covers ::buildRaw()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testPreparedStatementQuery($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->query(
|
||||
"SELECT * FROM <account> WHERE <user_name> = :user_name AND <age> = :age",
|
||||
[
|
||||
":user_name" => "John Smite",
|
||||
":age" => 20
|
||||
]
|
||||
);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT *
|
||||
FROM "account"
|
||||
WHERE "user_name" = 'John Smite' AND "age" = 20
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::query()
|
||||
* @covers ::isRaw()
|
||||
* @covers ::buildRaw()
|
||||
*/
|
||||
public function testQueryEscape()
|
||||
{
|
||||
$database = new Medoo([
|
||||
'testMode' => true,
|
||||
'prefix' => 'PREFIX_'
|
||||
]);
|
||||
|
||||
$database->query("SELECT * FROM <account> WHERE <name> = '<John>'");
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT *
|
||||
FROM "PREFIX_account"
|
||||
WHERE "name" = '<John>'
|
||||
EOD,
|
||||
$database->queryString
|
||||
);
|
||||
}
|
||||
}
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
namespace Medoo\Tests;
|
||||
|
||||
use Medoo\Medoo;
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Medoo\Medoo
|
||||
*/
|
||||
class QuoteTest extends MedooTestCase
|
||||
{
|
||||
/**
|
||||
* @covers ::quote()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testQuote($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$quotedString = $this->database->quote("Co'mpl''ex \"st'\"ring");
|
||||
|
||||
$expected = [
|
||||
'mysql' => <<<EOD
|
||||
'Co\'mpl\'\'ex \"st\'\"ring'
|
||||
EOD,
|
||||
'mssql' => <<<EOD
|
||||
'Co''mpl''''ex "st''"ring'
|
||||
EOD,
|
||||
'sqlite' => <<<EOD
|
||||
'Co''mpl''''ex "st''"ring'
|
||||
EOD,
|
||||
'pgsql' => <<<EOD
|
||||
'Co''mpl''''ex "st''"ring'
|
||||
EOD,
|
||||
'oracle' => <<<EOD
|
||||
'Co''mpl''''ex "st''"ring'
|
||||
EOD
|
||||
];
|
||||
|
||||
$this->assertEquals($expected[$type], $quotedString);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::columnQuote()
|
||||
*/
|
||||
public function testColumnQuote()
|
||||
{
|
||||
$this->assertEquals('"ColumnName"', $this->database->columnQuote("ColumnName"));
|
||||
$this->assertEquals('"Column"."name"', $this->database->columnQuote("Column.name"));
|
||||
$this->assertEquals('"Column"."Name"', $this->database->columnQuote("Column.Name"));
|
||||
|
||||
$this->assertEquals('"ネーム"', $this->database->columnQuote("ネーム"));
|
||||
}
|
||||
|
||||
public function columnNamesProvider(): array
|
||||
{
|
||||
return [
|
||||
["9ColumnName"],
|
||||
["@ColumnName"],
|
||||
[".ColumnName"],
|
||||
["ColumnName."],
|
||||
["ColumnName (alias)"]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::columnQuote()
|
||||
* @dataProvider columnNamesProvider
|
||||
*/
|
||||
public function testIncorrectColumnQuote($column)
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
$this->database->columnQuote($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::tableQuote()
|
||||
*/
|
||||
public function testTableQuote()
|
||||
{
|
||||
$this->assertEquals('"TableName"', $this->database->tableQuote("TableName"));
|
||||
$this->assertEquals('"_table"', $this->database->tableQuote("_table"));
|
||||
|
||||
$this->assertEquals('"アカウント"', $this->database->tableQuote("アカウント"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::tableQuote()
|
||||
*/
|
||||
public function testPrefixTableQuote()
|
||||
{
|
||||
$database = new Medoo([
|
||||
'testMode' => true,
|
||||
'prefix' => 'PREFIX_'
|
||||
]);
|
||||
|
||||
$this->assertEquals('"PREFIX_TableName"', $database->tableQuote("TableName"));
|
||||
}
|
||||
|
||||
public function tableNamesProvider(): array
|
||||
{
|
||||
return [
|
||||
["9TableName"],
|
||||
["@TableName"],
|
||||
[".TableName"],
|
||||
["TableName."],
|
||||
["Table.name"]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::tableQuote()
|
||||
* @dataProvider tableNamesProvider
|
||||
*/
|
||||
public function testIncorrectTableQuote($table)
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
$this->database->tableQuote($table);
|
||||
}
|
||||
}
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
namespace Medoo\Tests;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Medoo\Medoo
|
||||
*/
|
||||
class RandTest extends MedooTestCase
|
||||
{
|
||||
/**
|
||||
* @covers ::rand()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testRand($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->rand("account", [
|
||||
"user_name"
|
||||
]);
|
||||
|
||||
$this->assertQuery([
|
||||
'default' => <<<EOD
|
||||
SELECT "user_name"
|
||||
FROM "account"
|
||||
ORDER BY RANDOM()
|
||||
EOD,
|
||||
'mysql' => <<<EOD
|
||||
SELECT `user_name`
|
||||
FROM `account`
|
||||
ORDER BY RAND()
|
||||
EOD,
|
||||
'mssql' => <<<EOD
|
||||
SELECT [user_name]
|
||||
FROM [account]
|
||||
ORDER BY NEWID()
|
||||
EOD
|
||||
], $this->database->queryString);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::rand()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testWhereRand($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->rand("account", [
|
||||
"user_name"
|
||||
], [
|
||||
"location" => "Tokyo"
|
||||
]);
|
||||
|
||||
$this->assertQuery([
|
||||
'default' => <<<EOD
|
||||
SELECT "user_name"
|
||||
FROM "account"
|
||||
WHERE "location" = 'Tokyo'
|
||||
ORDER BY RANDOM()
|
||||
EOD,
|
||||
'mysql' => <<<EOD
|
||||
SELECT `user_name`
|
||||
FROM `account`
|
||||
WHERE `location` = 'Tokyo'
|
||||
ORDER BY RAND()
|
||||
EOD,
|
||||
'mssql' => <<<EOD
|
||||
SELECT [user_name]
|
||||
FROM [account]
|
||||
WHERE [location] = 'Tokyo'
|
||||
ORDER BY NEWID()
|
||||
EOD
|
||||
], $this->database->queryString);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::rand()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testWhereWithJoinRand($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->rand("account", [
|
||||
"[>]album" => "user_id"
|
||||
], [
|
||||
"account.user_name"
|
||||
], [
|
||||
"album.location" => "Tokyo"
|
||||
]);
|
||||
|
||||
$this->assertQuery([
|
||||
'default' => <<<EOD
|
||||
SELECT "account"."user_name"
|
||||
FROM "account"
|
||||
LEFT JOIN "album" USING ("user_id")
|
||||
WHERE "album"."location" = 'Tokyo'
|
||||
ORDER BY RANDOM()
|
||||
EOD,
|
||||
'mysql' => <<<EOD
|
||||
SELECT `account`.`user_name`
|
||||
FROM `account`
|
||||
LEFT JOIN `album` USING (`user_id`)
|
||||
WHERE `album`.`location` = 'Tokyo'
|
||||
ORDER BY RAND()
|
||||
EOD,
|
||||
'mssql' => <<<EOD
|
||||
SELECT [account].[user_name]
|
||||
FROM [account]
|
||||
LEFT JOIN [album] USING ([user_id])
|
||||
WHERE [album].[location] = 'Tokyo'
|
||||
ORDER BY NEWID()
|
||||
EOD
|
||||
], $this->database->queryString);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::rand()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testWithJoinRand($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->rand("account", [
|
||||
"[>]album" => "user_id"
|
||||
], [
|
||||
"account.user_name"
|
||||
]);
|
||||
|
||||
$this->assertQuery([
|
||||
'default' => <<<EOD
|
||||
SELECT "account"."user_name"
|
||||
FROM "account"
|
||||
LEFT JOIN "album" USING ("user_id")
|
||||
ORDER BY RANDOM()
|
||||
EOD,
|
||||
'mysql' => <<<EOD
|
||||
SELECT `account`.`user_name`
|
||||
FROM `account`
|
||||
LEFT JOIN `album` USING (`user_id`)
|
||||
ORDER BY RAND()
|
||||
EOD,
|
||||
'mssql' => <<<EOD
|
||||
SELECT [account].[user_name]
|
||||
FROM [account]
|
||||
LEFT JOIN [album] USING ([user_id])
|
||||
ORDER BY NEWID()
|
||||
EOD
|
||||
], $this->database->queryString);
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Medoo\Tests;
|
||||
|
||||
use Medoo\Medoo;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Medoo\Medoo
|
||||
*/
|
||||
class RawTest extends MedooTestCase
|
||||
{
|
||||
/**
|
||||
* @covers ::raw()
|
||||
* @covers ::isRaw()
|
||||
* @covers ::buildRaw()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testRawWithPlaceholder($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select('account', [
|
||||
'score' => Medoo::raw('SUM(<age> + <experience>)')
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT SUM("age" + "experience") AS "score"
|
||||
FROM "account"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::raw()
|
||||
* @covers ::isRaw()
|
||||
* @covers ::buildRaw()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testRawWithSamePlaceholderName($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select('account', [
|
||||
'system' => Medoo::raw("COUNT(<system> = 'window' OR <system> = 'mac')")
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT COUNT("system" = 'window' OR "system" = 'mac') AS "system"
|
||||
FROM "account"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Medoo\Tests;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Medoo\Medoo
|
||||
*/
|
||||
class ReplaceTest extends MedooTestCase
|
||||
{
|
||||
/**
|
||||
* @covers ::replace()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testReplace($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->replace("account", [
|
||||
"type" => [
|
||||
"user" => "new_user",
|
||||
"business" => "new_business"
|
||||
],
|
||||
"column" => [
|
||||
"old_value" => "new_value"
|
||||
]
|
||||
], [
|
||||
"user_id[>]" => 1000
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
UPDATE "account"
|
||||
SET "type" = REPLACE("type", 'user', 'new_user'),
|
||||
"type" = REPLACE("type", 'business', 'new_business'),
|
||||
"column" = REPLACE("column", 'old_value', 'new_value')
|
||||
WHERE "user_id" > 1000
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::replace()
|
||||
*/
|
||||
public function testReplaceEmptyColumns()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
$this->database->replace("account", [], [
|
||||
"user_id[>]" => 1000
|
||||
]);
|
||||
}
|
||||
}
|
||||
+715
@@ -0,0 +1,715 @@
|
||||
<?php
|
||||
|
||||
namespace Medoo\Tests;
|
||||
|
||||
use Medoo\Medoo;
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Medoo\Medoo
|
||||
*/
|
||||
class SelectTest extends MedooTestCase
|
||||
{
|
||||
/**
|
||||
* @covers ::select()
|
||||
* @covers ::selectContext()
|
||||
* @covers ::isJoin()
|
||||
* @covers ::columnMap()
|
||||
* @covers ::columnPush()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectAll($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", "*");
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT * FROM "account"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::select()
|
||||
* @covers ::selectContext()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectTableWithAlias($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account (user)", "name");
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "name"
|
||||
FROM "account" @AS "user"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::columnMap()
|
||||
* @covers ::columnPush()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectSingleColumn($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", "name");
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "name"
|
||||
FROM "account"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::columnMap()
|
||||
* @covers ::columnPush()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectColumns($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", ["name", "id"]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "name","id"
|
||||
FROM "account"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::columnMap()
|
||||
* @covers ::columnPush()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectColumnsWithAlias($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", ["name(nickname)", "id"]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "name" AS "nickname","id"
|
||||
FROM "account"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::columnMap()
|
||||
* @covers ::columnPush()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectColumnsWithType($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", ["name[String]", "data [JSON]"]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "name","data"
|
||||
FROM "account"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::columnMap()
|
||||
* @covers ::columnPush()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectColumnsWithAliasAndType($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", ["name (nickname) [String]", "data [JSON]"]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "name" AS "nickname","data"
|
||||
FROM "account"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::columnMap()
|
||||
* @covers ::columnPush()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectColumnsWithRaw($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", [
|
||||
"id [String]" => Medoo::raw("UUID()")
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT UUID() AS "id"
|
||||
FROM "account"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::select()
|
||||
* @covers ::selectContext()
|
||||
* @covers ::isJoin()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectWithWhere($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", [
|
||||
"name",
|
||||
"id"
|
||||
], [
|
||||
"ORDER" => "age"
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "name","id"
|
||||
FROM "account"
|
||||
ORDER BY "age"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::select()
|
||||
* @covers ::selectContext()
|
||||
* @covers ::isJoin()
|
||||
* @covers ::buildJoin()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectWithLeftJoin($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", [
|
||||
"[>]post" => "user_id"
|
||||
], [
|
||||
"account.name",
|
||||
"post.title"
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "account"."name","post"."title"
|
||||
FROM "account"
|
||||
LEFT JOIN "post"
|
||||
USING ("user_id")
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::isJoin()
|
||||
* @covers ::buildJoin()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectWithRightJoin($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", [
|
||||
"[<]post" => "user_id"
|
||||
], [
|
||||
"account.name",
|
||||
"post.title"
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "account"."name","post"."title"
|
||||
FROM "account"
|
||||
RIGHT JOIN "post"
|
||||
USING ("user_id")
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::isJoin()
|
||||
* @covers ::buildJoin()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectWithFullJoin($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", [
|
||||
"[<>]post" => "user_id"
|
||||
], [
|
||||
"account.name",
|
||||
"post.title"
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "account"."name","post"."title"
|
||||
FROM "account"
|
||||
FULL JOIN "post"
|
||||
USING ("user_id")
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::isJoin()
|
||||
* @covers ::buildJoin()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectWithInnerJoin($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", [
|
||||
"[><]post" => "user_id"
|
||||
], [
|
||||
"account.name",
|
||||
"post.title"
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "account"."name","post"."title"
|
||||
FROM "account"
|
||||
INNER JOIN "post"
|
||||
USING ("user_id")
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::isJoin()
|
||||
* @covers ::buildJoin()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectWithSameKeysJoin($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", [
|
||||
"[>]photo" => ["user_id", "avatar_id"],
|
||||
], [
|
||||
"account.name",
|
||||
"photo.link"
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "account"."name","photo"."link"
|
||||
FROM "account"
|
||||
LEFT JOIN "photo"
|
||||
USING ("user_id", "avatar_id")
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::isJoin()
|
||||
* @covers ::buildJoin()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectWithKeyJoin($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", [
|
||||
"[>]post" => ["user_id" => "author_id"],
|
||||
], [
|
||||
"account.name",
|
||||
"post.title"
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "account"."name","post"."title"
|
||||
FROM "account"
|
||||
LEFT JOIN "post"
|
||||
ON "account"."user_id" = "post"."author_id"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::isJoin()
|
||||
* @covers ::buildJoin()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectWithAliasJoin($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", [
|
||||
"[>]post (main_post)" => ["user_id" => "author_id"],
|
||||
], [
|
||||
"account.name",
|
||||
"main_post.title"
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "account"."name","main_post"."title"
|
||||
FROM "account"
|
||||
LEFT JOIN "post" @AS "main_post"
|
||||
ON "account"."user_id" = "main_post"."author_id"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::isJoin()
|
||||
* @covers ::buildJoin()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectWithReferJoin($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", [
|
||||
"[>]post" => ["user_id" => "author_id"],
|
||||
"[>]album" => ["post.author_id" => "user_id"],
|
||||
], [
|
||||
"account.name",
|
||||
"post.title",
|
||||
"album.link"
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "account"."name","post"."title","album"."link"
|
||||
FROM "account"
|
||||
LEFT JOIN "post"
|
||||
ON "account"."user_id" = "post"."author_id"
|
||||
LEFT JOIN "album"
|
||||
ON "post"."author_id" = "album"."user_id"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::isJoin()
|
||||
* @covers ::buildJoin()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectWithMultipleConditionJoin($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", [
|
||||
"[>]album" => ["author_id" => "user_id"],
|
||||
"[>]post" => [
|
||||
"user_id" => "author_id",
|
||||
"album.user_id" => "owner_id"
|
||||
]
|
||||
], [
|
||||
"account.name",
|
||||
"post.title",
|
||||
"album.link"
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "account"."name","post"."title","album"."link"
|
||||
FROM "account"
|
||||
LEFT JOIN "album"
|
||||
ON "account"."author_id" = "album"."user_id"
|
||||
LEFT JOIN "post"
|
||||
ON "account"."user_id" = "post"."author_id"
|
||||
AND "album"."user_id" = "post"."owner_id"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::isJoin()
|
||||
* @covers ::buildJoin()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectWithAdditionalConditionJoin($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", [
|
||||
"[>]post" => [
|
||||
"user_id" => "author_id",
|
||||
"AND" => [
|
||||
"post.id[>]" => 10
|
||||
]
|
||||
]
|
||||
], [
|
||||
"account.name",
|
||||
"post.title"
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "account"."name","post"."title"
|
||||
FROM "account"
|
||||
LEFT JOIN "post"
|
||||
ON "account"."user_id" = "post"."author_id"
|
||||
AND "post"."id" > 10
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::isJoin()
|
||||
* @covers ::buildJoin()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectRawJoin($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", [
|
||||
"[>]post" => Medoo::raw("ON <account.user_id> = <post.author_id>")
|
||||
], [
|
||||
"account.name",
|
||||
"post.title"
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "account"."name","post"."title"
|
||||
FROM "account"
|
||||
LEFT JOIN "post"
|
||||
ON "account"."user_id" = "post"."author_id"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::columnMap()
|
||||
* @covers ::columnPush()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectAllWithJoin($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
$this->database->select("account", [
|
||||
"[>]post" => "user_id"
|
||||
], [
|
||||
"account.*"
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::columnMap()
|
||||
* @covers ::columnPush()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectWithDataMapping($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("post", [
|
||||
"[>]account" => ["user_id"]
|
||||
], [
|
||||
"post.content",
|
||||
|
||||
"userData" => [
|
||||
"account.user_id",
|
||||
"account.email",
|
||||
|
||||
"meta" => [
|
||||
"account.location",
|
||||
"account.gender"
|
||||
]
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "post"."content","account"."user_id","account"."email","account"."location","account"."gender"
|
||||
FROM "post"
|
||||
LEFT JOIN "account"
|
||||
USING ("user_id")
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::columnMap()
|
||||
* @covers ::columnPush()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectWithIndexMapping($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", [
|
||||
"user_id" => [
|
||||
"name (nickname)",
|
||||
"location"
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "user_id","name" AS "nickname","location"
|
||||
FROM "account"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::columnMap()
|
||||
* @covers ::columnPush()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectWithDistinct($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", [
|
||||
"@location",
|
||||
"nickname"
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT DISTINCT "location","nickname"
|
||||
FROM "account"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::columnMap()
|
||||
* @covers ::columnPush()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectWithDistinctDiffOrder($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", [
|
||||
"location",
|
||||
"@nickname"
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT DISTINCT "nickname","location"
|
||||
FROM "account"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::columnMap()
|
||||
* @covers ::columnPush()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectWithUnicodeCharacter($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("considérer", [
|
||||
"name (名前)",
|
||||
"положение (ロケーション)"
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "name" AS "名前","положение" AS "ロケーション"
|
||||
FROM "considérer"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::columnMap()
|
||||
* @covers ::columnPush()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectWithHyphenCharacter($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("account", [
|
||||
"nick-name"
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "nick-name"
|
||||
FROM "account"
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::columnMap()
|
||||
* @covers ::columnPush()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testSelectWithSingleCharacter($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$this->database->select("a", [
|
||||
"[>]e" => ["f"]
|
||||
], [
|
||||
"b (c)"
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
SELECT "b" AS "c"
|
||||
FROM "a"
|
||||
LEFT JOIN "e" USING ("f")
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace Medoo\Tests;
|
||||
|
||||
use Medoo\Medoo;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Medoo\Medoo
|
||||
*/
|
||||
class UpdateTest extends MedooTestCase
|
||||
{
|
||||
/**
|
||||
* @covers \Medoo\Medoo::update()
|
||||
* @dataProvider typesProvider
|
||||
*/
|
||||
public function testUpdate($type)
|
||||
{
|
||||
$this->setType($type);
|
||||
|
||||
$objectData = new Foo();
|
||||
|
||||
$this->database->update("account", [
|
||||
"type" => "user",
|
||||
"money" => 23.2,
|
||||
"age[+]" => 1,
|
||||
"level[-]" => 5,
|
||||
"score[*]" => 2,
|
||||
"lang" => ["en", "fr"],
|
||||
"lang [JSON]" => ["en", "fr"],
|
||||
"is_locked" => true,
|
||||
"uuid" => Medoo::raw("UUID()"),
|
||||
"object" => $objectData
|
||||
], [
|
||||
"user_id[<]" => 1000
|
||||
]);
|
||||
|
||||
$this->assertQuery([
|
||||
'default' => <<<EOD
|
||||
UPDATE "account"
|
||||
SET "type" = 'user',
|
||||
"money" = '23.2',
|
||||
"age" = "age" + 1,
|
||||
"level" = "level" - 5,
|
||||
"score" = "score" * 2,
|
||||
"lang" = 'a:2:{i:0;s:2:"en";i:1;s:2:"fr";}',
|
||||
"lang" = '["en","fr"]',
|
||||
"is_locked" = 1,
|
||||
"uuid" = UUID(),
|
||||
"object" = :MeD5_mK
|
||||
WHERE "user_id" < 1000
|
||||
EOD,
|
||||
'mysql' => <<<EOD
|
||||
UPDATE "account"
|
||||
SET "type" = 'user',
|
||||
"money" = '23.2',
|
||||
"age" = "age" + 1,
|
||||
"level" = "level" - 5,
|
||||
"score" = "score" * 2,
|
||||
"lang" = 'a:2:{i:0;s:2:\"en\";i:1;s:2:\"fr\";}',
|
||||
"lang" = '[\"en\",\"fr\"]',
|
||||
"is_locked" = 1,
|
||||
"uuid" = UUID(),
|
||||
"object" = :MeD5_mK
|
||||
WHERE "user_id" < 1000
|
||||
EOD,
|
||||
], $this->database->queryString);
|
||||
}
|
||||
|
||||
public function testOracleLOBsUpdate()
|
||||
{
|
||||
$this->setType("oracle");
|
||||
|
||||
$fp = fopen('README.md', 'r');
|
||||
|
||||
$this->database->update("ACCOUNT", [
|
||||
"DATA" => $fp
|
||||
], [
|
||||
"ID" => 1
|
||||
]);
|
||||
|
||||
$this->assertQuery(
|
||||
<<<EOD
|
||||
UPDATE "ACCOUNT"
|
||||
SET "DATA" = EMPTY_BLOB()
|
||||
WHERE "ID" = 1
|
||||
RETURNING "DATA" INTO :MeD0_mK
|
||||
EOD,
|
||||
$this->database->queryString
|
||||
);
|
||||
}
|
||||
}
|
||||
+1177
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user