maxmind-db 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +13 -2
  3. data/Gemfile +8 -0
  4. data/Gemfile.lock +34 -0
  5. data/README.md +2 -2
  6. data/Rakefile +2 -0
  7. data/bin/mmdb-benchmark.rb +4 -1
  8. data/lib/maxmind/db.rb +49 -27
  9. data/lib/maxmind/db/decoder.rb +26 -26
  10. data/lib/maxmind/db/errors.rb +3 -1
  11. data/lib/maxmind/db/file_reader.rb +5 -3
  12. data/lib/maxmind/db/memory_reader.rb +3 -1
  13. data/lib/maxmind/db/metadata.rb +3 -1
  14. data/maxmind-db.gemspec +5 -2
  15. data/test/mmdb_util.rb +2 -0
  16. data/test/test_decoder.rb +2 -0
  17. data/test/test_reader.rb +117 -6
  18. metadata +7 -64
  19. data/test/data/LICENSE +0 -4
  20. data/test/data/MaxMind-DB-spec.md +0 -558
  21. data/test/data/MaxMind-DB-test-metadata-pointers.mmdb +0 -0
  22. data/test/data/README.md +0 -4
  23. data/test/data/bad-data/README.md +0 -7
  24. data/test/data/bad-data/libmaxminddb/libmaxminddb-offset-integer-overflow.mmdb +0 -0
  25. data/test/data/bad-data/maxminddb-golang/cyclic-data-structure.mmdb +0 -0
  26. data/test/data/bad-data/maxminddb-golang/invalid-bytes-length.mmdb +0 -1
  27. data/test/data/bad-data/maxminddb-golang/invalid-data-record-offset.mmdb +0 -0
  28. data/test/data/bad-data/maxminddb-golang/invalid-map-key-length.mmdb +0 -0
  29. data/test/data/bad-data/maxminddb-golang/invalid-string-length.mmdb +0 -1
  30. data/test/data/bad-data/maxminddb-golang/metadata-is-an-uint128.mmdb +0 -1
  31. data/test/data/bad-data/maxminddb-golang/unexpected-bytes.mmdb +0 -0
  32. data/test/data/perltidyrc +0 -12
  33. data/test/data/source-data/GeoIP2-Anonymous-IP-Test.json +0 -41
  34. data/test/data/source-data/GeoIP2-City-Test.json +0 -12852
  35. data/test/data/source-data/GeoIP2-Connection-Type-Test.json +0 -102
  36. data/test/data/source-data/GeoIP2-Country-Test.json +0 -11347
  37. data/test/data/source-data/GeoIP2-DensityIncome-Test.json +0 -14
  38. data/test/data/source-data/GeoIP2-Domain-Test.json +0 -452
  39. data/test/data/source-data/GeoIP2-Enterprise-Test.json +0 -673
  40. data/test/data/source-data/GeoIP2-ISP-Test.json +0 -12585
  41. data/test/data/source-data/GeoIP2-Precision-Enterprise-Test.json +0 -1598
  42. data/test/data/source-data/GeoIP2-User-Count-Test.json +0 -2824
  43. data/test/data/source-data/GeoLite2-ASN-Test.json +0 -37
  44. data/test/data/source-data/README +0 -15
  45. data/test/data/test-data/GeoIP2-Anonymous-IP-Test.mmdb +0 -0
  46. data/test/data/test-data/GeoIP2-City-Test-Broken-Double-Format.mmdb +0 -0
  47. data/test/data/test-data/GeoIP2-City-Test-Invalid-Node-Count.mmdb +0 -0
  48. data/test/data/test-data/GeoIP2-City-Test.mmdb +0 -0
  49. data/test/data/test-data/GeoIP2-Connection-Type-Test.mmdb +0 -0
  50. data/test/data/test-data/GeoIP2-Country-Test.mmdb +0 -0
  51. data/test/data/test-data/GeoIP2-DensityIncome-Test.mmdb +0 -0
  52. data/test/data/test-data/GeoIP2-Domain-Test.mmdb +0 -0
  53. data/test/data/test-data/GeoIP2-Enterprise-Test.mmdb +0 -0
  54. data/test/data/test-data/GeoIP2-ISP-Test.mmdb +0 -0
  55. data/test/data/test-data/GeoIP2-Precision-Enterprise-Test.mmdb +0 -0
  56. data/test/data/test-data/GeoIP2-User-Count-Test.mmdb +0 -0
  57. data/test/data/test-data/GeoLite2-ASN-Test.mmdb +0 -0
  58. data/test/data/test-data/MaxMind-DB-no-ipv4-search-tree.mmdb +0 -0
  59. data/test/data/test-data/MaxMind-DB-string-value-entries.mmdb +0 -0
  60. data/test/data/test-data/MaxMind-DB-test-broken-pointers-24.mmdb +0 -0
  61. data/test/data/test-data/MaxMind-DB-test-broken-search-tree-24.mmdb +0 -0
  62. data/test/data/test-data/MaxMind-DB-test-decoder.mmdb +0 -0
  63. data/test/data/test-data/MaxMind-DB-test-ipv4-24.mmdb +0 -0
  64. data/test/data/test-data/MaxMind-DB-test-ipv4-28.mmdb +0 -0
  65. data/test/data/test-data/MaxMind-DB-test-ipv4-32.mmdb +0 -0
  66. data/test/data/test-data/MaxMind-DB-test-ipv6-24.mmdb +0 -0
  67. data/test/data/test-data/MaxMind-DB-test-ipv6-28.mmdb +0 -0
  68. data/test/data/test-data/MaxMind-DB-test-ipv6-32.mmdb +0 -0
  69. data/test/data/test-data/MaxMind-DB-test-metadata-pointers.mmdb +0 -0
  70. data/test/data/test-data/MaxMind-DB-test-mixed-24.mmdb +0 -0
  71. data/test/data/test-data/MaxMind-DB-test-mixed-28.mmdb +0 -0
  72. data/test/data/test-data/MaxMind-DB-test-mixed-32.mmdb +0 -0
  73. data/test/data/test-data/MaxMind-DB-test-nested.mmdb +0 -0
  74. data/test/data/test-data/README.md +0 -26
  75. data/test/data/test-data/maps-with-pointers.raw +0 -0
  76. data/test/data/test-data/write-test-data.pl +0 -620
  77. data/test/data/tidyall.ini +0 -5
@@ -1,37 +0,0 @@
1
- [
2
- {
3
- "::1.128.0.0/107" : {
4
- "autonomous_system_number" : 1221,
5
- "autonomous_system_organization" : "Telstra Pty Ltd"
6
- }
7
- },
8
- {
9
- "::12.81.92.0/118" : {
10
- "autonomous_system_number" : 7018,
11
- "autonomous_system_organization" : "AT&T Services"
12
- }
13
- },
14
- {
15
- "::12.81.96.0/115" : {
16
- "autonomous_system_number" : 7018
17
- }
18
- },
19
- {
20
- "2600:6000::/20" : {
21
- "autonomous_system_number" : 237,
22
- "autonomous_system_organization" : "Merit Network Inc."
23
- }
24
- },
25
- {
26
- "2600:7000::/24" : {
27
- "autonomous_system_number" : 6939,
28
- "autonomous_system_organization" : "Hurricane Electric, Inc."
29
- }
30
- },
31
- {
32
- "2600:7100::/24" : {
33
- "autonomous_system_number" : 237,
34
- "autonomous_system_organization" : "Merit Network Inc."
35
- }
36
- }
37
- ]
@@ -1,15 +0,0 @@
1
- All of these but the City and Enterprise files are JSON dumps of the databases
2
- created by the GeoIP2 build integration tests
3
- (TestFor::MM::Integration::GeoIP2::Build).
4
-
5
- Additional data was added to match our legacy test databases.
6
-
7
- The City file is of unknown origin.
8
-
9
- The Enterprise file was a single example IP address, modified slightly to
10
- include all fields. It now has more than that.
11
-
12
- The Precision file was the normal Enterprise file with an additional marker
13
- (128.101.101.101) to differentiate the two. It now contains additional
14
- additions and changes as it is the database used in many MaxMind
15
- integration tests.
@@ -1,26 +0,0 @@
1
- The write-test-dbs script will create a small set of test databases with a
2
- variety of data and record sizes (24, 28, & 32 bit).
3
-
4
- These test databases are useful for testing code that reads MaxMind DB files.
5
-
6
- There is also a `maps-with-pointers.raw` file. This contains the raw output of
7
- the MaxMind::DB::Writer::Serializer module, when given a series of maps which
8
- share some keys and values. It is used to test that decoder code can handle
9
- pointers to map keys and values, as well as to the whole map.
10
-
11
- There are several ways to figure out what IP addresses are actually in the
12
- test databases. You can take a look at the
13
- [source-data directory](https://github.com/maxmind/MaxMind-DB/tree/master/source-data)
14
- in this repository. This directory contains JSON files which are used to
15
- generate many (but not all) of the database files.
16
-
17
- You can also use the
18
- [mmdb-dump-database script](https://github.com/maxmind/MaxMind-DB-Reader-perl/blob/master/eg/mmdb-dump-database)
19
- in the
20
- [MaxMind-DB-Reader-perl repository](https://github.com/maxmind/MaxMind-DB-Reader-perl).
21
-
22
- Some databases are intentionally broken and cannot be dumped. You can look at
23
- the
24
- [script which generates these databases](https://github.com/maxmind/MaxMind-DB/blob/master/test-data/write-test-data.pl)
25
- to see what IP addresses they include, which will be necessary for those
26
- databases which cannot be dumped because they contain intentional errors.
@@ -1,620 +0,0 @@
1
- #!/usr/bin/env perl
2
-
3
- use strict;
4
- use warnings;
5
- use autodie;
6
- use utf8;
7
-
8
- use Carp qw( croak );
9
- use Cwd qw( abs_path );
10
- use File::Basename qw( dirname );
11
- use File::Slurper qw( read_binary write_binary );
12
- use Cpanel::JSON::XS qw( decode_json );
13
- use Math::Int128 qw( uint128 );
14
- use MaxMind::DB::Writer::Serializer 0.100004;
15
- use MaxMind::DB::Writer::Tree 0.100004;
16
- use MaxMind::DB::Writer::Util qw( key_for_data );
17
- use Net::Works::Network;
18
- use Test::MaxMind::DB::Common::Util qw( standard_test_metadata );
19
-
20
- my $Dir = dirname( abs_path($0) );
21
-
22
- sub main {
23
- my @sizes = ( 24, 28, 32 );
24
- my @ipv4_range = ( '1.1.1.1', '1.1.1.32' );
25
-
26
- my @ipv4_subnets = Net::Works::Network->range_as_subnets(@ipv4_range);
27
- for my $record_size (@sizes) {
28
- write_test_db(
29
- $record_size,
30
- \@ipv4_subnets,
31
- { ip_version => 4 },
32
- 'ipv4',
33
- );
34
- }
35
-
36
- write_broken_pointers_test_db(
37
- 24,
38
- \@ipv4_subnets,
39
- { ip_version => 4 },
40
- 'broken-pointers',
41
- );
42
-
43
- write_broken_search_tree_db(
44
- 24,
45
- \@ipv4_subnets,
46
- { ip_version => 4 },
47
- 'broken-search-tree',
48
- );
49
-
50
- my @ipv6_subnets = Net::Works::Network->range_as_subnets(
51
- '::1:ffff:ffff',
52
- '::2:0000:0059'
53
- );
54
-
55
- for my $record_size (@sizes) {
56
- write_test_db(
57
- $record_size,
58
- \@ipv6_subnets,
59
- { ip_version => 6 },
60
- 'ipv6',
61
- );
62
-
63
- write_test_db(
64
- $record_size,
65
- [
66
- @ipv6_subnets,
67
- Net::Works::Network->range_as_subnets( @ipv4_range, 6 ),
68
- ],
69
- { ip_version => 6 },
70
- 'mixed',
71
- );
72
- }
73
-
74
- write_decoder_test_db();
75
- write_deeply_nested_structures_db();
76
-
77
- write_geoip2_dbs();
78
- write_broken_geoip2_city_db();
79
- write_invalid_node_count();
80
-
81
- write_no_ipv4_tree_db();
82
-
83
- write_no_map_db( \@ipv4_subnets );
84
-
85
- write_test_serialization_data();
86
-
87
- write_db_with_metadata_pointers();
88
- }
89
-
90
- sub write_broken_pointers_test_db {
91
- no warnings 'redefine';
92
-
93
- my $orig_store_data = MaxMind::DB::Writer::Serializer->can('store_data');
94
-
95
- # This breaks the value of the record for the 1.1.1.32 network, causing it
96
- # to point outside the database.
97
- local *MaxMind::DB::Writer::Serializer::store_data = sub {
98
- my $data_pointer = shift->$orig_store_data(@_);
99
- my $value = $_[1];
100
- if ( ref($value) eq 'HASH'
101
- && exists $value->{ip}
102
- && $value->{ip} eq '1.1.1.32' ) {
103
-
104
- $data_pointer += 100_000;
105
- }
106
- return $data_pointer;
107
- };
108
-
109
- # The next hack will poison the data section for the 1.1.16/28 subnet
110
- # value. It's value will be a pointer that resolves to an offset outside
111
- # the database.
112
-
113
- my $key_to_poison = key_for_data( { ip => '1.1.1.16' } );
114
-
115
- my $orig_position_for_data
116
- = MaxMind::DB::Writer::Serializer->can('_position_for_data');
117
- local *MaxMind::DB::Writer::Serializer::_position_for_data = sub {
118
- my $key = $_[1];
119
-
120
- if ( $key eq $key_to_poison ) {
121
- return 1_000_000;
122
- }
123
- else {
124
- return shift->$orig_position_for_data(@_);
125
- }
126
- };
127
-
128
- write_test_db(@_);
129
-
130
- return;
131
- }
132
-
133
- sub write_broken_search_tree_db {
134
- my $filename = ( write_test_db(@_) )[1];
135
-
136
- my $content = read_binary($filename);
137
-
138
- # This causes the right record of the first node to be 0, meaning it
139
- # points back to the top of the tree. This should never happen in a
140
- # database that follows the spec.
141
- substr( $content, 5, 1 ) = "\0";
142
- write_binary( $filename, $content );
143
-
144
- return;
145
- }
146
-
147
- sub write_test_db {
148
- my $record_size = shift;
149
- my $subnets = shift;
150
- my $metadata = shift;
151
- my $ip_version_name = shift;
152
-
153
- my $writer = MaxMind::DB::Writer::Tree->new(
154
- ip_version => $subnets->[0]->version(),
155
- record_size => $record_size,
156
- alias_ipv6_to_ipv4 => ( $subnets->[0]->version() == 6 ? 1 : 0 ),
157
- map_key_type_callback => sub { 'utf8_string' },
158
- standard_test_metadata(),
159
- %{$metadata},
160
- );
161
-
162
- for my $subnet ( @{$subnets} ) {
163
- $writer->insert_network(
164
- $subnet,
165
- { ip => $subnet->first()->as_string() }
166
- );
167
- }
168
-
169
- my $filename = sprintf(
170
- "$Dir/MaxMind-DB-test-%s-%i.mmdb",
171
- $ip_version_name,
172
- $record_size,
173
- );
174
- open my $fh, '>', $filename;
175
-
176
- $writer->write_tree($fh);
177
-
178
- close $fh;
179
-
180
- return ( $writer, $filename );
181
- }
182
-
183
- {
184
- # We will store this once for each subnet so we will also be testing
185
- # pointers, since the serializer will generate a pointer to this
186
- # structure.
187
- my %all_types = (
188
- utf8_string => 'unicode! ☯ - ♫',
189
- double => 42.123456,
190
- bytes => pack( 'N', 42 ),
191
- uint16 => 100,
192
- uint32 => 2**28,
193
- int32 => -1 * ( 2**28 ),
194
- uint64 => uint128(1) << 60,
195
- uint128 => uint128(1) << 120,
196
- array => [ 1, 2, 3, ],
197
- map => {
198
- mapX => {
199
- utf8_stringX => 'hello',
200
- arrayX => [ 7, 8, 9 ],
201
- },
202
- },
203
- boolean => 1,
204
- float => 1.1,
205
- );
206
-
207
- my %all_types_0 = (
208
- utf8_string => q{},
209
- double => 0,
210
- bytes => q{},
211
- uint16 => 0,
212
- uint32 => 0,
213
- int32 => 0,
214
- uint64 => uint128(0),
215
- uint128 => uint128(0),
216
- array => [],
217
- map => {},
218
- boolean => 0,
219
- float => 0,
220
- );
221
-
222
- sub write_decoder_test_db {
223
- my $writer = MaxMind::DB::Writer::Tree->new(
224
- ip_version => 6,
225
- record_size => 24,
226
- database_type => 'MaxMind DB Decoder Test',
227
- languages => ['en'],
228
- description => {
229
- en =>
230
- 'MaxMind DB Decoder Test database - contains every MaxMind DB data type',
231
- },
232
- alias_ipv6_to_ipv4 => 1,
233
- remove_reserved_networks => 0,
234
- map_key_type_callback => sub {
235
- my $key = $_[0];
236
- $key =~ s/X$//;
237
- return $key eq 'array' ? [ 'array', 'uint32' ] : $key;
238
- },
239
- );
240
-
241
- my @subnets
242
- = map { Net::Works::Network->new_from_string( string => $_ ) }
243
- qw(
244
- ::1.1.1.0/120
245
- ::2.2.0.0/112
246
- ::3.0.0.0/104
247
- ::4.5.6.7/128
248
- abcd::/64
249
- 1000::1234:0000/112
250
- );
251
-
252
- for my $subnet (@subnets) {
253
- $writer->insert_network(
254
- $subnet,
255
- \%all_types,
256
- );
257
- }
258
-
259
- $writer->insert_network(
260
- Net::Works::Network->new_from_string( string => '::0.0.0.0/128' ),
261
- \%all_types_0,
262
- );
263
-
264
- open my $fh, '>', "$Dir/MaxMind-DB-test-decoder.mmdb";
265
- $writer->write_tree($fh);
266
- close $fh;
267
-
268
- return;
269
- }
270
- }
271
-
272
- {
273
- my %nested = (
274
- map1 => {
275
- map2 => {
276
- array => [
277
- {
278
- map3 => { a => 1, b => 2, c => 3 },
279
- },
280
- ],
281
- },
282
- },
283
- );
284
-
285
- sub write_deeply_nested_structures_db {
286
- my $writer = MaxMind::DB::Writer::Tree->new(
287
- ip_version => 6,
288
- record_size => 24,
289
- ip_version => 6,
290
- database_type => 'MaxMind DB Nested Data Structures',
291
- languages => ['en'],
292
- description => {
293
- en =>
294
- 'MaxMind DB Nested Data Structures Test database - contains deeply nested map/array structures',
295
- },
296
- alias_ipv6_to_ipv4 => 1,
297
- map_key_type_callback => sub {
298
- my $key = shift;
299
- return
300
- $key =~ /^map/ ? 'map'
301
- : $key eq 'array' ? [ 'array', 'map' ]
302
- : 'uint32';
303
- }
304
- );
305
-
306
- my @subnets
307
- = map { Net::Works::Network->new_from_string( string => $_ ) }
308
- qw(
309
- ::1.1.1.0/120
310
- ::2.2.0.0/112
311
- ::3.0.0.0/104
312
- ::4.5.6.7/128
313
- abcd::/64
314
- 1000::1234:0000/112
315
- );
316
-
317
- for my $subnet (@subnets) {
318
- $writer->insert_network(
319
- $subnet,
320
- \%nested,
321
- );
322
- }
323
-
324
- open my $fh, '>', "$Dir/MaxMind-DB-test-nested.mmdb";
325
- $writer->write_tree($fh);
326
- close $fh;
327
-
328
- return;
329
- }
330
- }
331
-
332
- sub write_geoip2_dbs {
333
- _write_geoip2_db( @{$_}[ 0, 1 ], 'Test' )
334
- for (
335
- [ 'GeoIP2-Anonymous-IP', {} ],
336
- ['GeoIP2-City'],
337
- ['GeoIP2-Connection-Type'],
338
- ['GeoIP2-Country'],
339
- ['GeoIP2-DensityIncome'],
340
- ['GeoIP2-Domain'],
341
- ['GeoIP2-Enterprise'],
342
- ['GeoIP2-ISP'],
343
- ['GeoIP2-Precision-Enterprise'],
344
- ['GeoIP2-User-Count'],
345
- ['GeoLite2-ASN'],
346
- );
347
- }
348
-
349
- sub write_broken_geoip2_city_db {
350
- no warnings 'redefine';
351
-
352
- # This is how we _used_ to encode doubles. Storing them this way with the
353
- # current reader tools can lead to weird errors. This broken database is a
354
- # good way to test the robustness of reader code in the face of broken
355
- # databases.
356
- local *MaxMind::DB::Writer::Serializer::_encode_double = sub {
357
- my $self = shift;
358
- my $value = shift;
359
-
360
- $self->_simple_encode( double => $value );
361
- };
362
-
363
- _write_geoip2_db( 'GeoIP2-City', 0, 'Test Broken Double Format' );
364
- }
365
-
366
- sub write_invalid_node_count {
367
- no warnings 'redefine';
368
- local *MaxMind::DB::Writer::Tree::node_count = sub { 100000 };
369
-
370
- _write_geoip2_db( 'GeoIP2-City', 0, 'Test Invalid Node Count' );
371
- }
372
-
373
- sub _universal_map_key_type_callback {
374
- my $map = {
375
-
376
- # languages
377
- de => 'utf8_string',
378
- en => 'utf8_string',
379
- es => 'utf8_string',
380
- fr => 'utf8_string',
381
- ja => 'utf8_string',
382
- 'pt-BR' => 'utf8_string',
383
- ru => 'utf8_string',
384
- 'zh-CN' => 'utf8_string',
385
-
386
- # production
387
- accuracy_radius => 'uint16',
388
- autonomous_system_number => 'uint32',
389
- autonomous_system_organization => 'utf8_string',
390
- average_income => 'uint32',
391
- city => 'map',
392
- code => 'utf8_string',
393
- confidence => 'uint16',
394
- connection_type => 'utf8_string',
395
- continent => 'map',
396
- country => 'map',
397
- domain => 'utf8_string',
398
- geoname_id => 'uint32',
399
- ipv4_24 => 'uint32',
400
- ipv4_32 => 'uint32',
401
- ipv6_32 => 'uint32',
402
- ipv6_48 => 'uint32',
403
- ipv6_64 => 'uint32',
404
- is_anonymous => 'boolean',
405
- is_anonymous_proxy => 'boolean',
406
- is_anonymous_vpn => 'boolean',
407
- is_hosting_provider => 'boolean',
408
- is_in_european_union => 'boolean',
409
- is_legitimate_proxy => 'boolean',
410
- is_public_proxy => 'boolean',
411
- is_satellite_provider => 'boolean',
412
- is_tor_exit_node => 'boolean',
413
- iso_code => 'utf8_string',
414
- isp => 'utf8_string',
415
- latitude => 'double',
416
- location => 'map',
417
- longitude => 'double',
418
- metro_code => 'uint16',
419
- names => 'map',
420
- organization => 'utf8_string',
421
- population_density => 'uint32',
422
- postal => 'map',
423
- registered_country => 'map',
424
- represented_country => 'map',
425
- subdivisions => [ 'array', 'map' ],
426
- time_zone => 'utf8_string',
427
- traits => 'map',
428
- traits => 'map',
429
- type => 'utf8_string',
430
- user_type => 'utf8_string',
431
-
432
- # for testing only
433
- foo => 'utf8_string',
434
- bar => 'utf8_string',
435
- buzz => 'utf8_string',
436
- our_value => 'utf8_string',
437
- };
438
-
439
- my $callback = sub {
440
- my $key = shift;
441
-
442
- return $map->{$key} || die <<"ERROR";
443
- Unknown tree key '$key'.
444
-
445
- The universal_map_key_type_callback doesn't know what type to use for the passed
446
- key. If you are adding a new key that will be used in a frozen tree / mmdb then
447
- you should update the mapping in both our internal code and here.
448
- ERROR
449
- };
450
-
451
- return $callback;
452
- }
453
-
454
- sub _write_geoip2_db {
455
- my $type = shift;
456
- my $populate_all_networks_with_data = shift;
457
- my $description = shift;
458
-
459
- my $writer = MaxMind::DB::Writer::Tree->new(
460
- ip_version => 6,
461
- record_size => 28,
462
- ip_version => 6,
463
- database_type => $type,
464
- languages => [ 'en', $type eq 'GeoIP2-City' ? ('zh') : () ],
465
- description => {
466
- en => ( $type =~ s/-/ /gr )
467
- . " $description Database (fake GeoIP2 data, for example purposes only)",
468
- $type eq 'GeoIP2-City' ? ( zh => '小型数据库' ) : (),
469
- },
470
- alias_ipv6_to_ipv4 => 1,
471
- map_key_type_callback => _universal_map_key_type_callback(),
472
- );
473
-
474
- _populate_all_networks( $writer, $populate_all_networks_with_data )
475
- if $populate_all_networks_with_data;
476
-
477
- my $value = shift;
478
- my $nodes
479
- = decode_json( read_binary("$Dir/../source-data/$type-Test.json") );
480
-
481
- for my $node (@$nodes) {
482
- for my $network ( keys %$node ) {
483
- $writer->insert_network(
484
- Net::Works::Network->new_from_string( string => $network ),
485
- $node->{$network}
486
- );
487
- }
488
- }
489
-
490
- my $suffix = $description =~ s/ /-/gr;
491
- open my $output_fh, '>', "$Dir/$type-$suffix.mmdb";
492
- $writer->write_tree($output_fh);
493
- close $output_fh;
494
-
495
- return;
496
- }
497
-
498
- sub _populate_all_networks {
499
- my $writer = shift;
500
- my $data = shift;
501
-
502
- my $max_uint128 = uint128(0) - 1;
503
- my @networks = Net::Works::Network->range_as_subnets(
504
- Net::Works::Address->new_from_integer(
505
- integer => 0,
506
- version => 6,
507
- ),
508
- Net::Works::Address->new_from_integer(
509
- integer => $max_uint128,
510
- version => 6,
511
- ),
512
- );
513
-
514
- for my $network (@networks) {
515
- $writer->insert_network( $network => $data );
516
- }
517
- }
518
-
519
- sub write_no_ipv4_tree_db {
520
- my $subnets = shift;
521
-
522
- my $writer = MaxMind::DB::Writer::Tree->new(
523
- ip_version => 6,
524
- record_size => 24,
525
- ip_version => 6,
526
- database_type => 'MaxMind DB No IPv4 Search Tree',
527
- languages => ['en'],
528
- description => {
529
- en => 'MaxMind DB No IPv4 Search Tree',
530
- },
531
- remove_reserved_networks => 0,
532
- root_data_type => 'utf8_string',
533
- map_key_type_callback => sub { {} },
534
- );
535
-
536
- my $subnet = Net::Works::Network->new_from_string( string => '::/64' );
537
- $writer->insert_network( $subnet, $subnet->as_string() );
538
-
539
- open my $output_fh, '>', "$Dir/MaxMind-DB-no-ipv4-search-tree.mmdb";
540
- $writer->write_tree($output_fh);
541
- close $output_fh;
542
-
543
- return;
544
- }
545
-
546
- # The point of this database is to provide something where we can test looking
547
- # up a single value. In other words, each IP address points to a non-compound
548
- # value, a string rather than a map or array.
549
- sub write_no_map_db {
550
- my $subnets = shift;
551
-
552
- my $writer = MaxMind::DB::Writer::Tree->new(
553
- ip_version => 4,
554
- record_size => 24,
555
- database_type => 'MaxMind DB String Value Entries',
556
- languages => ['en'],
557
- description => {
558
- en =>
559
- 'MaxMind DB String Value Entries (no maps or arrays as values)',
560
- },
561
- root_data_type => 'utf8_string',
562
- map_key_type_callback => sub { {} },
563
- );
564
-
565
- for my $subnet ( @{$subnets} ) {
566
- $writer->insert_network( $subnet, $subnet->as_string() );
567
- }
568
-
569
- open my $output_fh, '>', "$Dir/MaxMind-DB-string-value-entries.mmdb";
570
- $writer->write_tree($output_fh);
571
- close $output_fh;
572
-
573
- return;
574
- }
575
-
576
- sub write_test_serialization_data {
577
- my $serializer = MaxMind::DB::Writer::Serializer->new(
578
- map_key_type_callback => sub { 'utf8_string' } );
579
-
580
- $serializer->store_data( map => { long_key => 'long_value1' } );
581
- $serializer->store_data( map => { long_key => 'long_value2' } );
582
- $serializer->store_data( map => { long_key2 => 'long_value1' } );
583
- $serializer->store_data( map => { long_key2 => 'long_value2' } );
584
- $serializer->store_data( map => { long_key => 'long_value1' } );
585
- $serializer->store_data( map => { long_key2 => 'long_value2' } );
586
-
587
- open my $fh, '>', 'maps-with-pointers.raw';
588
- print {$fh} ${ $serializer->buffer() }
589
- or die "Cannot write to maps-with-pointers.raw: $!";
590
- close $fh;
591
-
592
- return;
593
- }
594
-
595
- sub write_db_with_metadata_pointers {
596
- my $repeated_string = 'Lots of pointers in metadata';
597
- my $writer = MaxMind::DB::Writer::Tree->new(
598
- ip_version => 6,
599
- record_size => 24,
600
- map_key_type_callback => sub { 'utf8_string' },
601
- database_type => $repeated_string,
602
- languages => [ 'en', 'es', 'zh' ],
603
- description => {
604
- en => $repeated_string,
605
- es => $repeated_string,
606
- zh => $repeated_string,
607
- },
608
-
609
- );
610
-
611
- _populate_all_networks( $writer, {} );
612
-
613
- open my $fh, '>', 'MaxMind-DB-test-metadata-pointers.mmdb';
614
-
615
- $writer->write_tree($fh);
616
-
617
- close $fh;
618
- }
619
-
620
- main();