diff --git a/composer.json b/composer.json index 2d6f2c0..4ee2677 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "jfelder/oracledb", "description": "Oracle DB driver for Laravel", - "keywords": ["oracle", "laravel", "laravel 6", "pdo_oci", "oci8"], + "keywords": ["oracle", "laravel", "laravel 7", "pdo_oci", "oci8"], "license": "MIT", "authors": [ { @@ -10,15 +10,14 @@ } ], "require": { - "php": "^7.2", - "illuminate/support": "^6.0", - "illuminate/database": "^6.0", - "illuminate/pagination": "^6.0" + "php": "^7.2.5", + "illuminate/support": "^7.0", + "illuminate/database": "^7.0", + "illuminate/pagination": "^7.0" }, "require-dev": { - "fzaninotto/faker": "^1.9.1", - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^8.0" + "mockery/mockery": "^1.3.1", + "phpunit/phpunit": "^9.0" }, "autoload": { "psr-4": { diff --git a/readme.md b/readme.md index 0a938c8..51c1739 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@ ## Laravel Oracle Database Package -### OracleDB (updated for Laravel 6.x) +### OracleDB (updated for Laravel 7.x) [![Latest Stable Version](https://poser.pugx.org/jfelder/oracledb/v/stable.png)](https://packagist.org/packages/jfelder/oracledb) [![Total Downloads](https://poser.pugx.org/jfelder/oracledb/downloads.png)](https://packagist.org/packages/jfelder/oracledb) [![Build Status](https://travis-ci.org/jfelder/Laravel-OracleDB.png)](https://travis-ci.org/jfelder/Laravel-OracleDB) @@ -21,7 +21,7 @@ Add `jfelder/oracledb` as a requirement to composer.json: ```json { "require": { - "jfelder/oracledb": "6.*" + "jfelder/oracledb": "7.*" } } ``` @@ -77,7 +77,7 @@ in config/oracledb.php file. > **Note:** When using the insertGetId method, you can specify the auto-incrementing column name as the second parameter in insertGetId function. It will default to "id" if not specified. -See [Laravel Database Basic Docs](https://laravel.com/docs/6.x/database) for more information. +See [Laravel Database Basic Docs](https://laravel.com/docs/7.x/database) for more information. ### Unimplemented Features @@ -88,6 +88,7 @@ Some of the features available in the first-party Laravel database drivers are n - insertOrIgnore `DB::from('users')->insertOrIgnore(['email' => 'foo']);` - insertGetId with empty values `DB::from('users')->insertGetId([]);` (but calling with non-empty values is supported) - deleting with a join `DB::from('users')->join('contacts', 'users.id', '=', 'contacts.id')->where('users.email', '=', 'foo')->delete();` +- deleting with a limit `DB::from('users')->where('email', '=', 'foo')->orderBy('id')->take(1)->delete();` - json operations `DB::from('users')->where('items->sku', '=', 'foo-bar')->get();` #### Schema Builder @@ -108,6 +109,7 @@ Some of the features available in the first-party Laravel database drivers are n - create a datetime with timezone column without precision `$blueprint->dateTimeTz('created_at')`, or with precision `$blueprint->timestampTz('created_at', 1)` - create Laravel-style timestamp columns having a timezone component `$blueprint->timestampsTz()` - create a uuid column `$blueprint->uuid('foo')` (oracle recommends a column of data type 16 byte raw for storing uuids) +- create a foreign uuid column `$blueprint->foreignUuid('foo')` - create a column to hold IP addresses `$blueprint->ipAddress('foo')` (would be implemented as varchar2 45) - create a column to hold MAC addresses `$blueprint->macAddress('foo')` (would be implemented as varchar2 17) - create a geometry column `$blueprint->geometry('coordinates')` @@ -120,6 +122,7 @@ Some of the features available in the first-party Laravel database drivers are n - create a multilinestring column `$blueprint->multilinestring('coordinates')` - create a multipolygon column `$blueprint->multipolygon('coordinates')` - create a double column without specifying second or third parameters `$blueprint->double('foo')` (but `$blueprint->double('foo', 5, 2)` is supported) +- create a timestamp column with `useCurrent` modifier `$blueprint->timestamp('created_at')->useCurrent()` ### License diff --git a/tests/OracleDBQueryBuilderTest.php b/tests/OracleDBQueryBuilderTest.php index 723c8cb..12fa6fd 100644 --- a/tests/OracleDBQueryBuilderTest.php +++ b/tests/OracleDBQueryBuilderTest.php @@ -575,6 +575,14 @@ public function testWhereIntegerInRaw() $this->assertEquals([], $builder->getBindings()); } + public function testOrWhereIntegerInRaw() + { + $builder = $this->getOracleBuilder(); + $builder->select('*')->from('users')->where('id', '=', 1)->orWhereIntegerInRaw('id', ['1a', 2]); + $this->assertSame('select * from "users" where "id" = ? or "id" in (1, 2)', $builder->toSql()); + $this->assertEquals([0 => 1], $builder->getBindings()); + } + public function testWhereIntegerNotInRaw() { $builder = $this->getOracleBuilder(); @@ -583,6 +591,14 @@ public function testWhereIntegerNotInRaw() $this->assertEquals([], $builder->getBindings()); } + public function testOrWhereIntegerNotInRaw() + { + $builder = $this->getOracleBuilder(); + $builder->select('*')->from('users')->where('id', '=', 1)->orWhereIntegerNotInRaw('id', ['1a', 2]); + $this->assertSame('select * from "users" where "id" = ? or "id" not in (1, 2)', $builder->toSql()); + $this->assertEquals([0 => 1], $builder->getBindings()); + } + public function testEmptyWhereIntegerInRaw() { $builder = $this->getOracleBuilder(); @@ -743,6 +759,26 @@ public function testBasicWhereNulls() $this->assertEquals([0 => 1], $builder->getBindings()); } + public function testJsonWhereNull() + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('does not support'); + + $builder = $this->getOracleBuilder(); + $builder->select('*')->from('users')->whereNull('items->id'); + $builder->toSql(); + } + + public function testJsonWhereNotNull() + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('does not support'); + + $builder = $this->getOracleBuilder(); + $builder->select('*')->from('users')->whereNotNull('items->id'); + $builder->toSql(); + } + public function testArrayWhereNulls() { $builder = $this->getOracleBuilder(); @@ -839,6 +875,35 @@ public function testOrderBys() $this->assertEquals([1, 1, 'news', 'opinion'], $builder->getBindings()); } + public function testReorder() + { + $builder = $this->getOracleBuilder(); + $builder->select('*')->from('users')->orderBy('name'); + $this->assertSame('select * from "users" order by "name" asc', $builder->toSql()); + $builder->reorder(); + $this->assertSame('select * from "users"', $builder->toSql()); + + $builder = $this->getOracleBuilder(); + $builder->select('*')->from('users')->orderBy('name'); + $this->assertSame('select * from "users" order by "name" asc', $builder->toSql()); + $builder->reorder('email', 'desc'); + $this->assertSame('select * from "users" order by "email" desc', $builder->toSql()); + + $builder = $this->getOracleBuilder(); + $builder->select('*')->from('first'); + $builder->union($this->getOracleBuilder()->select('*')->from('second')); + $builder->orderBy('name'); + $this->assertSame('(select * from "first") union (select * from "second") order by "name" asc', $builder->toSql()); + $builder->reorder(); + $this->assertSame('(select * from "first") union (select * from "second")', $builder->toSql()); + + $builder = $this->getOracleBuilder(); + $builder->select('*')->from('users')->orderByRaw('?', [true]); + $this->assertEquals([true], $builder->getBindings()); + $builder->reorder(); + $this->assertEquals([], $builder->getBindings()); + } + public function testOrderBySubQueries() { $expected = 'select * from "users" order by (select t2.* from ( select rownum AS "rn", t1.* from (select "created_at" from "logins" where "user_id" = "users"."id") t1 ) t2 where t2."rn" between 1 and 1)'; @@ -1852,7 +1917,12 @@ public function testDeleteMethod() $builder = $this->getOracleBuilder(); $builder->getConnection()->shouldReceive('delete')->once()->with('delete from "users" where "users"."id" = ?', [1])->andReturn(1); $result = $builder->from('users')->selectRaw('?', ['ignore'])->delete(1); - $this->assertEquals(1, $result); + $this->assertEquals(1, $result); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('does not support'); + $builder = $this->getOracleBuilder(); + $builder->from('users')->where('email', '=', 'foo')->orderBy('id')->take(1)->delete(); } public function testDeleteWithJoinMethod() @@ -2173,6 +2243,22 @@ public function testSubSelect() $this->assertEquals($expectedBindings, $builder->getBindings()); } + public function testSubSelectResetBindings() + { + $builder = $this->getOracleBuilder(); + $builder->from('one')->selectSub(function ($query) { + $query->from('two')->select('baz')->where('subkey', '=', 'subval'); + }, 'sub'); + + $this->assertEquals('select (select "baz" from "two" where "subkey" = ?) as "sub" from "one"', $builder->toSql()); + $this->assertEquals(['subval'], $builder->getBindings()); + + $builder->select('*'); + + $this->assertEquals('select * from "one"', $builder->toSql()); + $this->assertEquals([], $builder->getBindings()); + } + public function testUppercaseLeadingBooleansAreRemoved() { $builder = $this->getOracleBuilder(); diff --git a/tests/OracleDBSchemaGrammarTest.php b/tests/OracleDBSchemaGrammarTest.php index 0c96599..ee96b38 100644 --- a/tests/OracleDBSchemaGrammarTest.php +++ b/tests/OracleDBSchemaGrammarTest.php @@ -2,6 +2,7 @@ use Illuminate\Database\Query\Expression; use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Schema\ForeignIdColumnDefinition; use Mockery as m; use PHPUnit\Framework\TestCase; @@ -361,6 +362,16 @@ public function testAddingIndex() $this->assertEquals('create index baz on users ( foo, bar )', $statements[0]); } + public function testAddingRawIndex() + { + $blueprint = new Blueprint('users'); + $blueprint->rawIndex('(function(column))', 'raw_index'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('create index raw_index on users ( (function(column)) )', $statements[0]); + } + public function testAddingForeignKey() { $blueprint = new Blueprint('users'); @@ -369,6 +380,13 @@ public function testAddingForeignKey() $this->assertEquals(1, count($statements)); $this->assertEquals('alter table users add constraint users_foo_id_foreign foreign key ( foo_id ) references orders ( id )', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->foreign('foo_id')->references('id')->on('orders')->cascadeOnDelete(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table users add constraint users_foo_id_foreign foreign key ( foo_id ) references orders ( id ) on delete cascade', $statements[0]); } public function testAddingForeignKeyWithCascadeDelete() @@ -401,6 +419,44 @@ public function testAddingSmallIncrementingID() $this->assertSame('alter table users add ( id number(5,0) not null, constraint users_id_primary primary key ( id ) )', $statements[0]); } + public function testAddingID() + { + $blueprint = new Blueprint('users'); + $blueprint->id(); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table users add ( id number(19,0) not null, constraint users_id_primary primary key ( id ) )', $statements[0]); + + $blueprint = new Blueprint('users'); + $blueprint->id('foo'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(1, $statements); + $this->assertSame('alter table users add ( foo number(19,0) not null, constraint users_foo_primary primary key ( foo ) )', $statements[0]); + } + + public function testAddingForeignID() + { + $blueprint = new Blueprint('users'); + $foreignId = $blueprint->foreignId('foo'); + $blueprint->foreignId('company_id')->constrained(); + $blueprint->foreignId('laravel_idea_id')->constrained(); + $blueprint->foreignId('team_id')->references('id')->on('teams'); + $blueprint->foreignId('team_column_id')->constrained('teams'); + + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertInstanceOf(ForeignIdColumnDefinition::class, $foreignId); + $this->assertSame([ + 'alter table users add ( foo number(19,0) not null, company_id number(19,0) not null, laravel_idea_id number(19,0) not null, team_id number(19,0) not null, team_column_id number(19,0) not null )', + 'alter table users add constraint users_company_id_foreign foreign key ( company_id ) references companies ( id )', + 'alter table users add constraint users_laravel_idea_id_foreign foreign key ( laravel_idea_id ) references laravel_ideas ( id )', + 'alter table users add constraint users_team_id_foreign foreign key ( team_id ) references teams ( id )', + 'alter table users add constraint users_team_column_id_foreign foreign key ( team_column_id ) references teams ( id )', + ], $statements); + } + public function testAddingBigIncrementingID() { $blueprint = new Blueprint('users');