activerecord-dbt 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -6,7 +6,33 @@
6
6
 
7
7
  `ActiveRecord::Dbt` generates [dbt](https://www.getdbt.com/) files from the information of the database connected via ActiveRecord.
8
8
 
9
- Currently, it can generate `yaml` files for `sources` and `models` files for `staging`.
9
+ Currently, it can generate:
10
+
11
+ - Sources: `YAML` files
12
+ - Staging models: `SQL` and `YAML` files
13
+ - Seeds: `CSV` and `YAML` files (based on `ActiveRecord` enum values)
14
+
15
+ > [!WARNING]
16
+ >
17
+ > dbt Version Compatibility
18
+ >
19
+ > Generated files are optimized for dbt v1.10+. For older versions, the following manual changes are required:
20
+ >
21
+ > | dbt Version | Required Changes |
22
+ > |-------------|------------------|
23
+ > | v1.7 or below | Rename `data_tests:` to `tests:` ([reference](https://docs.getdbt.com/docs/build/data-tests#new-data_tests-syntax)) |
24
+ > | v1.9 or below | Move properties from under `config:` to the top level ([reference](https://docs.getdbt.com/docs/dbt-versions/core-upgrade/upgrading-to-v1.10#custom-inputs)) |
25
+
26
+ ## Table of Contents
27
+
28
+ - [Installation](#installation)
29
+ - [Usage](#usage)
30
+ - [Configuration](#configuration)
31
+ - [Generate dbt Source File](#generate-dbt-source-file)
32
+ - [Generate dbt Staging Files](#generate-dbt-staging-files)
33
+ - [Generate dbt Seed Files](#generate-dbt-seed-files)
34
+ - [Contributing](#contributing)
35
+ - [License](#license)
10
36
 
11
37
  ## Installation
12
38
 
@@ -52,8 +78,8 @@ This will generate the `config/initializers/dbt.rb` file.
52
78
 
53
79
  Configuration | Description
54
80
  --------- | ---------
55
- config_directory_path | The path to the directory where files generated by `bin/rails generate active_record:dbt:*` are stored. The default is `lib/dbt`.
56
- export_directory_path | The path to the directory where configuration files are stored. The default is `doc/dbt`.
81
+ config_directory_path | The path to the directory where configuration files are stored. The default is `lib/dbt`.
82
+ export_directory_path | The path to the directory where files generated by `bin/rails generate active_record:dbt:*` are stored. The default is `doc/dbt`.
57
83
  dwh_platform | Specify the data warehouse platform to which dbt connects. The default is `bigquery`.
58
84
  data_sync_delayed | Indicates whether there is a data delay. If set to `true`, `severity: warn` is applied to the `relationships` test. The default is `false`.
59
85
  logger | The destination for log output. The default is `Logger.new('./log/active_record_dbt.log')`.
@@ -126,18 +152,29 @@ The available properties for `sources` and `table_overrides` are detailed in [So
126
152
 
127
153
  ##### sources
128
154
 
129
- Set all properties except for `tables`.
155
+ Set the configurations for `sources`.
156
+
157
+ Configuration | Description
158
+ --------- | ---------
159
+ project_name | Written to the beginning of the table or model `description`.
160
+ table_names in `exclude` | Specify which table names you do not want output in `sources`.
130
161
 
131
162
  Example:
132
163
 
133
164
  ```yml
134
165
  sources:
135
166
  name: dummy
136
- meta:
137
- generated_by: activerecord-dbt
138
167
  description: |-
139
168
  Write a description of the 'dummy' source.
140
169
  You can write multiple lines.
170
+ config:
171
+ meta:
172
+ project_name: dummy_project
173
+ generated_by: activerecord-dbt
174
+ exclude:
175
+ table_names:
176
+ - ar_internal_metadata
177
+ - schema_migrations
141
178
 
142
179
  ```
143
180
 
@@ -150,14 +187,15 @@ Example:
150
187
  ```yml
151
188
  table_overrides:
152
189
  users:
153
- loaded_at_field: created_at
154
- freshness:
155
- warn_after:
156
- count: 3
157
- period: day
158
- error_after:
159
- count: 5
160
- period: day
190
+ config:
191
+ freshness:
192
+ warn_after:
193
+ count: 3
194
+ period: day
195
+ error_after:
196
+ count: 5
197
+ period: day
198
+ loaded_at_field: created_at
161
199
  columns:
162
200
  created_at:
163
201
  data_tests:
@@ -170,15 +208,15 @@ table_overrides:
170
208
 
171
209
  Set the default value for the `description`(`logical_name`, `description`) of `tables`.
172
210
 
173
- In the `logical_name` and `description` of `table_descriptions`, you can refer to the table name with `{{ table_name }}`.
174
- In the `description` of `table_descriptions.columns`, you can refer to the table name with `{{ table_name }}` and the column name with `{{ column_name }}`.
211
+ In the `logical_name` and `description` fields of `table_descriptions`, you can use `{{ table_name }}` to refer to the table name and `{{ project_name }}` to refer to the project name.
212
+ In the `description` of `table_descriptions.columns`, you can use `{{ table_name }}` to refer to the table name and `{{ column_name }}` to refer to the column name.
175
213
 
176
214
  Example:
177
215
 
178
216
  ```yml
179
217
  defaults:
180
218
  table_descriptions:
181
- logical_name: Write a logical_name of the '{{ table_name }}' table.
219
+ logical_name: Write the logical_name of the '{{ table_name }}' table in '{{ project_name }}'.
182
220
  columns:
183
221
  description: Write a description of the '{{ table_name }}.{{ column_name }}' column.
184
222
 
@@ -189,7 +227,7 @@ If nothing is set, it defaults to the following:
189
227
  ```yml
190
228
  defaults:
191
229
  table_descriptions:
192
- logical_name: Write a logical_name of the '{{ table_name }}' table.
230
+ logical_name: Write the logical_name of the '{{ table_name }}' table in '{{ project_name }}'.
193
231
  columns:
194
232
  description: Write a description of the '{{ table_name }}.{{ column_name }}' column.
195
233
 
@@ -228,29 +266,33 @@ table_descriptions:
228
266
 
229
267
  ```
230
268
 
231
- ##### Example:
232
-
233
269
  Adjust the settings according to your environment.
234
270
 
235
271
  ```yml
236
272
  sources:
237
273
  name: dummy
238
- meta:
239
- generated_by: activerecord-dbt
240
274
  description: |-
241
275
  Write a description of the 'dummy' source.
242
276
  You can write multiple lines.
277
+ config:
278
+ meta:
279
+ project_name: dummy_project
280
+ generated_by: activerecord-dbt
281
+ exclude:
282
+ table_names:
283
+ - hoges
243
284
 
244
285
  table_overrides:
245
286
  users:
246
- loaded_at_field: created_at
247
- freshness:
248
- warn_after:
249
- count: 3
250
- period: day
251
- error_after:
252
- count: 5
253
- period: day
287
+ config:
288
+ freshness:
289
+ warn_after:
290
+ count: 3
291
+ period: day
292
+ error_after:
293
+ count: 5
294
+ period: day
295
+ loaded_at_field: created_at
254
296
  columns:
255
297
  created_at:
256
298
  data_tests:
@@ -259,9 +301,12 @@ table_overrides:
259
301
 
260
302
  defaults:
261
303
  table_descriptions:
262
- logical_name: Write a logical_name of the '{{ table_name }}' table.
304
+ logical_name: Write the logical_name of the '{{ table_name }}' table in '{{ project_name }}'.
263
305
  columns:
264
306
  description: Write a description of the '{{ table_name }}.{{ column_name }}' column.
307
+ seed_descriptions:
308
+ enum:
309
+ description: "{{ project_name }} {{ table_logical_name }} {{ column_description }} enum"
265
310
 
266
311
  table_descriptions:
267
312
  ar_internal_metadata:
@@ -294,34 +339,31 @@ $ bin/rails generate active_record:dbt:source
294
339
 
295
340
  Generate `#{export_directory_path}/models/sources/#{source_name}/src_#{source_name}.yml`.
296
341
 
297
- ##### Example:
342
+ Example:
298
343
 
299
344
  > [!NOTE]
300
345
  >
301
346
  > The output will be as shown below. It is recommended to indent the YAML file with a tool of your choice.
302
347
 
303
- > [!WARNING]
304
- >
305
- > If you are using a version of dbt lower than v1.8, replace `tests:` with `data_tests:` in the generated file.
306
- >
307
- > [Add data tests to your DAG | dbt Developer Hub](https://docs.getdbt.com/docs/build/data-tests#new-data_tests-syntax)
308
- >
309
- >> Data tests were historically called "tests" in dbt as the only form of testing available. With the introduction of unit tests in v1.8, the key was renamed from `tests:` to `data_tests:`.
310
-
311
348
  ```yaml
312
349
  ---
313
350
  version: 2
314
351
  sources:
315
352
  - name: dummy
316
- meta:
317
- generated_by: activerecord-dbt
318
353
  description: |-
319
354
  Write a description of the 'dummy' source.
320
355
  You can write multiple lines.
356
+ config:
357
+ meta:
358
+ project_name: dummy_project
359
+ generated_by: activerecord-dbt
360
+ exclude:
361
+ table_names:
362
+ - hoges
321
363
  tables:
322
364
  - name: ar_internal_metadata
323
365
  description: |-
324
- # Internal Metadata
366
+ # dummy_project Internal Metadata
325
367
  By default Rails will store information about your Rails environment and schema
326
368
  in an internal table named `ar_internal_metadata`.
327
369
  columns:
@@ -345,7 +387,7 @@ sources:
345
387
  data_tests:
346
388
  - not_null
347
389
  - name: companies
348
- description: Write a logical_name of the 'companies' table.
390
+ description: Write the logical_name of the 'companies' table in 'dummy_project'.
349
391
  columns:
350
392
  - name: id
351
393
  description: id
@@ -370,10 +412,11 @@ sources:
370
412
  data_tests:
371
413
  - not_null
372
414
  - accepted_values:
373
- values:
374
- - true
375
- - false
376
- quote: false
415
+ arguments:
416
+ values:
417
+ - true
418
+ - false
419
+ quote: false
377
420
  - name: created_at
378
421
  description: Created At
379
422
  data_type: datetime
@@ -385,7 +428,7 @@ sources:
385
428
  data_tests:
386
429
  - not_null
387
430
  - name: posts
388
- description: Post
431
+ description: dummy_project Post
389
432
  columns:
390
433
  - name: id
391
434
  description: ID
@@ -399,10 +442,11 @@ sources:
399
442
  data_tests:
400
443
  - not_null
401
444
  - relationships:
402
- to: source('dummy', 'users')
403
- field: id
404
- meta:
405
- relationship_type: many-to-one
445
+ arguments:
446
+ to: source('dummy', 'users')
447
+ field: id
448
+ meta:
449
+ relationship_type: many-to-one
406
450
  - name: title
407
451
  description: Title
408
452
  data_type: string
@@ -420,22 +464,24 @@ sources:
420
464
  data_tests:
421
465
  - not_null
422
466
  - name: status
423
- description: Write a description of the 'posts.status' column.
467
+ description: Status
424
468
  data_type: int64
425
469
  data_tests:
426
470
  - accepted_values:
427
- values:
428
- - 0
429
- - 1
430
- - 2
431
- quote: false
471
+ arguments:
472
+ values:
473
+ - 0
474
+ - 1
475
+ - 2
476
+ quote: false
432
477
  - name: posts_tags
433
- description: Write a logical_name of the 'posts_tags' table.
478
+ description: Write the logical_name of the 'posts_tags' table in 'dummy_project'.
434
479
  data_tests:
435
480
  - dbt_utils.unique_combination_of_columns:
436
- combination_of_columns:
437
- - post_id
438
- - tag_id
481
+ arguments:
482
+ combination_of_columns:
483
+ - post_id
484
+ - tag_id
439
485
  columns:
440
486
  - name: post_id
441
487
  description: post_id
@@ -443,28 +489,38 @@ sources:
443
489
  data_tests:
444
490
  - not_null
445
491
  - relationships:
446
- to: source('dummy', 'posts')
447
- field: id
448
- meta:
449
- relationship_type: many-to-one
450
- active_record_dbt_error:
451
- class: NameError
452
- message: uninitialized constant PostsTag
492
+ arguments:
493
+ to: source('dummy', 'posts')
494
+ field: id
495
+ meta:
496
+ relationship_type: many-to-one
497
+ active_record_dbt_error:
498
+ class: NameError
499
+ message: |-
500
+ uninitialized constant PostsTag
501
+
502
+ Object.const_get(camel_cased_word)
503
+ ^^^^^^^^^^
453
504
  - name: tag_id
454
505
  description: tag_id
455
506
  data_type: int64
456
507
  data_tests:
457
508
  - not_null
458
509
  - relationships:
459
- to: source('dummy', 'tags')
460
- field: id
461
- meta:
462
- relationship_type: many-to-one
463
- active_record_dbt_error:
464
- class: NameError
465
- message: uninitialized constant PostsTag
510
+ arguments:
511
+ to: source('dummy', 'tags')
512
+ field: id
513
+ meta:
514
+ relationship_type: many-to-one
515
+ active_record_dbt_error:
516
+ class: NameError
517
+ message: |-
518
+ uninitialized constant PostsTag
519
+
520
+ Object.const_get(camel_cased_word)
521
+ ^^^^^^^^^^
466
522
  - name: profiles
467
- description: Write a logical_name of the 'profiles' table.
523
+ description: Write the logical_name of the 'profiles' table in 'dummy_project'.
468
524
  columns:
469
525
  - name: id
470
526
  description: id
@@ -479,10 +535,11 @@ sources:
479
535
  - unique
480
536
  - not_null
481
537
  - relationships:
482
- to: source('dummy', 'users')
483
- field: id
484
- meta:
485
- relationship_type: one-to-one
538
+ arguments:
539
+ to: source('dummy', 'users')
540
+ field: id
541
+ meta:
542
+ relationship_type: one-to-one
486
543
  - name: first_name
487
544
  description: Write a description of the 'profiles.first_name' column.
488
545
  data_type: string
@@ -504,12 +561,13 @@ sources:
504
561
  data_tests:
505
562
  - not_null
506
563
  - name: relationships
507
- description: Write a logical_name of the 'relationships' table.
564
+ description: Write the logical_name of the 'relationships' table in 'dummy_project'.
508
565
  data_tests:
509
566
  - dbt_utils.unique_combination_of_columns:
510
- combination_of_columns:
511
- - follower_id
512
- - followed_id
567
+ arguments:
568
+ combination_of_columns:
569
+ - follower_id
570
+ - followed_id
513
571
  columns:
514
572
  - name: id
515
573
  description: id
@@ -523,20 +581,22 @@ sources:
523
581
  data_tests:
524
582
  - not_null
525
583
  - relationships:
526
- to: source('dummy', 'users')
527
- field: id
528
- meta:
529
- relationship_type: many-to-one
584
+ arguments:
585
+ to: source('dummy', 'users')
586
+ field: id
587
+ meta:
588
+ relationship_type: many-to-one
530
589
  - name: followed_id
531
590
  description: followed_id
532
591
  data_type: int64
533
592
  data_tests:
534
593
  - not_null
535
594
  - relationships:
536
- to: source('dummy', 'users')
537
- field: id
538
- meta:
539
- relationship_type: many-to-one
595
+ arguments:
596
+ to: source('dummy', 'users')
597
+ field: id
598
+ meta:
599
+ relationship_type: many-to-one
540
600
  - name: created_at
541
601
  description: Created At
542
602
  data_type: datetime
@@ -549,7 +609,7 @@ sources:
549
609
  - not_null
550
610
  - name: schema_migrations
551
611
  description: |-
552
- # Schema Migrations
612
+ # dummy_project Schema Migrations
553
613
  Rails keeps track of which migrations have been committed to the database and
554
614
  stores them in a neighboring table in that same database called `schema_migrations`.
555
615
  columns:
@@ -560,7 +620,7 @@ sources:
560
620
  - unique
561
621
  - not_null
562
622
  - name: tags
563
- description: Write a logical_name of the 'tags' table.
623
+ description: Write the logical_name of the 'tags' table in 'dummy_project'.
564
624
  columns:
565
625
  - name: id
566
626
  description: id
@@ -585,12 +645,13 @@ sources:
585
645
  data_tests:
586
646
  - not_null
587
647
  - name: user_tags
588
- description: Write a logical_name of the 'user_tags' table.
648
+ description: Write the logical_name of the 'user_tags' table in 'dummy_project'.
589
649
  data_tests:
590
650
  - dbt_utils.unique_combination_of_columns:
591
- combination_of_columns:
592
- - user_id
593
- - tag_id
651
+ arguments:
652
+ combination_of_columns:
653
+ - user_id
654
+ - tag_id
594
655
  columns:
595
656
  - name: id
596
657
  description: id
@@ -604,20 +665,22 @@ sources:
604
665
  data_tests:
605
666
  - not_null
606
667
  - relationships:
607
- to: source('dummy', 'users')
608
- field: id
609
- meta:
610
- relationship_type: many-to-one
668
+ arguments:
669
+ to: source('dummy', 'users')
670
+ field: id
671
+ meta:
672
+ relationship_type: many-to-one
611
673
  - name: tag_id
612
674
  description: tag_id
613
675
  data_type: int64
614
676
  data_tests:
615
677
  - not_null
616
678
  - relationships:
617
- to: source('dummy', 'tags')
618
- field: id
619
- meta:
620
- relationship_type: many-to-one
679
+ arguments:
680
+ to: source('dummy', 'tags')
681
+ field: id
682
+ meta:
683
+ relationship_type: many-to-one
621
684
  - name: created_at
622
685
  description: Created At
623
686
  data_type: datetime
@@ -629,15 +692,16 @@ sources:
629
692
  data_tests:
630
693
  - not_null
631
694
  - name: users
632
- description: User
633
- loaded_at_field: created_at
634
- freshness:
635
- warn_after:
636
- count: 3
637
- period: day
638
- error_after:
639
- count: 5
640
- period: day
695
+ description: dummy_project User
696
+ config:
697
+ freshness:
698
+ warn_after:
699
+ count: 3
700
+ period: day
701
+ error_after:
702
+ count: 5
703
+ period: day
704
+ loaded_at_field: created_at
641
705
  columns:
642
706
  - name: id
643
707
  description: ID
@@ -661,10 +725,11 @@ sources:
661
725
  data_type: int64
662
726
  data_tests:
663
727
  - relationships:
664
- to: source('dummy', 'companies')
665
- field: id
666
- meta:
667
- relationship_type: many-to-one
728
+ arguments:
729
+ to: source('dummy', 'companies')
730
+ field: id
731
+ meta:
732
+ relationship_type: many-to-one
668
733
 
669
734
  ```
670
735
 
@@ -846,20 +911,12 @@ Example:
846
911
  >
847
912
  > The output will be as shown below. It is recommended to indent the YAML file with a tool of your choice.
848
913
 
849
- > [!WARNING]
850
- >
851
- > If you are using a version of dbt lower than v1.8, replace `tests:` with `data_tests:` in the generated file.
852
- >
853
- > [Add data tests to your DAG | dbt Developer Hub](https://docs.getdbt.com/docs/build/data-tests#new-data_tests-syntax)
854
- >
855
- >> Data tests were historically called "tests" in dbt as the only form of testing available. With the introduction of unit tests in v1.8, the key was renamed from `tests:` to `data_tests:`.
856
-
857
914
  ```yaml
858
915
  ---
859
916
  version: 2
860
917
  models:
861
918
  - name: stg_dummy__profiles
862
- description: Write a logical_name of the 'profiles' table.
919
+ description: Write the logical_name of the 'profiles' table in 'dummy_project'.
863
920
  columns:
864
921
  - name: profile_id
865
922
  description: profile_id
@@ -868,10 +925,11 @@ models:
868
925
  - unique
869
926
  - not_null
870
927
  - relationships:
871
- to: source('dummy', 'profiles')
872
- field: id
873
- meta:
874
- relationship_type: one-to-one
928
+ arguments:
929
+ to: source('dummy', 'profiles')
930
+ field: id
931
+ meta:
932
+ relationship_type: one-to-one
875
933
  - name: user_id
876
934
  description: user_id
877
935
  data_type: int64
@@ -879,10 +937,11 @@ models:
879
937
  - unique
880
938
  - not_null
881
939
  - relationships:
882
- to: source('dummy', 'users')
883
- field: id
884
- meta:
885
- relationship_type: one-to-one
940
+ arguments:
941
+ to: source('dummy', 'users')
942
+ field: id
943
+ meta:
944
+ relationship_type: one-to-one
886
945
  - name: first_name
887
946
  description: Write a description of the 'profiles.first_name' column.
888
947
  data_type: string
@@ -906,7 +965,7 @@ models:
906
965
 
907
966
  ```
908
967
 
909
- ### Generated dbt Seed Files
968
+ ### Generate dbt Seed Files
910
969
 
911
970
  #### dbt Seed Configuration
912
971
 
@@ -917,7 +976,7 @@ You can configure `defaults` in this file.
917
976
 
918
977
  Set the default value for the `description` of the `seeds` enum.
919
978
 
920
- In the `description` of `seed_descriptions.enum`, you can refer to the source name with `{{ source_name }}`, the translated table name with `{{ translated_table_name }}`, and the translated column name with `{{ translated_attribute_name }}`.
979
+ In the `description` of `seed_descriptions.enum`, you can refer to the project name with `{{ project_name }}`, the table logical table name with `{{ table_logical_name }}`, and the column description with `{{ column_description }}`.
921
980
 
922
981
  Example:
923
982
 
@@ -925,7 +984,7 @@ Example:
925
984
  defaults:
926
985
  seed_descriptions:
927
986
  enum:
928
- description: "{{ source_name }} {{ translated_table_name }} {{ translated_attribute_name }} enum"
987
+ description: "{{ project_name }} {{ table_logical_name }} {{ column_description }} enum"
929
988
 
930
989
  ```
931
990
 
@@ -935,7 +994,7 @@ If nothing is set, it defaults to the following:
935
994
  defaults:
936
995
  seed_descriptions:
937
996
  enum:
938
- description: "{{ source_name }} {{ translated_table_name }} {{ translated_attribute_name }} enum"
997
+ description: "{{ project_name }} {{ table_logical_name }} {{ column_description }} enum"
939
998
 
940
999
  ```
941
1000
 
@@ -980,47 +1039,43 @@ Example:
980
1039
  >
981
1040
  > The output will be as shown below. It is recommended to indent the YAML file with a tool of your choice.
982
1041
 
983
- > [!WARNING]
984
- >
985
- > If you are using a version of dbt lower than v1.8, replace `tests:` with `data_tests:` in the generated file.
986
- >
987
- > [Add data tests to your DAG | dbt Developer Hub](https://docs.getdbt.com/docs/build/data-tests#new-data_tests-syntax)
988
- >
989
- >> Data tests were historically called "tests" in dbt as the only form of testing available. With the introduction of unit tests in v1.8, the key was renamed from `tests:` to `data_tests:`.
990
-
991
1042
  ```yaml
992
1043
  ---
993
1044
  version: 2
994
1045
  seeds:
995
1046
  - name: seed_dummy__post_enum_statuses
996
- description: dummy Post Status enum
1047
+ description: dummy_project Post Status enum
997
1048
  config:
998
1049
  column_types:
999
1050
  status_before_type_of_cast: int64
1000
1051
  status_key: string
1001
1052
  status_en: string
1002
1053
  status_ja: string
1003
- columns:
1004
- - name: status_before_type_of_cast
1005
- description: Status
1006
- data_tests:
1007
- - unique
1008
- - not_null
1009
- - name: status_key
1010
- description: Status(key)
1011
- data_tests:
1012
- - unique
1013
- - not_null
1014
- - name: status_en
1015
- description: Status(en)
1016
- data_tests:
1017
- - unique
1018
- - not_null
1019
- - name: status_ja
1020
- description: Status(ja)
1021
- data_tests:
1022
- - unique
1023
- - not_null
1054
+ columns:
1055
+ - name: status_before_type_of_cast
1056
+ description: Status(before_type_of_cast)
1057
+ data_type: int64
1058
+ data_tests:
1059
+ - unique
1060
+ - not_null
1061
+ - name: status_key
1062
+ description: Status(key)
1063
+ data_type: string
1064
+ data_tests:
1065
+ - unique
1066
+ - not_null
1067
+ - name: status_en
1068
+ description: Status(en)
1069
+ data_type: string
1070
+ data_tests:
1071
+ - unique
1072
+ - not_null
1073
+ - name: status_ja
1074
+ description: Status(ja)
1075
+ data_type: string
1076
+ data_tests:
1077
+ - unique
1078
+ - not_null
1024
1079
 
1025
1080
  ```
1026
1081