Skip to content

Commit 49135e5

Browse files
committed
implement json source
1 parent fef33f3 commit 49135e5

File tree

9 files changed

+147
-18
lines changed

9 files changed

+147
-18
lines changed

resources/Zip32_utf8_10501_1.zip

-416 KB
Binary file not shown.

resources/converter.php

+32-11
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,21 @@
22

33
include __DIR__.'/../vendor/autoload.php';
44

5-
use Recca0120\Twzipcode\Sources\CSV;
5+
use Recca0120\Twzipcode\Sources\Csv;
6+
use Recca0120\Twzipcode\Sources\Json;
67
use Recca0120\Twzipcode\Storages\File;
78

9+
// https://data.gov.tw/dataset/5948
10+
$downloadUrl = 'https://quality.data.gov.tw/dq_download_json.php?nid=5948&md5_url=e1f6004ad33eb3ff3a824fb992a4b01a';
11+
$extension = 'json';
12+
$file = __DIR__.'/Zip32_11208.zip';
13+
814
set_error_handler(static function ($severity, $message, $file, $line) {
915
throw new ErrorException($message, $severity, $severity, $file, $line);
1016
});
1117

12-
$start = microtime(true);
13-
$file = __DIR__.'/Zip32_utf8_10501_1.zip';
14-
15-
// https://data.gov.tw/dataset/5948
16-
$url = 'https://quality.data.gov.tw/dq_download_csv.php?nid=5948&md5_url=e1f6004ad33eb3ff3a824fb992a4b01a';
17-
18-
if (file_exists($file) === false) {
19-
touch($file);
18+
function csv($url)
19+
{
2020
$contents = file_get_contents($url);
2121

2222
$encoding = mb_detect_encoding($contents, ['UCS-2LE', 'BIG5', 'UTF-8']);
@@ -30,11 +30,32 @@
3030
throw new RuntimeException($contents);
3131
}
3232

33+
return $contents;
34+
}
35+
36+
function json($url)
37+
{
38+
return file_get_contents($url);
39+
}
40+
41+
$start = microtime(true);
42+
if (file_exists($file) === false) {
43+
$contents = $extension($downloadUrl);
44+
45+
touch($file);
3346
$zip = new ZipArchive;
3447
$zip->open($file, ZipArchive::OVERWRITE);
35-
$zip->addFromString(pathinfo($file, PATHINFO_FILENAME).'.csv', $contents);
48+
$zip->addFromString(pathinfo($file, PATHINFO_FILENAME).'.'.$extension, $contents);
3649
$zip->close();
3750
}
3851

39-
(new File)->load(new CSV($file));
52+
$lookup = [
53+
'csv' => Csv::class,
54+
'json' => Json::class,
55+
];
56+
$class = $lookup[$extension];
57+
58+
$source = new $class($file);
59+
60+
(new File)->load($source);
4061
echo 'benchmark: '.(microtime(true) - $start)."\n";

resources/data/zip5.rules

-7.73 KB
Binary file not shown.

src/Sources/CSV.php src/Sources/Csv.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Recca0120\Twzipcode\Sources;
44

5-
class CSV extends Source
5+
class Csv extends Source
66
{
77
/** @var string */
88
protected $file;

src/Sources/Json.php

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Recca0120\Twzipcode\Sources;
4+
5+
class Json extends Csv
6+
{
7+
/**
8+
* @return array{array{zipcode: string, county: string, district: string, text: string}} $rows
9+
*/
10+
protected function rows()
11+
{
12+
return array_map(static function ($data) {
13+
return [
14+
'zipcode' => $data['郵遞區號'],
15+
'county' => $data['縣市名稱'],
16+
'district' => $data['鄉鎮市區'],
17+
'rule' => implode(',', $data),
18+
];
19+
}, json_decode($this->contents(), true));
20+
}
21+
}

src/Sources/Source.php

+9-4
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,15 @@ protected function rows()
3333
return ! empty(trim($line));
3434
});
3535

36-
return array_map(static function ($line) {
37-
$data = explode(',', $line);
36+
return array_map(static function ($rule) {
37+
$data = explode(',', $rule);
3838

39-
return ['zipcode' => $data[0], 'county' => $data[1], 'district' => $data[2], 'text' => $line];
39+
return [
40+
'zipcode' => $data[0],
41+
'county' => $data[1],
42+
'district' => $data[2],
43+
'rule' => $rule,
44+
];
4045
}, $lines);
4146
}
4247

@@ -51,7 +56,7 @@ protected static function prepare($rows)
5156
? self::$tricks[$row['county'].$row['district']]
5257
: substr($row['zipcode'], 0, 3);
5358

54-
$results[$row['county']][$row['district']][$zip3][] = $row['text'];
59+
$results[$row['county']][$row['district']][$zip3][] = $row['rule'];
5560

5661
return $results;
5762
}, []);

tests/Sources/CsvTest.php

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace Recca0120\Twzipcode\Tests\Sources;
4+
5+
use PHPUnit\Framework\TestCase;
6+
use Recca0120\Twzipcode\Sources\Csv;
7+
8+
class CsvTest extends TestCase
9+
{
10+
public function test_csv_contents()
11+
{
12+
$source = new StubCsv('test.csv');
13+
$source->setContents('10058,臺北市,中正區,八德路1段,全
14+
10079,臺北市,中正區,三元街,單全
15+
');
16+
17+
$source->each(function ($zipcode, $county, $district, $rules) {
18+
self::assertEquals(100, $zipcode);
19+
self::assertEquals('臺北市', $county);
20+
self::assertEquals('中正區', $district);
21+
self::assertEquals([
22+
'10058,臺北市,中正區,八德路1段,全',
23+
'10079,臺北市,中正區,三元街,單全',
24+
], $rules);
25+
});
26+
}
27+
}
28+
29+
class StubCsv extends Csv
30+
{
31+
private $contents = '';
32+
33+
public function setContents($contents)
34+
{
35+
$this->contents = $contents;
36+
}
37+
38+
public function contents()
39+
{
40+
return $this->contents;
41+
}
42+
}

tests/Sources/JsonTest.php

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace Recca0120\Twzipcode\Tests\Sources;
4+
5+
use PHPUnit\Framework\TestCase;
6+
use Recca0120\Twzipcode\Sources\Json;
7+
8+
class JsonTest extends TestCase
9+
{
10+
public function test_csv_contents()
11+
{
12+
$source = new StubJson('test.json');
13+
$source->setContents('[{"郵遞區號":"10058","縣市名稱":"臺北市","鄉鎮市區":"中正區","原始路名":"八德路1段","投遞範圍":"全"},{"郵遞區號":"10079","縣市名稱":"臺北市","鄉鎮市區":"中正區","原始路名":"三元街","投遞範圍":"單全"}]');
14+
15+
$source->each(function ($zipcode, $county, $district, $rules) {
16+
self::assertEquals(100, $zipcode);
17+
self::assertEquals('臺北市', $county);
18+
self::assertEquals('中正區', $district);
19+
self::assertEquals([
20+
'10058,臺北市,中正區,八德路1段,全',
21+
'10079,臺北市,中正區,三元街,單全',
22+
], $rules);
23+
});
24+
}
25+
}
26+
27+
class StubJson extends Json
28+
{
29+
private $contents = '';
30+
31+
public function setContents($contents)
32+
{
33+
$this->contents = $contents;
34+
}
35+
36+
public function contents()
37+
{
38+
return $this->contents;
39+
}
40+
}

tests/Storages/FileTest.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use org\bovigo\vfs\vfsStream;
88
use PHPUnit\Framework\TestCase;
99
use Recca0120\Twzipcode\Address;
10-
use Recca0120\Twzipcode\Sources\CSV;
10+
use Recca0120\Twzipcode\Sources\Csv;
1111
use Recca0120\Twzipcode\Sources\Text;
1212
use Recca0120\Twzipcode\Storages\File as Storage;
1313

@@ -125,7 +125,7 @@ public function testLoadResources()
125125
Storage::$cached = ['zip3' => null, 'zip5' => null];
126126
$root = vfsStream::setup();
127127
$storage = new Storage($root->url());
128-
$storage->flush()->load(new CSV(__DIR__.'/../../resources/Zip32_utf8_10501_1.zip'));
128+
$storage->flush()->load(new Csv(__DIR__.'/../../resources/Zip32_utf8_10501_1.zip'));
129129

130130
$address = m::mock(Address::class);
131131

0 commit comments

Comments
 (0)