Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 40 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,20 @@ Library on [Packagist](https://packagist.org/packages/gin0115/pixie-wpdb).
- [Where In](#where-in)
- [Where Between](#where-between)
- [Where Null](#where-null)
- [Grouped Where](#grouped-where)
- [Where Date](#where-date)
- [Where Day](#where-day)
- [Where Month](#where-month)
- [Where Year](#where-year)
- [Grouped Where](#grouped-where)
- [Group By and Order By](#group-by-and-order-by)
- [Having](#having)
- [Limit and Offset](#limit-and-offset)
- [Join](#join)
- [Join Using](#join-using)
- [Multiple Join Criteria](#multiple-join-criteria)
- [Raw Query](#raw-query)
- [Raw Expressions](#raw-expressions)
- [Value Binding](#bindings)
- [Value Binding](#value-binding)
- [**Insert**](#insert)
- [Batch Insert](#batch-insert)
- [Insert with ON DUPLICATE KEY statement](#insert-with-on-duplicate-key-statement)
Expand Down Expand Up @@ -285,6 +290,30 @@ QB::table('my_table')
->orWhereNotNull('field4');
```

### Where Date
```PHP
QB::table('my_table')
->whereDate('column', '<', '2020-12-29'); // All where date after 29 Dec 2020
```

### Where Day
```PHP
QB::table('my_table')
->whereDay('date_column', '=', '29'); // All where day is 29 in any date formats
```

### Where Month
```PHP
QB::table('my_table')
->whereMonth('date_column', '=', '12'); // All where month is december in any date formats
```

### Where Year
```PHP
QB::table('my_table')
->whereYear('date_column', '=', '2015'); // All where year is 2015 in any date formats
```

#### Grouped Where
Sometimes queries get complex, where you need grouped criteria, for example `WHERE age = 10 and (name like '%usman%' or description LIKE '%usman%')`.

Expand Down Expand Up @@ -344,7 +373,7 @@ Available methods,

### Join Using

It is possible to create a simple join statment between 2 tables, where they are matched on the same key names.
It is possible to create a simple join statement between 2 tables, where they are matched on the same key names.

```php
->table('foo')->join('bar', 'bar.id', '=', 'foo.id');
Expand Down Expand Up @@ -412,14 +441,14 @@ QB::table('my_table')
Neither of the above string would be automatically wrapped in `'single quotes'`.

**Types**

`Binding::asString($value)`
`Binding::asInt($value)`
`Binding::asFloat($value)`
`Binding::asBool($value)`
`Binding::asJson($value)`
`Binding::asRaw($value)`

```php
Binding::asString($value);
Binding::asInt($value);
Binding::asFloat($value);
Binding::asBool($value);
Binding::asJson($value);
Binding::asRaw($value);
```

### Insert
```PHP
Expand Down
79 changes: 79 additions & 0 deletions src/QueryBuilder/QueryBuilderHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -926,6 +926,85 @@ public function orWhereBetween($key, $valueFrom, $valueTo): self
return $this->whereHandler($key, 'BETWEEN', [$valueFrom, $valueTo], 'OR');
}

/**
* Handles all function call based where conditions
*
* @param string|Raw $key
* @param string $function
* @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
* @param mixed|null $value
* @return static
*/
protected function whereFunctionCallHandler($key, $function, $operator, $value): self
{
$key = \sprintf('%s(%s)', $function, $this->addTablePrefix($key));
return $this->where($key, $operator, $value);
}

/**
* @param string|Raw $key
* @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
* @param mixed|null $value
* @return self
*/
public function whereMonth($key, $operator = null, $value = null): self
{
// If two params are given then assume operator is =
if (2 == func_num_args()) {
$value = $operator;
$operator = '=';
}
return $this->whereFunctionCallHandler($key, 'MONTH', $operator, $value);
}

/**
* @param string|Raw $key
* @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
* @param mixed|null $value
* @return self
*/
public function whereDay($key, $operator = null, $value = null): self
{
// If two params are given then assume operator is =
if (2 == func_num_args()) {
$value = $operator;
$operator = '=';
}
return $this->whereFunctionCallHandler($key, 'DAY', $operator, $value);
}

/**
* @param string|Raw $key
* @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
* @param mixed|null $value
* @return self
*/
public function whereYear($key, $operator = null, $value = null): self
{
// If two params are given then assume operator is =
if (2 == func_num_args()) {
$value = $operator;
$operator = '=';
}
return $this->whereFunctionCallHandler($key, 'YEAR', $operator, $value);
}

/**
* @param string|Raw $key
* @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
* @param mixed|null $value
* @return self
*/
public function whereDate($key, $operator = null, $value = null): self
{
// If two params are given then assume operator is =
if (2 == func_num_args()) {
$value = $operator;
$operator = '=';
}
return $this->whereFunctionCallHandler($key, 'DATE', $operator, $value);
}

/**
* @param string|Raw $key
*
Expand Down
142 changes: 142 additions & 0 deletions tests/TestIntegrationWithWPDB.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@

use stdClass;
use Exception;
use Pixie\Binding;
use WP_UnitTestCase;
use Pixie\Connection;
use Pixie\QueryBuilder\Raw;
use Pixie\Tests\Logable_WPDB;
use Pixie\Tests\Fixtures\ModelForMockFoo;
use Pixie\QueryBuilder\QueryBuilderHandler;
Expand Down Expand Up @@ -61,9 +63,31 @@ public function createTables(): void
)
COLLATE {$this->wpdb->collate}";

$sqlJson =
"CREATE TABLE mock_json (
id mediumint(8) unsigned NOT NULL auto_increment ,
string varchar(255) NULL,
json json NULL,
PRIMARY KEY (id)
)
COLLATE {$this->wpdb->collate}";

$sqlDates =
"CREATE TABLE mock_dates (
id mediumint(8) unsigned NOT NULL auto_increment ,
date DATE NULL,
datetime DATETIME NULL,
unix TIMESTAMP NULL,
time TIME NULL,
PRIMARY KEY (id)
)
COLLATE {$this->wpdb->collate}";

require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sqlFoo);
dbDelta($sqlBar);
dbDelta($sqlJson);
dbDelta($sqlDates);

static::$createdTables = true;
}
Expand Down Expand Up @@ -537,4 +561,122 @@ public function testFindOrFail(): void

$row = $builder->findOrFail('Forth', 'string');
}

/** @testdox It should be possible to query a date column by month */
public function testWhereMonth(): void
{
$this->wpdb->insert('mock_dates', ['date' => '2020-10-10', 'unix' => '2020-10-10 18:19:03', 'datetime' => '2020-10-10 18:19:03'], ['%s', '%s']);
$this->wpdb->insert('mock_dates', ['date' => '2002-10-05', 'unix' => '2002-10-10 18:19:03', 'datetime' => '2002-10-10 18:19:03'], ['%s', '%s']);
$this->wpdb->insert('mock_dates', ['date' => '2002-3-3', 'unix' => '2002-3-3 18:19:03', 'datetime' => '2002-3-3 18:19:03'], ['%s', '%s']);

$month3 = $this->queryBuilderProvider('mock_')
->table('dates')
->whereMonth('unix', Binding::asString(3))
->get();

$this->assertCount(1, $month3);
$this->assertEquals('2002-03-03', $month3[0]->date);

$month10 = $this->queryBuilderProvider('mock_')
->table('dates')
->whereMonth('date', '>', 9)
->get();

$this->assertCount(2, $month10);
$this->assertEquals('2020-10-10', $month10[0]->date);
$this->assertEquals('2002-10-05', $month10[1]->date);
}

/** @testdox It should be possible to query a date column by day */
public function testWhereDay(): void
{
$this->wpdb->insert('mock_dates', ['date' => '2020-10-10', 'unix' => '2020-10-10 18:19:03', 'datetime' => '2020-10-10 18:19:03'], ['%s', '%s']);
$this->wpdb->insert('mock_dates', ['date' => '2010-10-05', 'unix' => '2010-10-05 18:19:03', 'datetime' => '2010-10-05 18:19:03'], ['%s', '%s']);
$this->wpdb->insert('mock_dates', ['date' => '2002-03-12', 'unix' => '2002-03-12 18:19:03', 'datetime' => '2002-03-12 18:19:03'], ['%s', '%s']);

$day5 = $this->queryBuilderProvider('mock_')
->table('dates')
->whereDay('unix', Binding::asString(5))
->get();
$this->assertCount(1, $day5);
$this->assertEquals('2010-10-05', $day5[0]->date);

$dayAbove9 = $this->queryBuilderProvider('mock_')
->table('dates')
->whereDay('date', '>', 9)
->get();

$this->assertCount(2, $dayAbove9);
$this->assertEquals('2020-10-10', $dayAbove9[0]->date);
$this->assertEquals('2002-03-12', $dayAbove9[1]->date);

$day10 = $this->queryBuilderProvider('mock_')
->table('dates')
->whereDay('datetime', Binding::asString(10))
->get();
$this->assertCount(1, $day10);
$this->assertEquals('2020-10-10', $day10[0]->date);
}

/** @testdox It should be possible to query a date column by year */
public function testWhereYear(): void
{
$this->wpdb->insert('mock_dates', ['date' => '2022-10-10', 'unix' => '2022-10-10 18:19:03', 'datetime' => '2022-10-10 18:19:03'], ['%s', '%s']);
$this->wpdb->insert('mock_dates', ['date' => '2010-10-05', 'unix' => '2010-10-05 18:19:03', 'datetime' => '2010-10-05 18:19:03'], ['%s', '%s']);
$this->wpdb->insert('mock_dates', ['date' => '2020-03-12', 'unix' => '2020-03-12 18:19:03', 'datetime' => '2020-03-12 18:19:03'], ['%s', '%s']);

$only2010 = $this->queryBuilderProvider('mock_')
->table('dates')
->whereYear('unix', Binding::asString(2010))
->get();
$this->assertCount(1, $only2010);
$this->assertEquals('2010-10-05', $only2010[0]->date);

$after2009 = $this->queryBuilderProvider('mock_')
->table('dates')
->whereYear('date', '>', new Raw('%d', [2019]))
->get();

$this->assertCount(2, $after2009);
$this->assertEquals('2022-10-10', $after2009[0]->date);
$this->assertEquals('2020-03-12', $after2009[1]->date);

$only2022 = $this->queryBuilderProvider('mock_')
->table('dates')
->whereYear('datetime', Binding::asFloat(2022))
->get();
$this->assertCount(1, $only2022);
$this->assertEquals('2022-10-10', $only2022[0]->date);
}

/** @testdox It should be possible to query a date column by date */
public function testWhereDate(): void
{
$this->wpdb->insert('mock_dates', ['date' => '2022-10-10', 'unix' => '2022-10-10 18:19:03', 'datetime' => '2022-10-10 18:19:03'], ['%s', '%s']);
$this->wpdb->insert('mock_dates', ['date' => '2010-10-05', 'unix' => '2010-10-05 18:19:03', 'datetime' => '2010-10-05 18:19:03'], ['%s', '%s']);
$this->wpdb->insert('mock_dates', ['date' => '2020-03-12', 'unix' => '2020-03-12 18:19:03', 'datetime' => '2020-03-12 18:19:03'], ['%s', '%s']);

$resultA = $this->queryBuilderProvider('mock_')
->table('dates')
->whereDate('unix', Binding::asString('2010-10-05'))
->get();
$this->assertCount(1, $resultA);
$this->assertEquals('2010-10-05', $resultA[0]->date);

$resultB = $this->queryBuilderProvider('mock_')
->table('dates')
->whereDate('date', '!=', new Raw('%s', ['2020-03-12']))
->get();

$this->assertCount(2, $resultB);
$this->assertEquals('2022-10-10', $resultB[0]->date);
$this->assertEquals('2010-10-05', $resultB[1]->date);

$resultC = $this->queryBuilderProvider('mock_')
->table('dates')
->whereDate('datetime', date("Y-m-d", 1665425943)) // strtotime('2022-10-10 18:19:03')
->get();
$this->assertCount(1, $resultC);
$this->assertEquals('2022-10-10', $resultC[0]->date);
}
}