Skip to content

Commit

Permalink
Implementing a year type factory (#15)
Browse files Browse the repository at this point in the history
* Add development database sention in the README

* Fix some bugs to pass test

* Customize the default SQLite database path

* Compatibility between MySQL and SQLite

* Explanation of unsupported field types in sq lite in the readme

* Create mappers and document about database compatibility

* Fix a nullable bug

* Create YearResolverTest class and needed files

* To be able to access properties from magic method `__get`

* Add xeed command to pass test in bootstrap

* Completed YearResolverTest
  • Loading branch information
cable8mm authored Mar 15, 2024
1 parent f51d82d commit 30d88d2
Show file tree
Hide file tree
Showing 19 changed files with 428 additions and 20 deletions.
1 change: 1 addition & 0 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ jobs:
run: |
cp .env.example .env
touch database/database.sqlite
bin/console xeed
- name: Execute tests
run: composer test
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ composer.lock
/build
/cache
/doctum.php
/.phpunit.cache
83 changes: 83 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,89 @@ composer test
# Run tests
```

### Database

For migrations and factories, when you need to execute tests for all database field types, utilize the following command.

```sh
bin/console xeed
# Import an 'xeeds' Table into the Database

bin/console xeed drop
# Drop the 'xeeds' Table from the Database
```

Utilize migration files for all database field types by referring to the following location `resources/tests` these files are saved in the specified folder.

🔥 SQLite does not yet support the `SET` and `ENUM` field types, so the corresponding lines are commented out. If you are using MySQL, you will need to uncomment the following line.

```php
Schema::create('xeeds', function (Blueprint $table) {
$table->id();
$table->bigInteger('big_integer');
$table->binary('binary');
$table->boolean('boolean');
$table->char('char', 100);
$table->dateTimeTz('date_time_tz', $precision = 0);
$table->dateTime('date_time', $precision = 0);
$table->date('date');
$table->decimal('decimal', $precision = 8, $scale = 2);
$table->double('double', 8, 2);
// $table->enum('enum', ['easy', 'hard']);
//-> SQLite unsupported
$table->float('float', 8, 2);
$table->foreignId('foreign_id');
$table->foreignUlid('foreign_ulid');
$table->foreignUuid('foreign_uuid');
$table->geometryCollection('geometry_collection');
$table->geometry('geometry');
$table->integer('integer');
$table->ipAddress('ip_address');
$table->json('json');
$table->jsonb('jsonb');
$table->lineString('line_string');
$table->longText('long_text');
$table->macAddress('mac_address');
$table->mediumInteger('medium_integer');
$table->mediumText('medium_text');
$table->morphs('morphs');
$table->multiLineString('multi_line_string');
$table->multiPoint('multi_point');
$table->multiPolygon('multi_polygon');
$table->nullableMorphs('nullable_morphs');
$table->nullableUlidMorphs('nullable_ulid_morphs');
$table->nullableUuidMorphs('nullable_uuid_morphs');
$table->point('point');
$table->polygon('polygon');
$table->rememberToken();
// $table->set('set', ['strawberry', 'vanilla']);
//-> SQLite unsupported
$table->smallInteger('small_integer');
$table->softDeletesTz($column = 'soft_deletes_tz', $precision = 0);
$table->softDeletes($column = 'soft_deletes', $precision = 0);
$table->string('string', 100);
$table->text('text');
$table->timeTz('time_tz', $precision = 0);
$table->time('time', $precision = 0);
$table->timestampTz('timestamp_tz', $precision = 0);
$table->timestamp('timestamp', $precision = 0);
$table->timestamps($precision = 0);
$table->tinyInteger('tiny_integer');
$table->tinyText('tiny_text');
$table->unsignedBigInteger('unsigned_big_integer');
$table->unsignedDecimal('unsigned_decimal', $precision = 8, $scale = 2);
$table->unsignedInteger('unsigned_integer');
$table->unsignedMediumInteger('unsigned_medium_integer');
$table->unsignedSmallInteger('unsigned_small_integer');
$table->unsignedTinyInteger('unsigned_tiny_integer');
$table->ulidMorphs('ulid_morphs');
$table->uuidMorphs('uuid_morphs');
$table->ulid('ulid');
$table->uuid('uuid');
$table->year('birth_year');
}
```

### Issue a bug report and Pull Request

The opportunity for you to create issues and pull requests makes me happy. Feel free to contribute and submit pull requests whenever you need.
Expand Down
4 changes: 3 additions & 1 deletion database/Seeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ public function dropTables()

private function createUserTable(): int|false
{
$schema = 'CREATE TABLE `'.self::TABLE.'` ( id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(25) NOT NULL, email VARCHAR(100) NOT NULL)';
$autoIncrement = $this->db->driver === 'mysql' ? 'AUTO_INCREMENT' : 'AUTOINCREMENT';

$schema = 'CREATE TABLE `'.self::TABLE.'` ( id INTEGER PRIMARY KEY '.$autoIncrement.', name VARCHAR(25) NOT NULL, email VARCHAR(100) NOT NULL)';

return $this->db->exec($schema);
}
Expand Down
9 changes: 9 additions & 0 deletions docs/LARAVEL_MIGRATIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Laravel Migrations Compatibility

Here's a table outlining some commonly used field types in Laravel migrations and their equivalents between SQLite and MySQL:

| Laravel Migration Type | SQLite Equivalent | MySQL Equivalent |
| :-------------------------: | :---------------: | :--------------: |
| `$table->year('birth_day')` | year | integer |

These are basic mappings and may not cover all possible scenarios. It's important to consult the documentation for SQLite and MySQL to ensure compatibility with your specific requirements. Additionally, some Laravel-specific features like $table->timestamps() and $table->softDeletes() do not directly translate to specific field types in database systems like SQLite or MySQL.
11 changes: 11 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
processIsolation="false"
bootstrap="vendor/autoload.php"
displayDetailsOnTestsThatTriggerDeprecations="true"
displayDetailsOnTestsThatTriggerErrors="true"
displayDetailsOnTestsThatTriggerNotices="true"
displayDetailsOnTestsThatTriggerWarnings="true"
cacheDirectory=".phpunit.cache"
colors="true"
testdox="true">
<testsuites>
Expand All @@ -23,5 +28,11 @@
<php>
<env name="DB_CONNECTION" value="sqlite" />
<env name="DB_DATABASE" value="database/database.sqlite" />
<!-- <env name="DB_CONNECTION" value="mysql" />
<env name="DB_HOST" value="127.0.0.1" />
<env name="DB_PORT" value="3306" />
<env name="DB_DATABASE" value="xeed" />
<env name="DB_USERNAME" value="root" />
<env name="DB_PASSWORD" value="" /> -->
</php>
</phpunit>
File renamed without changes.
116 changes: 116 additions & 0 deletions resources/tests/xeeds.sqlite.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
Navicat Premium Data Transfer
Source Server : Test
Source Server Type : SQLite
Source Server Version : 3030001
Source Schema : main
Target Server Type : SQLite
Target Server Version : 3030001
File Encoding : 65001
Date: 16/03/2024 00:21:45
*/
PRAGMA foreign_keys = false;
-- ----------------------------
-- Table structure for xeeds
-- ----------------------------
DROP TABLE IF EXISTS "xeeds";
CREATE TABLE "xeeds" (
"id" integer primary key autoincrement not null,
"big_integer" integer not null,
"binary" blob not null,
"boolean" tinyint(1) not null,
"char" varchar not null,
"date_time_tz" datetime not null,
"date_time" datetime not null,
"date" date not null,
"decimal" numeric not null,
"double" float not null,
"float" float not null,
"foreign_id" integer not null,
"foreign_ulid" varchar not null,
"foreign_uuid" varchar not null,
"geometry_collection" geometrycollection not null,
"geometry" geometry not null,
"integer" integer not null,
"ip_address" varchar not null,
"json" text not null,
"jsonb" text not null,
"line_string" linestring not null,
"long_text" text not null,
"mac_address" varchar not null,
"medium_integer" integer not null,
"medium_text" text not null,
"morphs_type" varchar not null,
"morphs_id" integer not null,
"multi_line_string" multilinestring not null,
"multi_point" multipoint not null,
"multi_polygon" multipolygon not null,
"nullable_morphs_type" varchar,
"nullable_morphs_id" integer,
"nullable_ulid_morphs_type" varchar,
"nullable_ulid_morphs_id" varchar,
"nullable_uuid_morphs_type" varchar,
"nullable_uuid_morphs_id" varchar,
"point" point not null,
"polygon" polygon not null,
"remember_token" varchar,
"small_integer" integer not null,
"soft_deletes_tz" datetime,
"soft_deletes" datetime,
"string" varchar not null,
"text" text not null,
"time_tz" time not null,
"time" time not null,
"timestamp_tz" datetime not null,
"timestamp" datetime not null,
"created_at" datetime,
"updated_at" datetime,
"tiny_integer" integer not null,
"tiny_text" text not null,
"unsigned_big_integer" integer not null,
"unsigned_decimal" numeric not null,
"unsigned_integer" integer not null,
"unsigned_medium_integer" integer not null,
"unsigned_small_integer" integer not null,
"unsigned_tiny_integer" integer not null,
"ulid_morphs_type" varchar not null,
"ulid_morphs_id" varchar not null,
"uuid_morphs_type" varchar not null,
"uuid_morphs_id" varchar not null,
"ulid" varchar not null,
"uuid" varchar not null,
"birth_year" integer not null
);
-- ----------------------------
-- Records of xeeds
-- ----------------------------
BEGIN;
COMMIT;
-- ----------------------------
-- Indexes structure for table xeeds
-- ----------------------------
CREATE INDEX "main"."xeeds_morphs_type_morphs_id_index" ON "xeeds" ("morphs_type" ASC, "morphs_id" ASC);
CREATE INDEX "main"."xeeds_nullable_morphs_type_nullable_morphs_id_index" ON "xeeds" (
"nullable_morphs_type" ASC,
"nullable_morphs_id" ASC
);
CREATE INDEX "main"."xeeds_nullable_ulid_morphs_type_nullable_ulid_morphs_id_index" ON "xeeds" (
"nullable_ulid_morphs_type" ASC,
"nullable_ulid_morphs_id" ASC
);
CREATE INDEX "main"."xeeds_nullable_uuid_morphs_type_nullable_uuid_morphs_id_index" ON "xeeds" (
"nullable_uuid_morphs_type" ASC,
"nullable_uuid_morphs_id" ASC
);
CREATE INDEX "main"."xeeds_ulid_morphs_type_ulid_morphs_id_index" ON "xeeds" (
"ulid_morphs_type" ASC,
"ulid_morphs_id" ASC
);
CREATE INDEX "main"."xeeds_uuid_morphs_type_uuid_morphs_id_index" ON "xeeds" (
"uuid_morphs_type" ASC,
"uuid_morphs_id" ASC
);
PRAGMA foreign_keys = true;
8 changes: 5 additions & 3 deletions src/Command/ImportXeedCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int

$drop = $input->getArgument('drop');

$db = DB::getInstance();

if ($drop) {
DB::getInstance()->prepare('DROP TABLE xeeds')->execute();
$db->prepare('DROP TABLE xeeds')->execute();
} else {
$sql = file_get_contents(Path::resourceTest().'xeeds.sql');
$sql = file_get_contents(Path::resourceTest().'xeeds.'.$db->driver.'.sql');

DB::getInstance()->exec($sql);
$db->exec($sql);
}

return Command::SUCCESS;
Expand Down
24 changes: 15 additions & 9 deletions src/DB.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

use ArrayAccess;
use Cable8mm\Xeed\Interfaces\Provider;
use Cable8mm\Xeed\Support\Path;
use InvalidArgumentException;
use PDO;

/**
Expand All @@ -29,8 +31,8 @@ final class DB extends PDO implements ArrayAccess
private Provider $provider;

private function __construct(
string $driver,
string $database,
public string $driver,
?string $database = null,
?string $host = null,
?string $port = null,
?string $username = null,
Expand All @@ -42,7 +44,7 @@ private function __construct(
$this->provider = new (__NAMESPACE__.'\\Provider\\'.ucfirst($driver).'Provider');

if ($driver === 'sqlite') {
$dns = $driver.':'.$database;
$dns = $driver.':'.($database ?? Path::database().'database.sqlite');

parent::__construct($dns, options: $options);

Expand All @@ -66,11 +68,11 @@ public static function getInstance(): static
$dotenv->safeLoad();

$driver = $_ENV['DB_CONNECTION'];
$host = $_ENV['DB_HOST'];
$port = $_ENV['DB_PORT'];
$database = $_ENV['DB_DATABASE'];
$username = $_ENV['DB_USERNAME'];
$password = $_ENV['DB_PASSWORD'];
$host = $_ENV['DB_HOST'] ?? null;
$port = $_ENV['DB_PORT'] ?? null;
$database = $_ENV['DB_DATABASE'] ?? null;
$username = $_ENV['DB_USERNAME'] ?? null;
$password = $_ENV['DB_PASSWORD'] ?? null;

self::$instance = new self($driver, $database, $host, $port, $username, $password);
}
Expand All @@ -81,7 +83,7 @@ public static function getInstance(): static
/**
* To get new instance
*/
public static function newGetInstance(): static
public static function getNewInstance(): static
{
self::$instance = null;

Expand Down Expand Up @@ -111,6 +113,10 @@ public function getTables(): array
*/
public function getTable(string $table): ?Table
{
if (! isset($this->tables[$table])) {
throw new InvalidArgumentException('Table '.$table.' does not exist');
}

return $this->tables[$table];
}

Expand Down
5 changes: 5 additions & 0 deletions src/Mappers/mysql.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

return [
'year' => 'year',
];
5 changes: 5 additions & 0 deletions src/Mappers/sqlite.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

return [
'year' => 'integer',
];
Loading

0 comments on commit 30d88d2

Please sign in to comment.