Table   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 141
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 18
eloc 43
c 1
b 0
f 0
dl 0
loc 141
ccs 49
cts 49
cp 1
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A character() 0 3 1
A getTableName() 0 13 3
A getDataFilePath() 0 16 4
A prepareLoadStatement() 0 8 1
A getDefaultDataFilePath() 0 7 2
A makeMigration() 0 14 4
A loadData() 0 11 2
1
<?php
2
3
namespace LaraGeoData\Database\Tables;
4
5
use Illuminate\Filesystem\Filesystem;
6
use Illuminate\Support\Facades\DB;
7
use Illuminate\Support\Facades\Schema;
8
use Illuminate\Support\Str;
9
use LaraGeoData\Facades\GeoDataImporter;
10
11
abstract class Table implements GeoTable
12
{
13
    /**
14
     * The filesystem instance.
15
     *
16
     * @var Filesystem
17
     */
18
    protected Filesystem $files;
19
20
    /**
21
     * Path where stored all templates.
22
     *
23
     * @var string
24
     */
25
    protected string $migrationTemplatesPath = __DIR__ . '/../../../database/migrations-stubs/';
26
27
    /**
28
     * Data file path prefix.
29
     *
30
     * @var string
31
     */
32
    protected $defaultDataFilePathPrefix = '';
33
34 13
    public function __construct(Filesystem $files)
35
    {
36 13
        $this->files = $files;
37 13
    }
38
39
    /**
40
     * @inheritDoc
41
     */
42 11
    public function makeMigration(?string $suffix = null): string
43
    {
44 11
        $templateNameRoot = $this->getTemplateNameRoot();
45 11
        $template         = $this->migrationTemplatesPath . $templateNameRoot . '.php.stub';
46 11
        $saveTo           = database_path('migrations/' . date('Y_m_d_His', time()) . '_' . $templateNameRoot . ($suffix ? "_{$suffix}" : '') . '.php');
47
48 11
        $this->files->copy($template, $saveTo);
49
50 11
        $text = $this->files->get($saveTo);
51 11
        $text = str_replace('/** class_suffix **/', $suffix ? Str::ucfirst(Str::camel($suffix)) : '', $text);
52 11
        $text = str_replace('/** table_suffix **/', $suffix ? " . '_{$suffix}'" : '', $text);
53 11
        $this->files->put($saveTo, $text);
54
55 11
        return $saveTo;
56
    }
57
58
    /**
59
     * Get migration template file name (only root part).
60
     *
61
     * @return string
62
     */
63
    abstract public function getTemplateNameRoot(): string;
64
65
    /**
66
     * Get table name (only root part).
67
     *
68
     * @return string
69
     */
70
    abstract public function getTableNameRoot(): string;
71
72
    /**
73
     * @inheritDoc
74
     */
75 10
    public function loadData(?string $filePath = null, ?string $suffix = null, $truncate = true)
76
    {
77 10
        $tableName = $this->getTableName($suffix);
78 9
        $filePath  = $this->getDataFilePath($suffix, $filePath);
79
80 4
        if ($truncate) {
81 2
            DB::table($tableName)->truncate();
82
        }
83
84 4
        DB::connection(config('geonames.database.connection'))
85 4
          ->statement($this->prepareLoadStatement($tableName, $filePath));
86 4
    }
87
88 9
    protected function getDataFilePath(?string $suffix, ?string $filePath): string
89
    {
90 9
        $filePath = $filePath ?: $this->getDefaultDataFilePath($suffix);
91
92 9
        throw_if(!$filePath, new \Exception('File not found.'));
93
94 9
        if (!$this->files->exists($filePath)) {
95 5
            $initialFilePath = $filePath;
96 5
            $filePath        = GeoDataImporter::storagePath($filePath);
97
98 5
            if (!$this->files->exists($filePath)) {
99 5
                throw new \Exception("File [{$initialFilePath}] not found.");
100
            }
101
        }
102
103 4
        return $filePath;
104
    }
105
106 8
    protected function getDefaultDataFilePath(?string $suffix): string
107
    {
108 8
        if (!$suffix) {
109 2
            return GeoDataImporter::storagePath($this->defaultDataFilePathPrefix . 'allCountries.txt');
110
        }
111
112 6
        return GeoDataImporter::storagePath($this->defaultDataFilePathPrefix . Str::upper($suffix) . '.txt');
113
    }
114
115 10
    protected function getTableName(?string $suffix): string
116
    {
117 10
        $tableName = $this->getTableNameRoot();
118
119 10
        if ($suffix) {
120 7
            $tableName = "{$tableName}_{$suffix}";
121
        }
122
123 10
        if (!Schema::connection(config('geonames.database.connection'))->hasTable($tableName)) {
124 1
            throw new \Exception("Table [{$tableName}] not found. Maybe you need run migrations.");
125
        }
126
127 9
        return $tableName;
128
    }
129
130 4
    protected function prepareLoadStatement(string $tableName, string $filePath): string
131
    {
132 4
        $columnsNames = implode(',', $this->orderedColumnsListToLoad());
133
134 4
        return "LOAD DATA LOCAL INFILE '{$filePath}'
135 4
        INTO TABLE `{$tableName}`
136 4
        CHARACTER SET  '{$this->character()}'
137 4
        ({$columnsNames},
138
        @status,
139
        @created_at,
140
        @updated_at)
141
        SET status=2,created_at=NOW(),updated_at=NOW()";
142
    }
143
144
    abstract protected function orderedColumnsListToLoad(): array;
145
146
    /**
147
     * @return string
148
     */
149 4
    protected function character(): string
150
    {
151 4
        return 'utf8mb4';
152
    }
153
}
154