diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 390ac1ac9..f3ff7a625 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -22,15 +22,6 @@ jobs: php: - '8.1' - '8.2' - services: - mysql: - image: mysql:8.0 - ports: - - 3307:3306 - env: - MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' - MYSQL_DATABASE: 'unittest' - MYSQL_ROOT_PASSWORD: steps: - uses: actions/checkout@v4 @@ -77,8 +68,6 @@ jobs: ./vendor/bin/phpunit --coverage-clover coverage.xml env: MONGODB_URI: 'mongodb://127.0.0.1/?replicaSet=rs' - MYSQL_HOST: 0.0.0.0 - MYSQL_PORT: 3307 - uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 096fd8a06..4de5b27bd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -39,11 +39,10 @@ Before submitting a pull request: ## Run Tests The full test suite requires PHP cli with mongodb extension, a running MongoDB server and a running MySQL server. -Tests requiring MySQL will be skipped if it is not running. Duplicate the `phpunit.xml.dist` file to `phpunit.xml` and edit the environment variables to match your setup. ```bash -$ docker-compose up -d mongodb mysql +$ docker-compose up -d mongodb $ docker-compose run tests ``` diff --git a/Dockerfile b/Dockerfile index 49a2ce736..5d22eb513 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,7 @@ RUN apt-get update && \ apt-get install -y autoconf pkg-config libssl-dev git unzip libzip-dev zlib1g-dev && \ pecl install mongodb && docker-php-ext-enable mongodb && \ pecl install xdebug && docker-php-ext-enable xdebug && \ - docker-php-ext-install -j$(nproc) pdo_mysql zip + docker-php-ext-install -j$(nproc) zip COPY --from=composer:2.6.2 /usr/bin/composer /usr/local/bin/composer diff --git a/docker-compose.yml b/docker-compose.yml index 7ae2b00d8..fec4aa191 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,22 +12,9 @@ services: working_dir: /code environment: MONGODB_URI: 'mongodb://mongodb/' - MYSQL_HOST: 'mysql' depends_on: mongodb: condition: service_healthy - mysql: - condition: service_started - - mysql: - container_name: mysql - image: mysql:8.0 - ports: - - "3306:3306" - environment: - MYSQL_ROOT_PASSWORD: - MYSQL_DATABASE: unittest - MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' mongodb: container_name: mongodb diff --git a/docs/eloquent-models.md b/docs/eloquent-models.md index f8dabb91a..c64bb76b6 100644 --- a/docs/eloquent-models.md +++ b/docs/eloquent-models.md @@ -427,7 +427,7 @@ If you want this functionality to work both ways, your SQL-models will need to u **This functionality only works for `hasOne`, `hasMany` and `belongsTo`.** -The MySQL model should use the `HybridRelations` trait: +The SQL model should use the `HybridRelations` trait: ```php use MongoDB\Laravel\Eloquent\HybridRelations; diff --git a/phpunit.xml.dist b/phpunit.xml.dist index cd883f311..7a38678eb 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -11,44 +11,14 @@ > - + tests/ - - tests/SchemaTest.php - - - tests/SeederTest.php - - - tests/QueryBuilderTest.php - tests/QueryTest.php - - - tests/TransactionTest.php - - - tests/ModelTest.php - tests/RelationsTest.php - - - tests/RelationsTest.php - tests/EmbeddedRelationsTest.php - - - tests/RelationsTest.php - - - tests/ValidationTest.php - - - - - + diff --git a/src/Query/Builder.php b/src/Query/Builder.php index 6bcea4158..1494a7345 100644 --- a/src/Query/Builder.php +++ b/src/Query/Builder.php @@ -276,7 +276,7 @@ public function toMql(): array $group['_id'][$column] = '$' . $column; // When grouping, also add the $last operator to each grouped field, - // this mimics MySQL's behaviour a bit. + // this mimics SQL's behaviour a bit. $group[$column] = ['$last' => '$' . $column]; } diff --git a/tests/HybridRelationsTest.php b/tests/HybridRelationsTest.php index 5dc6b307b..9ff6264e5 100644 --- a/tests/HybridRelationsTest.php +++ b/tests/HybridRelationsTest.php @@ -4,13 +4,13 @@ namespace MongoDB\Laravel\Tests; -use Illuminate\Database\MySqlConnection; +use Illuminate\Database\SQLiteConnection; use Illuminate\Support\Facades\DB; use MongoDB\Laravel\Tests\Models\Book; -use MongoDB\Laravel\Tests\Models\MysqlBook; -use MongoDB\Laravel\Tests\Models\MysqlRole; -use MongoDB\Laravel\Tests\Models\MysqlUser; use MongoDB\Laravel\Tests\Models\Role; +use MongoDB\Laravel\Tests\Models\SqlBook; +use MongoDB\Laravel\Tests\Models\SqlRole; +use MongoDB\Laravel\Tests\Models\SqlUser; use MongoDB\Laravel\Tests\Models\User; use PDOException; @@ -21,30 +21,30 @@ public function setUp(): void parent::setUp(); try { - DB::connection('mysql')->select('SELECT 1'); + DB::connection('sqlite')->select('SELECT 1'); } catch (PDOException) { - $this->markTestSkipped('MySQL connection is not available.'); + $this->markTestSkipped('SQLite connection is not available.'); } - MysqlUser::executeSchema(); - MysqlBook::executeSchema(); - MysqlRole::executeSchema(); + SqlUser::executeSchema(); + SqlBook::executeSchema(); + SqlRole::executeSchema(); } public function tearDown(): void { - MysqlUser::truncate(); - MysqlBook::truncate(); - MysqlRole::truncate(); + SqlUser::truncate(); + SqlBook::truncate(); + SqlRole::truncate(); } - public function testMysqlRelations() + public function testSqlRelations() { - $user = new MysqlUser(); - $this->assertInstanceOf(MysqlUser::class, $user); - $this->assertInstanceOf(MySqlConnection::class, $user->getConnection()); + $user = new SqlUser(); + $this->assertInstanceOf(SqlUser::class, $user); + $this->assertInstanceOf(SQLiteConnection::class, $user->getConnection()); - // Mysql User + // SQL User $user->name = 'John Doe'; $user->save(); $this->assertIsInt($user->id); @@ -52,22 +52,22 @@ public function testMysqlRelations() // SQL has many $book = new Book(['title' => 'Game of Thrones']); $user->books()->save($book); - $user = MysqlUser::find($user->id); // refetch + $user = SqlUser::find($user->id); // refetch $this->assertCount(1, $user->books); // MongoDB belongs to $book = $user->books()->first(); // refetch - $this->assertEquals('John Doe', $book->mysqlAuthor->name); + $this->assertEquals('John Doe', $book->sqlAuthor->name); // SQL has one $role = new Role(['type' => 'admin']); $user->role()->save($role); - $user = MysqlUser::find($user->id); // refetch + $user = SqlUser::find($user->id); // refetch $this->assertEquals('admin', $user->role->type); // MongoDB belongs to $role = $user->role()->first(); // refetch - $this->assertEquals('John Doe', $role->mysqlUser->name); + $this->assertEquals('John Doe', $role->sqlUser->name); // MongoDB User $user = new User(); @@ -75,36 +75,36 @@ public function testMysqlRelations() $user->save(); // MongoDB has many - $book = new MysqlBook(['title' => 'Game of Thrones']); - $user->mysqlBooks()->save($book); + $book = new SqlBook(['title' => 'Game of Thrones']); + $user->sqlBooks()->save($book); $user = User::find($user->_id); // refetch - $this->assertCount(1, $user->mysqlBooks); + $this->assertCount(1, $user->sqlBooks); // SQL belongs to - $book = $user->mysqlBooks()->first(); // refetch + $book = $user->sqlBooks()->first(); // refetch $this->assertEquals('John Doe', $book->author->name); // MongoDB has one - $role = new MysqlRole(['type' => 'admin']); - $user->mysqlRole()->save($role); + $role = new SqlRole(['type' => 'admin']); + $user->sqlRole()->save($role); $user = User::find($user->_id); // refetch - $this->assertEquals('admin', $user->mysqlRole->type); + $this->assertEquals('admin', $user->sqlRole->type); // SQL belongs to - $role = $user->mysqlRole()->first(); // refetch + $role = $user->sqlRole()->first(); // refetch $this->assertEquals('John Doe', $role->user->name); } public function testHybridWhereHas() { - $user = new MysqlUser(); - $otherUser = new MysqlUser(); - $this->assertInstanceOf(MysqlUser::class, $user); - $this->assertInstanceOf(MySqlConnection::class, $user->getConnection()); - $this->assertInstanceOf(MysqlUser::class, $otherUser); - $this->assertInstanceOf(MySqlConnection::class, $otherUser->getConnection()); - - //MySql User + $user = new SqlUser(); + $otherUser = new SqlUser(); + $this->assertInstanceOf(SqlUser::class, $user); + $this->assertInstanceOf(SQLiteConnection::class, $user->getConnection()); + $this->assertInstanceOf(SqlUser::class, $otherUser); + $this->assertInstanceOf(SQLiteConnection::class, $otherUser->getConnection()); + + // SQL User $user->name = 'John Doe'; $user->id = 2; $user->save(); @@ -130,19 +130,19 @@ public function testHybridWhereHas() new Book(['title' => 'Harry Planter']), ]); - $users = MysqlUser::whereHas('books', function ($query) { + $users = SqlUser::whereHas('books', function ($query) { return $query->where('title', 'LIKE', 'Har%'); })->get(); $this->assertEquals(2, $users->count()); - $users = MysqlUser::whereHas('books', function ($query) { + $users = SqlUser::whereHas('books', function ($query) { return $query->where('title', 'LIKE', 'Harry%'); }, '>=', 2)->get(); $this->assertEquals(1, $users->count()); - $books = Book::whereHas('mysqlAuthor', function ($query) { + $books = Book::whereHas('sqlAuthor', function ($query) { return $query->where('name', 'LIKE', 'Other%'); })->get(); @@ -151,14 +151,14 @@ public function testHybridWhereHas() public function testHybridWith() { - $user = new MysqlUser(); - $otherUser = new MysqlUser(); - $this->assertInstanceOf(MysqlUser::class, $user); - $this->assertInstanceOf(MySqlConnection::class, $user->getConnection()); - $this->assertInstanceOf(MysqlUser::class, $otherUser); - $this->assertInstanceOf(MySqlConnection::class, $otherUser->getConnection()); - - //MySql User + $user = new SqlUser(); + $otherUser = new SqlUser(); + $this->assertInstanceOf(SqlUser::class, $user); + $this->assertInstanceOf(SQLiteConnection::class, $user->getConnection()); + $this->assertInstanceOf(SqlUser::class, $otherUser); + $this->assertInstanceOf(SQLiteConnection::class, $otherUser->getConnection()); + + // SQL User $user->name = 'John Doe'; $user->id = 2; $user->save(); @@ -171,18 +171,18 @@ public function testHybridWith() $this->assertIsInt($otherUser->id); // Clear to start Book::truncate(); - MysqlBook::truncate(); + SqlBook::truncate(); // Create books - // Mysql relation - $user->mysqlBooks()->saveMany([ - new MysqlBook(['title' => 'Game of Thrones']), - new MysqlBook(['title' => 'Harry Potter']), + // SQL relation + $user->sqlBooks()->saveMany([ + new SqlBook(['title' => 'Game of Thrones']), + new SqlBook(['title' => 'Harry Potter']), ]); - $otherUser->mysqlBooks()->saveMany([ - new MysqlBook(['title' => 'Harry Plants']), - new MysqlBook(['title' => 'Harveys']), - new MysqlBook(['title' => 'Harry Planter']), + $otherUser->sqlBooks()->saveMany([ + new SqlBook(['title' => 'Harry Plants']), + new SqlBook(['title' => 'Harveys']), + new SqlBook(['title' => 'Harry Planter']), ]); // SQL has many Hybrid $user->books()->saveMany([ @@ -196,12 +196,12 @@ public function testHybridWith() new Book(['title' => 'Harry Planter']), ]); - MysqlUser::with('books')->get() + SqlUser::with('books')->get() ->each(function ($user) { $this->assertEquals($user->id, $user->books->count()); }); - MysqlUser::whereHas('mysqlBooks', function ($query) { + SqlUser::whereHas('sqlBooks', function ($query) { return $query->where('title', 'LIKE', 'Harry%'); }) ->with('books') diff --git a/tests/Models/Book.php b/tests/Models/Book.php index e196ec4b3..70d566fe2 100644 --- a/tests/Models/Book.php +++ b/tests/Models/Book.php @@ -24,8 +24,8 @@ public function author(): BelongsTo return $this->belongsTo(User::class, 'author_id'); } - public function mysqlAuthor(): BelongsTo + public function sqlAuthor(): BelongsTo { - return $this->belongsTo(MysqlUser::class, 'author_id'); + return $this->belongsTo(SqlUser::class, 'author_id'); } } diff --git a/tests/Models/Role.php b/tests/Models/Role.php index 2c191ac1b..ab5eaa029 100644 --- a/tests/Models/Role.php +++ b/tests/Models/Role.php @@ -18,8 +18,8 @@ public function user(): BelongsTo return $this->belongsTo(User::class); } - public function mysqlUser(): BelongsTo + public function sqlUser(): BelongsTo { - return $this->belongsTo(MysqlUser::class); + return $this->belongsTo(SqlUser::class); } } diff --git a/tests/Models/MysqlBook.php b/tests/Models/SqlBook.php similarity index 65% rename from tests/Models/MysqlBook.php rename to tests/Models/SqlBook.php index 0a3662686..babc984eb 100644 --- a/tests/Models/MysqlBook.php +++ b/tests/Models/SqlBook.php @@ -7,17 +7,17 @@ use Illuminate\Database\Eloquent\Model as EloquentModel; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Schema\Blueprint; -use Illuminate\Database\Schema\MySqlBuilder; +use Illuminate\Database\Schema\SQLiteBuilder; use Illuminate\Support\Facades\Schema; use MongoDB\Laravel\Eloquent\HybridRelations; use function assert; -class MysqlBook extends EloquentModel +class SqlBook extends EloquentModel { use HybridRelations; - protected $connection = 'mysql'; + protected $connection = 'sqlite'; protected $table = 'books'; protected static $unguarded = true; protected $primaryKey = 'title'; @@ -32,17 +32,14 @@ public function author(): BelongsTo */ public static function executeSchema(): void { - $schema = Schema::connection('mysql'); - assert($schema instanceof MySqlBuilder); + $schema = Schema::connection('sqlite'); + assert($schema instanceof SQLiteBuilder); - if ($schema->hasTable('books')) { - return; - } - - Schema::connection('mysql')->create('books', function (Blueprint $table) { + $schema->dropIfExists('books'); + $schema->create('books', function (Blueprint $table) { $table->string('title'); $table->string('author_id')->nullable(); - $table->integer('mysql_user_id')->unsigned()->nullable(); + $table->integer('sql_user_id')->unsigned()->nullable(); $table->timestamps(); }); } diff --git a/tests/Models/MysqlRole.php b/tests/Models/SqlRole.php similarity index 62% rename from tests/Models/MysqlRole.php rename to tests/Models/SqlRole.php index e4f293313..17c01e819 100644 --- a/tests/Models/MysqlRole.php +++ b/tests/Models/SqlRole.php @@ -7,17 +7,17 @@ use Illuminate\Database\Eloquent\Model as EloquentModel; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Schema\Blueprint; -use Illuminate\Database\Schema\MySqlBuilder; +use Illuminate\Database\Schema\SQLiteBuilder; use Illuminate\Support\Facades\Schema; use MongoDB\Laravel\Eloquent\HybridRelations; use function assert; -class MysqlRole extends EloquentModel +class SqlRole extends EloquentModel { use HybridRelations; - protected $connection = 'mysql'; + protected $connection = 'sqlite'; protected $table = 'roles'; protected static $unguarded = true; @@ -26,9 +26,9 @@ public function user(): BelongsTo return $this->belongsTo(User::class); } - public function mysqlUser(): BelongsTo + public function sqlUser(): BelongsTo { - return $this->belongsTo(MysqlUser::class); + return $this->belongsTo(SqlUser::class); } /** @@ -36,14 +36,11 @@ public function mysqlUser(): BelongsTo */ public static function executeSchema() { - $schema = Schema::connection('mysql'); - assert($schema instanceof MySqlBuilder); + $schema = Schema::connection('sqlite'); + assert($schema instanceof SQLiteBuilder); - if ($schema->hasTable('roles')) { - return; - } - - Schema::connection('mysql')->create('roles', function (Blueprint $table) { + $schema->dropIfExists('roles'); + $schema->create('roles', function (Blueprint $table) { $table->string('type'); $table->string('user_id'); $table->timestamps(); diff --git a/tests/Models/MysqlUser.php b/tests/Models/SqlUser.php similarity index 66% rename from tests/Models/MysqlUser.php rename to tests/Models/SqlUser.php index c16a14220..1fe11276a 100644 --- a/tests/Models/MysqlUser.php +++ b/tests/Models/SqlUser.php @@ -8,17 +8,17 @@ use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Database\Schema\Blueprint; -use Illuminate\Database\Schema\MySqlBuilder; +use Illuminate\Database\Schema\SQLiteBuilder; use Illuminate\Support\Facades\Schema; use MongoDB\Laravel\Eloquent\HybridRelations; use function assert; -class MysqlUser extends EloquentModel +class SqlUser extends EloquentModel { use HybridRelations; - protected $connection = 'mysql'; + protected $connection = 'sqlite'; protected $table = 'users'; protected static $unguarded = true; @@ -32,9 +32,9 @@ public function role(): HasOne return $this->hasOne(Role::class); } - public function mysqlBooks(): HasMany + public function sqlBooks(): HasMany { - return $this->hasMany(MysqlBook::class); + return $this->hasMany(SqlBook::class); } /** @@ -42,14 +42,11 @@ public function mysqlBooks(): HasMany */ public static function executeSchema(): void { - $schema = Schema::connection('mysql'); - assert($schema instanceof MySqlBuilder); + $schema = Schema::connection('sqlite'); + assert($schema instanceof SQLiteBuilder); - if ($schema->hasTable('users')) { - return; - } - - Schema::connection('mysql')->create('users', function (Blueprint $table) { + $schema->dropIfExists('users'); + $schema->create('users', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->timestamps(); diff --git a/tests/Models/User.php b/tests/Models/User.php index 945d8b074..523b489e7 100644 --- a/tests/Models/User.php +++ b/tests/Models/User.php @@ -51,9 +51,9 @@ public function books() return $this->hasMany(Book::class, 'author_id'); } - public function mysqlBooks() + public function sqlBooks() { - return $this->hasMany(MysqlBook::class, 'author_id'); + return $this->hasMany(SqlBook::class, 'author_id'); } public function items() @@ -66,9 +66,9 @@ public function role() return $this->hasOne(Role::class); } - public function mysqlRole() + public function sqlRole() { - return $this->hasOne(MysqlRole::class); + return $this->hasOne(SqlRole::class); } public function clients() diff --git a/tests/TestCase.php b/tests/TestCase.php index 7098f729f..9f3a76e00 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -67,7 +67,7 @@ protected function getEnvironmentSetUp($app) $app['config']->set('app.key', 'ZsZewWyUJ5FsKp9lMwv4tYbNlegQilM7'); $app['config']->set('database.default', 'mongodb'); - $app['config']->set('database.connections.mysql', $config['connections']['mysql']); + $app['config']->set('database.connections.sqlite', $config['connections']['sqlite']); $app['config']->set('database.connections.mongodb', $config['connections']['mongodb']); $app['config']->set('database.connections.mongodb2', $config['connections']['mongodb']); diff --git a/tests/config/database.php b/tests/config/database.php index 24fee24f4..275dce61a 100644 --- a/tests/config/database.php +++ b/tests/config/database.php @@ -15,13 +15,9 @@ ], ], - 'mysql' => [ - 'driver' => 'mysql', - 'host' => env('MYSQL_HOST', 'mysql'), - 'port' => env('MYSQL_PORT') ? (int) env('MYSQL_PORT') : 3306, - 'database' => env('MYSQL_DATABASE', 'unittest'), - 'username' => env('MYSQL_USERNAME', 'root'), - 'password' => env('MYSQL_PASSWORD', ''), + 'sqlite' => [ + 'driver' => 'sqlite', + 'database' => env('SQLITE_DATABASE', ':memory:'), 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '',