maxmind-geoip2 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/README.md +10 -5
  4. data/lib/maxmind/geoip2/client.rb +18 -9
  5. data/lib/maxmind/geoip2/model/city.rb +4 -5
  6. data/lib/maxmind/geoip2/model/connection_type.rb +3 -2
  7. data/lib/maxmind/geoip2/model/enterprise.rb +2 -3
  8. data/lib/maxmind/geoip2/model/insights.rb +3 -5
  9. data/lib/maxmind/geoip2/record/traits.rb +39 -27
  10. data/lib/maxmind/geoip2/version.rb +8 -0
  11. data/maxmind-geoip2.gemspec +7 -2
  12. data/test/data/cmd/write-test-data/main.go +68 -0
  13. data/test/data/go.mod +13 -0
  14. data/test/data/go.sum +16 -0
  15. data/test/data/perltidyrc +6 -0
  16. data/test/data/pkg/writer/decoder.go +178 -0
  17. data/test/data/pkg/writer/geoip2.go +182 -0
  18. data/test/data/pkg/writer/ip.go +39 -0
  19. data/test/data/pkg/writer/maxmind.go +245 -0
  20. data/test/data/pkg/writer/nestedstructures.go +73 -0
  21. data/test/data/pkg/writer/writer.go +58 -0
  22. data/test/data/source-data/GeoIP2-City-Test.json +322 -1
  23. data/test/data/source-data/GeoIP2-Connection-Type-Test.json +15 -10
  24. data/test/data/source-data/GeoIP2-Country-Test.json +99 -0
  25. data/test/data/source-data/GeoIP2-Domain-Test.json +5 -0
  26. data/test/data/source-data/GeoIP2-Enterprise-Test.json +347 -1
  27. data/test/data/source-data/GeoIP2-Precision-Enterprise-Sandbox-Test.json +296 -0
  28. data/test/data/source-data/GeoIP2-Precision-Enterprise-Test.json +412 -2
  29. data/test/data/source-data/GeoIP2-Static-IP-Score-Test.json +15 -0
  30. data/test/data/source-data/GeoIP2-User-Count-Test.json +18 -0
  31. data/test/data/source-data/GeoLite2-City-Test.json +168 -0
  32. data/test/data/source-data/GeoLite2-Country-Test.json +92 -0
  33. data/test/data/test-data/GeoIP2-Anonymous-IP-Test.mmdb +0 -0
  34. data/test/data/test-data/GeoIP2-City-Test-Broken-Double-Format.mmdb +0 -0
  35. data/test/data/test-data/GeoIP2-City-Test-Invalid-Node-Count.mmdb +0 -0
  36. data/test/data/test-data/GeoIP2-City-Test.mmdb +0 -0
  37. data/test/data/test-data/GeoIP2-Connection-Type-Test.mmdb +0 -0
  38. data/test/data/test-data/GeoIP2-Country-Test.mmdb +0 -0
  39. data/test/data/test-data/GeoIP2-DensityIncome-Test.mmdb +0 -0
  40. data/test/data/test-data/GeoIP2-Domain-Test.mmdb +0 -0
  41. data/test/data/test-data/GeoIP2-Enterprise-Test.mmdb +0 -0
  42. data/test/data/test-data/GeoIP2-ISP-Test.mmdb +0 -0
  43. data/test/data/test-data/GeoIP2-Precision-Enterprise-Test.mmdb +0 -0
  44. data/test/data/test-data/GeoIP2-Static-IP-Score-Test.mmdb +0 -0
  45. data/test/data/test-data/GeoIP2-User-Count-Test.mmdb +0 -0
  46. data/test/data/test-data/GeoLite2-ASN-Test.mmdb +0 -0
  47. data/test/data/test-data/GeoLite2-City-Test.mmdb +0 -0
  48. data/test/data/test-data/GeoLite2-Country-Test.mmdb +0 -0
  49. data/test/data/test-data/MaxMind-DB-no-ipv4-search-tree.mmdb +0 -0
  50. data/test/data/test-data/MaxMind-DB-string-value-entries.mmdb +0 -0
  51. data/test/data/test-data/MaxMind-DB-test-broken-pointers-24.mmdb +0 -0
  52. data/test/data/test-data/MaxMind-DB-test-broken-search-tree-24.mmdb +0 -0
  53. data/test/data/test-data/MaxMind-DB-test-decoder.mmdb +0 -0
  54. data/test/data/test-data/MaxMind-DB-test-ipv4-24.mmdb +0 -0
  55. data/test/data/test-data/MaxMind-DB-test-ipv4-28.mmdb +0 -0
  56. data/test/data/test-data/MaxMind-DB-test-ipv4-32.mmdb +0 -0
  57. data/test/data/test-data/MaxMind-DB-test-ipv6-24.mmdb +0 -0
  58. data/test/data/test-data/MaxMind-DB-test-ipv6-28.mmdb +0 -0
  59. data/test/data/test-data/MaxMind-DB-test-ipv6-32.mmdb +0 -0
  60. data/test/data/test-data/MaxMind-DB-test-metadata-pointers.mmdb +0 -0
  61. data/test/data/test-data/MaxMind-DB-test-mixed-24.mmdb +0 -0
  62. data/test/data/test-data/MaxMind-DB-test-mixed-28.mmdb +0 -0
  63. data/test/data/test-data/MaxMind-DB-test-mixed-32.mmdb +0 -0
  64. data/test/data/test-data/MaxMind-DB-test-nested.mmdb +0 -0
  65. data/test/data/test-data/MaxMind-DB-test-pointer-decoder.mmdb +0 -0
  66. data/test/data/test-data/README.md +28 -12
  67. data/test/test_client.rb +18 -2
  68. data/test/test_reader.rb +19 -1
  69. metadata +16 -7
  70. data/test/data/source-data/README +0 -15
  71. data/test/data/test-data/write-test-data.pl +0 -695
@@ -1,695 +0,0 @@
1
- #!/usr/bin/env perl
2
-
3
- use strict;
4
- use warnings;
5
- use autodie;
6
- use utf8;
7
-
8
- use Cwd qw( abs_path );
9
- use File::Basename qw( dirname );
10
- use File::Slurper qw( read_binary write_binary );
11
- use Cpanel::JSON::XS 4.16 qw( decode_json );
12
- use Math::Int128 qw( MAX_UINT128 string_to_uint128 uint128 );
13
- use MaxMind::DB::Writer::Serializer 0.100004;
14
- use MaxMind::DB::Writer::Tree 0.100004;
15
- use MaxMind::DB::Writer::Util qw( key_for_data );
16
- use Net::Works::Network ();
17
- use Test::MaxMind::DB::Common::Util qw( standard_test_metadata );
18
-
19
- my $Dir = dirname( abs_path($0) );
20
-
21
- sub main {
22
- my @sizes = ( 24, 28, 32 );
23
- my @ipv4_range = ( '1.1.1.1', '1.1.1.32' );
24
-
25
- my @ipv4_subnets = Net::Works::Network->range_as_subnets(@ipv4_range);
26
- for my $record_size (@sizes) {
27
- write_test_db(
28
- $record_size,
29
- \@ipv4_subnets,
30
- { ip_version => 4 },
31
- 'ipv4',
32
- );
33
- }
34
-
35
- write_broken_pointers_test_db(
36
- 24,
37
- \@ipv4_subnets,
38
- { ip_version => 4 },
39
- 'broken-pointers',
40
- );
41
-
42
- write_broken_search_tree_db(
43
- 24,
44
- \@ipv4_subnets,
45
- { ip_version => 4 },
46
- 'broken-search-tree',
47
- );
48
-
49
- my @ipv6_subnets = Net::Works::Network->range_as_subnets(
50
- '::1:ffff:ffff',
51
- '::2:0000:0059'
52
- );
53
-
54
- for my $record_size (@sizes) {
55
- write_test_db(
56
- $record_size,
57
- \@ipv6_subnets,
58
- { ip_version => 6 },
59
- 'ipv6',
60
- );
61
-
62
- write_test_db(
63
- $record_size,
64
- [
65
- @ipv6_subnets,
66
- Net::Works::Network->range_as_subnets( @ipv4_range, 6 ),
67
- ],
68
- { ip_version => 6 },
69
- 'mixed',
70
- );
71
- }
72
-
73
- write_decoder_test_db();
74
- write_pointer_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
- # We limit this to numeric types as the other types would generate
223
- # very large databases
224
- my %numeric_types_max = (
225
- double => 'Inf',
226
- float => 'Inf',
227
- int32 => 0x7fffffff,
228
- uint16 => 0xffff,
229
- uint32 => string_to_uint128('0xffff_ffff'),
230
- uint64 => string_to_uint128('0xffff_ffff_ffff_ffff'),
231
- uint128 => MAX_UINT128,
232
- );
233
-
234
- sub write_decoder_test_db {
235
- my $writer = _decoder_writer();
236
-
237
- my @subnets
238
- = map { Net::Works::Network->new_from_string( string => $_ ) }
239
- qw(
240
- ::1.1.1.0/120
241
- ::2.2.0.0/112
242
- ::3.0.0.0/104
243
- ::4.5.6.7/128
244
- abcd::/64
245
- 1000::1234:0000/112
246
- );
247
-
248
- for my $subnet (@subnets) {
249
- $writer->insert_network(
250
- $subnet,
251
- \%all_types,
252
- );
253
- }
254
-
255
- $writer->insert_network(
256
- Net::Works::Network->new_from_string( string => '::0.0.0.0/128' ),
257
- \%all_types_0,
258
- );
259
-
260
- $writer->insert_network(
261
- Net::Works::Network->new_from_string(
262
- string => '::255.255.255.255/128'
263
- ),
264
- \%numeric_types_max,
265
- );
266
-
267
- open my $fh, '>', "$Dir/MaxMind-DB-test-decoder.mmdb";
268
- $writer->write_tree($fh);
269
- close $fh;
270
-
271
- return;
272
- }
273
-
274
- sub write_pointer_decoder_test_db {
275
-
276
- # We want to create a database where most values are pointers
277
- no warnings 'redefine';
278
- local *MaxMind::DB::Writer::Serializer::_should_cache_value
279
- = sub { 1 };
280
- my $writer = _decoder_writer();
281
-
282
- # We add these slightly different records so that we end up with
283
- # pointers for the individual values in the maps, not just pointers
284
- # to the map
285
- $writer->insert_network(
286
- '1.0.0.0/32',
287
- {
288
- %all_types,
289
- booleanX => 0,
290
- arrayX => [ 1, 2, 3, 4, ],
291
- mapXX => {
292
- utf8_stringX => 'hello',
293
- arrayX => [ 7, 8, 9, 10 ],
294
- booleanX => 0,
295
- },
296
- },
297
- );
298
-
299
- $writer->insert_network(
300
- '1.1.1.0/32',
301
- {
302
- %all_types,
303
-
304
- # This has to be 0 rather than 1 as otherwise the buggy
305
- # Perl writer will think it is the same as an uint32 value of
306
- # 1 and make a pointer to a value of a different type.
307
- boolean => 0,
308
- },
309
- );
310
-
311
- open my $fh, '>', "$Dir/MaxMind-DB-test-pointer-decoder.mmdb";
312
- $writer->write_tree($fh);
313
- close $fh;
314
-
315
- return;
316
- }
317
-
318
- sub _decoder_writer {
319
- return MaxMind::DB::Writer::Tree->new(
320
- ip_version => 6,
321
- record_size => 24,
322
- database_type => 'MaxMind DB Decoder Test',
323
- languages => ['en'],
324
- description => {
325
- en =>
326
- 'MaxMind DB Decoder Test database - contains every MaxMind DB data type',
327
- },
328
- alias_ipv6_to_ipv4 => 1,
329
- remove_reserved_networks => 0,
330
- map_key_type_callback => sub {
331
- my $key = $_[0];
332
- $key =~ s/X*$//;
333
- return $key eq 'array' ? [ 'array', 'uint32' ] : $key;
334
- },
335
- );
336
- }
337
- }
338
-
339
- {
340
- my %nested = (
341
- map1 => {
342
- map2 => {
343
- array => [
344
- {
345
- map3 => { a => 1, b => 2, c => 3 },
346
- },
347
- ],
348
- },
349
- },
350
- );
351
-
352
- sub write_deeply_nested_structures_db {
353
- my $writer = MaxMind::DB::Writer::Tree->new(
354
- ip_version => 6,
355
- record_size => 24,
356
- ip_version => 6,
357
- database_type => 'MaxMind DB Nested Data Structures',
358
- languages => ['en'],
359
- description => {
360
- en =>
361
- 'MaxMind DB Nested Data Structures Test database - contains deeply nested map/array structures',
362
- },
363
- alias_ipv6_to_ipv4 => 1,
364
- map_key_type_callback => sub {
365
- my $key = shift;
366
- return
367
- $key =~ /^map/ ? 'map'
368
- : $key eq 'array' ? [ 'array', 'map' ]
369
- : 'uint32';
370
- }
371
- );
372
-
373
- my @subnets
374
- = map { Net::Works::Network->new_from_string( string => $_ ) }
375
- qw(
376
- ::1.1.1.0/120
377
- ::2.2.0.0/112
378
- ::3.0.0.0/104
379
- ::4.5.6.7/128
380
- abcd::/64
381
- 1000::1234:0000/112
382
- );
383
-
384
- for my $subnet (@subnets) {
385
- $writer->insert_network(
386
- $subnet,
387
- \%nested,
388
- );
389
- }
390
-
391
- open my $fh, '>', "$Dir/MaxMind-DB-test-nested.mmdb";
392
- $writer->write_tree($fh);
393
- close $fh;
394
-
395
- return;
396
- }
397
- }
398
-
399
- sub write_geoip2_dbs {
400
- _write_geoip2_db( @{$_}[ 0, 1 ], 'Test' )
401
- for (
402
- [ 'GeoIP2-Anonymous-IP', {} ],
403
- ['GeoIP2-City'],
404
- ['GeoIP2-Connection-Type'],
405
- ['GeoIP2-Country'],
406
- ['GeoIP2-DensityIncome'],
407
- ['GeoIP2-Domain'],
408
- ['GeoIP2-Enterprise'],
409
- ['GeoIP2-ISP'],
410
- ['GeoIP2-Precision-Enterprise'],
411
- ['GeoIP2-Static-IP-Score'],
412
- ['GeoIP2-User-Count'],
413
- ['GeoLite2-ASN'],
414
- ['GeoLite2-City'],
415
- ['GeoLite2-Country'],
416
- );
417
- }
418
-
419
- sub write_broken_geoip2_city_db {
420
- no warnings 'redefine';
421
-
422
- # This is how we _used_ to encode doubles. Storing them this way with the
423
- # current reader tools can lead to weird errors. This broken database is a
424
- # good way to test the robustness of reader code in the face of broken
425
- # databases.
426
- local *MaxMind::DB::Writer::Serializer::_encode_double = sub {
427
- my $self = shift;
428
- my $value = shift;
429
-
430
- $self->_simple_encode( double => $value );
431
- };
432
-
433
- _write_geoip2_db( 'GeoIP2-City', 0, 'Test Broken Double Format' );
434
- }
435
-
436
- sub write_invalid_node_count {
437
- no warnings 'redefine';
438
- local *MaxMind::DB::Writer::Tree::node_count = sub { 100000 };
439
-
440
- _write_geoip2_db( 'GeoIP2-City', 0, 'Test Invalid Node Count' );
441
- }
442
-
443
- sub _universal_map_key_type_callback {
444
- my $map = {
445
-
446
- # languages
447
- de => 'utf8_string',
448
- en => 'utf8_string',
449
- es => 'utf8_string',
450
- fr => 'utf8_string',
451
- ja => 'utf8_string',
452
- 'pt-BR' => 'utf8_string',
453
- ru => 'utf8_string',
454
- 'zh-CN' => 'utf8_string',
455
-
456
- # production
457
- accuracy_radius => 'uint16',
458
- autonomous_system_number => 'uint32',
459
- autonomous_system_organization => 'utf8_string',
460
- average_income => 'uint32',
461
- city => 'map',
462
- code => 'utf8_string',
463
- confidence => 'uint16',
464
- connection_type => 'utf8_string',
465
- continent => 'map',
466
- country => 'map',
467
- domain => 'utf8_string',
468
- geoname_id => 'uint32',
469
- ipv4_24 => 'uint32',
470
- ipv4_32 => 'uint32',
471
- ipv6_32 => 'uint32',
472
- ipv6_48 => 'uint32',
473
- ipv6_64 => 'uint32',
474
- is_anonymous => 'boolean',
475
- is_anonymous_proxy => 'boolean',
476
- is_anonymous_vpn => 'boolean',
477
- is_hosting_provider => 'boolean',
478
- is_in_european_union => 'boolean',
479
- is_legitimate_proxy => 'boolean',
480
- is_public_proxy => 'boolean',
481
- is_residential_proxy => 'boolean',
482
- is_satellite_provider => 'boolean',
483
- is_tor_exit_node => 'boolean',
484
- iso_code => 'utf8_string',
485
- isp => 'utf8_string',
486
- latitude => 'double',
487
- location => 'map',
488
- longitude => 'double',
489
- metro_code => 'uint16',
490
- mobile_country_code => 'utf8_string',
491
- mobile_network_code => 'utf8_string',
492
- names => 'map',
493
- organization => 'utf8_string',
494
- population_density => 'uint32',
495
- postal => 'map',
496
- registered_country => 'map',
497
- represented_country => 'map',
498
- score => 'double',
499
- static_ip_score => 'double',
500
- subdivisions => [ 'array', 'map' ],
501
- time_zone => 'utf8_string',
502
- traits => 'map',
503
- traits => 'map',
504
- type => 'utf8_string',
505
- user_type => 'utf8_string',
506
-
507
- # for testing only
508
- foo => 'utf8_string',
509
- bar => 'utf8_string',
510
- buzz => 'utf8_string',
511
- our_value => 'utf8_string',
512
- };
513
-
514
- my $callback = sub {
515
- my $key = shift;
516
-
517
- return $map->{$key} || die <<"ERROR";
518
- Unknown tree key '$key'.
519
-
520
- The universal_map_key_type_callback doesn't know what type to use for the passed
521
- key. If you are adding a new key that will be used in a frozen tree / mmdb then
522
- you should update the mapping in both our internal code and here.
523
- ERROR
524
- };
525
-
526
- return $callback;
527
- }
528
-
529
- sub _write_geoip2_db {
530
- my $type = shift;
531
- my $populate_all_networks_with_data = shift;
532
- my $description = shift;
533
-
534
- my $writer = MaxMind::DB::Writer::Tree->new(
535
- ip_version => 6,
536
- record_size => 28,
537
- ip_version => 6,
538
- database_type => $type,
539
- languages => [ 'en', $type eq 'GeoIP2-City' ? ('zh') : () ],
540
- description => {
541
- en => ( $type =~ s/-/ /gr )
542
- . " $description Database (fake GeoIP2 data, for example purposes only)",
543
- $type eq 'GeoIP2-City' ? ( zh => '小型数据库' ) : (),
544
- },
545
- alias_ipv6_to_ipv4 => 1,
546
- map_key_type_callback => _universal_map_key_type_callback(),
547
- );
548
-
549
- _populate_all_networks( $writer, $populate_all_networks_with_data )
550
- if $populate_all_networks_with_data;
551
-
552
- my $value = shift;
553
- my $nodes
554
- = decode_json( read_binary("$Dir/../source-data/$type-Test.json") );
555
-
556
- for my $node (@$nodes) {
557
- for my $network ( keys %$node ) {
558
- $writer->insert_network(
559
- Net::Works::Network->new_from_string( string => $network ),
560
- $node->{$network}
561
- );
562
- }
563
- }
564
-
565
- my $suffix = $description =~ s/ /-/gr;
566
- open my $output_fh, '>', "$Dir/$type-$suffix.mmdb";
567
- $writer->write_tree($output_fh);
568
- close $output_fh;
569
-
570
- return;
571
- }
572
-
573
- sub _populate_all_networks {
574
- my $writer = shift;
575
- my $data = shift;
576
-
577
- my $max_uint128 = uint128(0) - 1;
578
- my @networks = Net::Works::Network->range_as_subnets(
579
- Net::Works::Address->new_from_integer(
580
- integer => 0,
581
- version => 6,
582
- ),
583
- Net::Works::Address->new_from_integer(
584
- integer => $max_uint128,
585
- version => 6,
586
- ),
587
- );
588
-
589
- for my $network (@networks) {
590
- $writer->insert_network( $network => $data );
591
- }
592
- }
593
-
594
- sub write_no_ipv4_tree_db {
595
- my $subnets = shift;
596
-
597
- my $writer = MaxMind::DB::Writer::Tree->new(
598
- ip_version => 6,
599
- record_size => 24,
600
- ip_version => 6,
601
- database_type => 'MaxMind DB No IPv4 Search Tree',
602
- languages => ['en'],
603
- description => {
604
- en => 'MaxMind DB No IPv4 Search Tree',
605
- },
606
- remove_reserved_networks => 0,
607
- root_data_type => 'utf8_string',
608
- map_key_type_callback => sub { {} },
609
- );
610
-
611
- my $subnet = Net::Works::Network->new_from_string( string => '::/64' );
612
- $writer->insert_network( $subnet, $subnet->as_string() );
613
-
614
- open my $output_fh, '>', "$Dir/MaxMind-DB-no-ipv4-search-tree.mmdb";
615
- $writer->write_tree($output_fh);
616
- close $output_fh;
617
-
618
- return;
619
- }
620
-
621
- # The point of this database is to provide something where we can test looking
622
- # up a single value. In other words, each IP address points to a non-compound
623
- # value, a string rather than a map or array.
624
- sub write_no_map_db {
625
- my $subnets = shift;
626
-
627
- my $writer = MaxMind::DB::Writer::Tree->new(
628
- ip_version => 4,
629
- record_size => 24,
630
- database_type => 'MaxMind DB String Value Entries',
631
- languages => ['en'],
632
- description => {
633
- en =>
634
- 'MaxMind DB String Value Entries (no maps or arrays as values)',
635
- },
636
- root_data_type => 'utf8_string',
637
- map_key_type_callback => sub { {} },
638
- );
639
-
640
- for my $subnet ( @{$subnets} ) {
641
- $writer->insert_network( $subnet, $subnet->as_string() );
642
- }
643
-
644
- open my $output_fh, '>', "$Dir/MaxMind-DB-string-value-entries.mmdb";
645
- $writer->write_tree($output_fh);
646
- close $output_fh;
647
-
648
- return;
649
- }
650
-
651
- sub write_test_serialization_data {
652
- my $serializer = MaxMind::DB::Writer::Serializer->new(
653
- map_key_type_callback => sub { 'utf8_string' } );
654
-
655
- $serializer->store_data( map => { long_key => 'long_value1' } );
656
- $serializer->store_data( map => { long_key => 'long_value2' } );
657
- $serializer->store_data( map => { long_key2 => 'long_value1' } );
658
- $serializer->store_data( map => { long_key2 => 'long_value2' } );
659
- $serializer->store_data( map => { long_key => 'long_value1' } );
660
- $serializer->store_data( map => { long_key2 => 'long_value2' } );
661
-
662
- open my $fh, '>', "$Dir/maps-with-pointers.raw";
663
- print {$fh} ${ $serializer->buffer() }
664
- or die "Cannot write to maps-with-pointers.raw: $!";
665
- close $fh;
666
-
667
- return;
668
- }
669
-
670
- sub write_db_with_metadata_pointers {
671
- my $repeated_string = 'Lots of pointers in metadata';
672
- my $writer = MaxMind::DB::Writer::Tree->new(
673
- ip_version => 6,
674
- record_size => 24,
675
- map_key_type_callback => sub { 'utf8_string' },
676
- database_type => $repeated_string,
677
- languages => [ 'en', 'es', 'zh' ],
678
- description => {
679
- en => $repeated_string,
680
- es => $repeated_string,
681
- zh => $repeated_string,
682
- },
683
-
684
- );
685
-
686
- _populate_all_networks( $writer, {} );
687
-
688
- open my $fh, '>', "$Dir/MaxMind-DB-test-metadata-pointers.mmdb";
689
-
690
- $writer->write_tree($fh);
691
-
692
- close $fh;
693
- }
694
-
695
- main();