Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
danharrin committed Jan 11, 2021
1 parent 776aa56 commit 50020fc
Show file tree
Hide file tree
Showing 23 changed files with 333 additions and 151 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"Squire\\AirlinesServiceProvider",
"Squire\\CountriesServiceProvider",
"Squire\\RegionsEnServiceProvider",
"Squire\\ModelServiceProvider",
"Squire\\GbCountiesEnServiceProvider",
"Squire\\AirlinesEnServiceProvider",
"Squire\\CountriesEnServiceProvider",
Expand Down
10 changes: 10 additions & 0 deletions packages/airlines/src/Models/Airline.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@

class Airline extends Model
{
public static $schema = [
'id' => 'string',
'alias' => 'string',
'call_sign' => 'string',
'code_iata' => 'string',
'code_icao' => 'string',
'country_id' => 'string',
'name' => 'string',
];

public function country()
{
return $this->belongsTo(Country::class);
Expand Down
11 changes: 11 additions & 0 deletions packages/airports/src/Models/Airport.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@

class Airport extends Model
{
public static $schema = [
'id' => 'string',
'code_gps' => 'string',
'code_iata' => 'string',
'code_local' => 'string',
'municipality' => 'string',
'name' => 'string',
'region_id' => 'string',
'type' => 'string',
];

public function country()
{
return $this->hasOneThrough(Country::class, Region::class);
Expand Down
6 changes: 6 additions & 0 deletions packages/continents/src/Models/Continent.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@

class Continent extends Model
{
public static $schema = [
'id' => 'string',
'code' => 'string',
'name' => 'string',
];

public function countries()
{
return $this->hasMany(Country::class);
Expand Down
10 changes: 9 additions & 1 deletion packages/countries/src/Models/Country.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,16 @@

class Country extends Model
{
protected $schema = [
public static $schema = [
'id' => 'string',
'calling_code' => 'string',
'capital_city' => 'string',
'code_2' => 'string',
'code_3' => 'string',
'continent_id' => 'string',
'currency_id' => 'string',
'flag' => 'string',
'name' => 'string',
];

public function airlines()
Expand Down
12 changes: 12 additions & 0 deletions packages/currencies/src/Models/Currency.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@

class Currency extends Model
{
public static $schema = [
'id' => 'string',
'code_alphabetic' => 'string',
'code_numeric' => 'integer',
'decimal_digits' => 'integer',
'name' => 'string',
'name_plural' => 'string',
'rounding' => 'integer',
'symbol' => 'string',
'symbol_native' => 'string',
];

public function countries()
{
return $this->hasMany(Country::class);
Expand Down
7 changes: 7 additions & 0 deletions packages/gb-counties/src/Models/GbCounty.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@

class GbCounty extends Model
{
public static $schema = [
'id' => 'string',
'code' => 'string',
'name' => 'string',
'region_id' => 'string',
];

public function region()
{
return $this->belongsTo(Region::class);
Expand Down
7 changes: 7 additions & 0 deletions packages/model/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@
"Squire\\": "src"
}
},
"extra": {
"laravel": {
"providers": [
"Squire\\ModelServiceProvider"
]
}
},
"config": {
"sort-packages": true
},
Expand Down
9 changes: 9 additions & 0 deletions packages/model/config/squire.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

return [

'cache-path' => storage_path('framework/cache'),

'cache-prefix' => 'squire',

];
179 changes: 120 additions & 59 deletions packages/model/src/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,99 +2,160 @@

namespace Squire;

use Illuminate\Database\Connectors\ConnectionFactory;
use Illuminate\Database\Eloquent;
use Illuminate\Support\Str;
use Sushi\Sushi;

class Model extends Eloquent\Model
{
use Sushi;

public $incrementing = false;

protected $map;

protected $rawData;
public static $schema = [];

protected $schema;
protected static $sqliteConnection;

public static function bootSushi()
protected static function boot()
{
$instance = (new static);
parent::boot();

$cacheFileName = config('sushi.cache-prefix', 'sushi').'-'.Str::kebab(str_replace('\\', '', static::class)).'-'.Repository::getLocale(static::class).'.sqlite';
$cacheDirectory = realpath(config('sushi.cache-path', storage_path('framework/cache')));
$cachePath = $cacheDirectory.'/'.$cacheFileName;
$sourcePath = Repository::getSource(static::class);
if (static::hasValidCache()) {
static::setSqliteConnection(static::getCachePath());

$states = [
'cache-file-found-and-up-to-date' => function () use ($cachePath) {
static::setSqliteConnection($cachePath);
},
'cache-file-not-found-or-stale' => function () use ($cachePath, $sourcePath, $instance) {
file_put_contents($cachePath, '');
return;
}

static::setSqliteConnection($cachePath);
if (static::isCacheable()) {
static::cache([
Repository::getLocale(static::class),
]);

$instance->migrate();
return;
}

touch($cachePath, filemtime($sourcePath));
}
];
static::setSqliteConnection(':memory:');

switch (true) {
case file_exists($cachePath) && filemtime($sourcePath) <= filemtime($cachePath):
$states['cache-file-found-and-up-to-date']();
break;
static::migrate();
}

case file_exists($cacheDirectory) && is_writable($cacheDirectory):
$states['cache-file-not-found-or-stale']();
break;
public static function cache($locales = [])
{
if (! static::isCacheable()) return false;

default:
$states['cache-file-not-found-or-stale']();
break;
if (! count($locales)) {
$locales = array_keys(Repository::getSources(static::class));
}

collect($locales)->filter(function ($locale) {
return Repository::sourceIsRegistered(static::class, $locale);
})->each(function ($locale) {
$cachePath = static::getCachePath($locale);

file_put_contents($cachePath, '');

static::setSqliteConnection($cachePath);

static::migrate($locale);

$modelUpdatedAt = static::getModelUpdatedAt();
$sourceUpdatedAt = static::getSourceUpdatedAt($locale);

touch($cachePath, $modelUpdatedAt >= $sourceUpdatedAt ? $modelUpdatedAt : $sourceUpdatedAt);
});

return false;
}

public function getMap()
protected static function getCachedAt($locale = null)
{
$map = collect($this->map);
$cachePath = static::getCachePath($locale);

if ($map->count()) return $map;
return file_exists($cachePath) ? filemtime($cachePath) : 0;
}

return collect($this->rawData->first())->mapWithKeys(function ($value, $columnName) {
return [$columnName => $columnName];
});
protected static function getCacheDirectory()
{
return realpath(config('squire.cache-path', storage_path('framework/cache')));
}

protected static function getCacheFileName($locale = null)
{
$kebabCaseLocale = Str::of($locale ?? Repository::getLocale(static::class))->replace('_', '-')->lower();
$kebabCaseModelClassName = Str::of( static::class)->replace('\\', '')->kebab();

return config('squire.cache-prefix', 'squire').'-'.$kebabCaseModelClassName.'-'.$kebabCaseLocale.'.sqlite';
}

protected static function getCachePath($locale = null)
{
return static::getCacheDirectory().'/'.static::getCacheFileName($locale);
}

protected static function getModelUpdatedAt()
{
return filemtime((new \ReflectionClass(static::class))->getFileName());
}

protected static function getSourceUpdatedAt($locale = null)
{
return filemtime(Repository::getSource(static::class, $locale));
}

protected static function hasValidCache($locale = null)
{
$cachedAt = static::getCachedAt($locale);
$modelUpdatedAt = static::getModelUpdatedAt();
$sourceUpdatedAt = static::getSourceUpdatedAt($locale);

return $modelUpdatedAt <= $cachedAt && $sourceUpdatedAt <= $cachedAt;
}

public function getRows()
protected static function isCacheable()
{
$this->rawData = collect(Repository::fetchData(static::class));
$cacheDirectory = static::getCacheDirectory();

$map = $this->getMap();
return file_exists($cacheDirectory) && is_writable($cacheDirectory);
}

return $this->rawData->map(function ($row) use ($map) {
$record = [];
public static function migrate($locale = null)
{
$tableName = (new static)->getTable();

foreach ($map as $columnName => $sourceColumnName) {
$record[$columnName] = $row[$sourceColumnName];
static::resolveConnection()->getSchemaBuilder()->create($tableName, function ($table) {
foreach (static::$schema as $name => $type) {
$table->{$type}($name)->nullable();
}
});

return $record;
})->toArray();
$data = collect(Repository::fetchData(static::class));

$schema = collect(str_getcsv($data->first()));

$data->transform(function ($line) use ($schema) {
return $schema->combine(str_getcsv($line));
});

$data->shift();

foreach (array_chunk($data->toArray(), 100) ?? [] as $dataToInsert) {
if (! empty($dataToInsert)) static::insert($dataToInsert);
}
}

public static function resolveConnection($connection = null)
{
return static::$sqliteConnection;
}

protected static function setSqliteConnection($database)
{
static::$sqliteConnection = app(ConnectionFactory::class)->make([
'driver' => 'sqlite',
'database' => $database,
]);
}

public function getSchema()
public function usesTimestamps()
{
$schema = collect($this->schema ?? []);

return $this->getMap()
->filter(function ($sourceColumnName, $columnName) use ($schema) {
return $schema->get($sourceColumnName, false);
})
->mapWithKeys(function ($sourceColumnName, $columnName) use ($schema) {
return [$columnName => $schema->get($sourceColumnName)];
})->toArray();
return false;
}
}
19 changes: 19 additions & 0 deletions packages/model/src/ModelServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Squire;

use Illuminate\Support\ServiceProvider;

class ModelServiceProvider extends ServiceProvider
{
public function boot()
{
$this->publishes([
__DIR__.'/../config/squire.php' => config_path('squire.php'),
]);

$this->mergeConfigFrom(
__DIR__.'/../config/squire.php', 'squire'
);
}
}
7 changes: 7 additions & 0 deletions packages/regions/src/Models/Region.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@

class Region extends Model
{
public static $schema = [
'id' => 'string',
'code' => 'string',
'country_id' => 'string',
'name' => 'string',
];

public function airports()
{
return $this->hasMany(Airport::class);
Expand Down
Loading

0 comments on commit 50020fc

Please sign in to comment.