floe-python 0.4.3__tar.gz → 0.4.4__tar.gz
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.
- {floe_python-0.4.3 → floe_python-0.4.4}/Cargo.lock +3 -3
- {floe_python-0.4.3 → floe_python-0.4.4}/PKG-INFO +1 -1
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/Cargo.toml +1 -1
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/iceberg/rest.rs +26 -2
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/iceberg.rs +10 -4
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/lib.rs +1 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/run/context.rs +3 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/run/entity/accepted_write.rs +3 -1
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/run/entity/incremental.rs +51 -8
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/run/entity/mod.rs +7 -1
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/run/mod.rs +14 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/state/mod.rs +94 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/integration/archive_run.rs +4 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/integration/composite_unique.rs +1 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/integration/delta_run.rs +41 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/integration/dry_run.rs +2 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/integration/fixed_width.rs +3 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/integration/iceberg_gcs_run.rs +4 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/integration/iceberg_glue_run.rs +4 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/integration/iceberg_run.rs +2 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/integration/iceberg_s3_run.rs +4 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/integration/json_selectors.rs +3 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/integration/local_run.rs +2 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/integration/path_normalization.rs +1 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/integration/run_entities_filter.rs +1 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/read/avro_input.rs +1 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/read/json_array.rs +1 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/read/json_ndjson.rs +1 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/read/orc_input.rs +1 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/read/parquet_input.rs +1 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/read/xlsx_input.rs +1 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/read/xml.rs +1 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/write/delta_merge.rs +5 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/run/check_order.rs +1 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/run/entity/accepted_output.rs +1 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/run/entity/incremental.rs +326 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/run/schema_mismatch.rs +1 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-python/Cargo.toml +2 -2
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-python/src/functions.rs +3 -1
- {floe_python-0.4.3 → floe_python-0.4.4}/pyproject.toml +1 -1
- {floe_python-0.4.3 → floe_python-0.4.4}/python/floe/_floe.pyi +1 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/Cargo.toml +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/README.md +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/README.md +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/add_entity.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/checks/cast.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/checks/mismatch.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/checks/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/checks/normalize.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/checks/not_null.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/checks/unique.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/config/catalog.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/config/location.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/config/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/config/parse.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/config/storage.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/config/template.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/config/types.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/config/validate.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/config/yaml_decode.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/errors.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/format.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/read/avro.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/read/csv.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/read/fixed_width.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/read/json.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/read/json_selector.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/read/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/read/orc.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/read/parquet.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/read/xlsx.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/read/xml.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/read/xml_selector.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/storage/core/extensions.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/storage/core/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/storage/core/paths.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/storage/core/placement.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/storage/core/planner.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/storage/core/uri.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/storage/core/validation.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/storage/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/storage/object_store.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/storage/ops/archive.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/storage/ops/inputs.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/storage/ops/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/storage/ops/output.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/storage/providers/adls.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/storage/providers/gcs.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/storage/providers/local.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/storage/providers/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/storage/providers/s3.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/storage/target.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/unique_seed/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/accepted.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/arrow_convert.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/csv.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/delta/commit_metrics.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/delta/options.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/delta/record_batch.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/delta/unity.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/delta/unity_tests.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/delta.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/iceberg/context.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/iceberg/data_files.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/iceberg/glue.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/iceberg/metadata.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/iceberg/schema.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/metrics.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/parquet.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/parts.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/sink_format.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/strategy/append.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/strategy/merge/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/strategy/merge/scd1.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/strategy/merge/scd2.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/strategy/merge/shared.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/strategy/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/io/write/strategy/overwrite.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/lineage/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/log.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/manifest/builder.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/manifest/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/manifest/model.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/manifest/reconstruct.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/profile/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/profile/parse.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/profile/types.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/profile/validate.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/report/build.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/report/entity.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/report/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/report/output.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/run/entity/pii.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/run/entity/precheck.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/run/entity/process.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/run/entity/resolve.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/run/entity/validate_split.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/run/events.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/run/file.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/run/output.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/run/perf.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/runner/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/runner/outcome.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/runtime.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/vars/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/vars/resolve.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/src/warnings.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/integration/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/integration.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/common.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/config/add_entity.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/config/adls_storage.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/config/adls_validation.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/config/catalogs.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/config/config_validation.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/config/gcs_storage.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/config/gcs_validation.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/config/lineage_validation.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/config/local_storage.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/config/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/config/parse.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/config/pii_validation.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/config/remote_base.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/config/templating.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/format.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/read/csv_nulls.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/read/json_selector.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/read/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/read/tsv.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/read/xml_selector.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/storage/adls.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/storage/adls_integration.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/storage/gcs.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/storage/inputs.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/storage/local.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/storage/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/storage/paths.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/storage/planner.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/storage/s3.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/storage/target.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/write/delta_write.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/write/iceberg_write.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/write/metrics.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/write/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/write/object_store.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/write/parquet_write.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/write/parts.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/io/write/rejected_csv.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/manifest/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/profile/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/profile/parse.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/profile/validate.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/report/accepted_output.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/report/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/report/storage.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/run/checks.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/run/entity/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/run/lineage.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/run/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/run/normalize.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/run/pii.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/run/report.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/runner/adapter.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/runner/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/state/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/vars/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit/vars/resolve.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-core/tests/unit.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-python/.gitignore +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-python/README.md +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-python/src/lib.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-python/src/observer.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-python/src/types/config.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-python/src/types/errors.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-python/src/types/mod.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-python/src/types/outcome.rs +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-python/tests/fixtures/config.yml +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-python/tests/fixtures/in/customer/customers_valid.csv +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-python/tests/fixtures/invalid_config.yml +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-python/tests/fixtures/profile.yml +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/crates/floe-python/tests/test_floe.py +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/python/floe/__init__.py +0 -0
- {floe_python-0.4.3 → floe_python-0.4.4}/python/floe/py.typed +0 -0
|
@@ -3399,7 +3399,7 @@ dependencies = [
|
|
|
3399
3399
|
|
|
3400
3400
|
[[package]]
|
|
3401
3401
|
name = "floe-cli"
|
|
3402
|
-
version = "0.4.
|
|
3402
|
+
version = "0.4.4"
|
|
3403
3403
|
dependencies = [
|
|
3404
3404
|
"assert_cmd",
|
|
3405
3405
|
"clap",
|
|
@@ -3412,7 +3412,7 @@ dependencies = [
|
|
|
3412
3412
|
|
|
3413
3413
|
[[package]]
|
|
3414
3414
|
name = "floe-core"
|
|
3415
|
-
version = "0.4.
|
|
3415
|
+
version = "0.4.4"
|
|
3416
3416
|
dependencies = [
|
|
3417
3417
|
"apache-avro 0.16.0",
|
|
3418
3418
|
"arrow",
|
|
@@ -3455,7 +3455,7 @@ dependencies = [
|
|
|
3455
3455
|
|
|
3456
3456
|
[[package]]
|
|
3457
3457
|
name = "floe-python"
|
|
3458
|
-
version = "0.4.
|
|
3458
|
+
version = "0.4.4"
|
|
3459
3459
|
dependencies = [
|
|
3460
3460
|
"floe-core",
|
|
3461
3461
|
"pyo3",
|
|
@@ -9,6 +9,7 @@ use iceberg::{Catalog, CatalogBuilder, NamespaceIdent, TableIdent};
|
|
|
9
9
|
use iceberg_catalog_rest::{
|
|
10
10
|
RestCatalogBuilder, REST_CATALOG_PROP_URI, REST_CATALOG_PROP_WAREHOUSE,
|
|
11
11
|
};
|
|
12
|
+
use iceberg_storage_opendal::OpenDalStorageFactory;
|
|
12
13
|
|
|
13
14
|
use crate::config::CatalogTypeConfig;
|
|
14
15
|
use crate::errors::RunError;
|
|
@@ -28,6 +29,7 @@ use super::{map_iceberg_err, IcebergWriteResult, PreparedIcebergWrite};
|
|
|
28
29
|
pub(crate) async fn build_rest_catalog(
|
|
29
30
|
rest_cfg: &RestIcebergCatalogConfig,
|
|
30
31
|
file_io_props: HashMap<String, String>,
|
|
32
|
+
table_location: &str,
|
|
31
33
|
) -> FloeResult<iceberg_catalog_rest::RestCatalog> {
|
|
32
34
|
let mut props: HashMap<String, String> = file_io_props;
|
|
33
35
|
|
|
@@ -63,7 +65,29 @@ pub(crate) async fn build_rest_catalog(
|
|
|
63
65
|
props.insert("scope".to_string(), scope.to_string());
|
|
64
66
|
}
|
|
65
67
|
|
|
66
|
-
|
|
68
|
+
// Prefer the concrete table location for storage factory dispatch; fall back to the
|
|
69
|
+
// warehouse field for cases where the caller only has catalog-level config (e.g. seeding).
|
|
70
|
+
let effective_uri = if !table_location.is_empty() {
|
|
71
|
+
table_location
|
|
72
|
+
} else {
|
|
73
|
+
rest_cfg.warehouse.as_deref().unwrap_or("")
|
|
74
|
+
};
|
|
75
|
+
let storage_factory: Arc<dyn StorageFactory> =
|
|
76
|
+
if effective_uri.starts_with("s3://") || effective_uri.starts_with("s3a://") {
|
|
77
|
+
let scheme = effective_uri
|
|
78
|
+
.split("://")
|
|
79
|
+
.next()
|
|
80
|
+
.unwrap_or("s3")
|
|
81
|
+
.to_string();
|
|
82
|
+
Arc::new(OpenDalStorageFactory::S3 {
|
|
83
|
+
configured_scheme: scheme,
|
|
84
|
+
customized_credential_load: None,
|
|
85
|
+
})
|
|
86
|
+
} else if effective_uri.starts_with("gs://") {
|
|
87
|
+
Arc::new(OpenDalStorageFactory::Gcs)
|
|
88
|
+
} else {
|
|
89
|
+
Arc::new(LocalFsStorageFactory)
|
|
90
|
+
};
|
|
67
91
|
|
|
68
92
|
RestCatalogBuilder::default()
|
|
69
93
|
.with_storage_factory(storage_factory)
|
|
@@ -125,7 +149,7 @@ pub(crate) async fn write_via_rest_catalog(
|
|
|
125
149
|
mode: config::WriteMode,
|
|
126
150
|
small_file_threshold_bytes: u64,
|
|
127
151
|
) -> FloeResult<IcebergWriteResult> {
|
|
128
|
-
let catalog = build_rest_catalog(rest_cfg, file_io_props).await?;
|
|
152
|
+
let catalog = build_rest_catalog(rest_cfg, file_io_props, &table_root_uri).await?;
|
|
129
153
|
|
|
130
154
|
let namespace_name = rest_cfg.namespace.clone();
|
|
131
155
|
let namespace = NamespaceIdent::new(namespace_name);
|
|
@@ -627,9 +627,14 @@ fn seed_iceberg_from_catalog(
|
|
|
627
627
|
.map_err(|err| Box::new(RunError(format!("glue iceberg seed failed: {err}"))))?;
|
|
628
628
|
seed_from_batches(tracker, batches, rename_back)
|
|
629
629
|
}
|
|
630
|
-
IcebergCatalogConfig::Rest(rest_cfg) =>
|
|
631
|
-
|
|
632
|
-
|
|
630
|
+
IcebergCatalogConfig::Rest(rest_cfg) => seed_iceberg_from_rest(
|
|
631
|
+
tracker,
|
|
632
|
+
rest_cfg,
|
|
633
|
+
file_io_props,
|
|
634
|
+
&warehouse_location,
|
|
635
|
+
scan_cols,
|
|
636
|
+
rename_back,
|
|
637
|
+
),
|
|
633
638
|
}
|
|
634
639
|
}
|
|
635
640
|
|
|
@@ -637,6 +642,7 @@ fn seed_iceberg_from_rest(
|
|
|
637
642
|
tracker: &mut check::UniqueTracker,
|
|
638
643
|
rest_cfg: &RestIcebergCatalogConfig,
|
|
639
644
|
file_io_props: HashMap<String, String>,
|
|
645
|
+
warehouse_location: &str,
|
|
640
646
|
scan_cols: &[String],
|
|
641
647
|
rename_back: &HashMap<String, String>,
|
|
642
648
|
) -> FloeResult<()> {
|
|
@@ -653,7 +659,7 @@ fn seed_iceberg_from_rest(
|
|
|
653
659
|
|
|
654
660
|
let batches = runtime
|
|
655
661
|
.block_on(async {
|
|
656
|
-
let catalog = build_rest_catalog(rest_cfg, file_io_props).await?;
|
|
662
|
+
let catalog = build_rest_catalog(rest_cfg, file_io_props, warehouse_location).await?;
|
|
657
663
|
let namespace = NamespaceIdent::new(rest_cfg.namespace.clone());
|
|
658
664
|
|
|
659
665
|
if !catalog
|
|
@@ -16,6 +16,7 @@ pub struct RunContext {
|
|
|
16
16
|
pub run_id: String,
|
|
17
17
|
pub started_at: String,
|
|
18
18
|
pub run_timer: Instant,
|
|
19
|
+
pub full_refresh: bool,
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
impl RunContext {
|
|
@@ -82,6 +83,7 @@ impl RunContext {
|
|
|
82
83
|
run_id,
|
|
83
84
|
started_at,
|
|
84
85
|
run_timer: Instant::now(),
|
|
86
|
+
full_refresh: options.full_refresh,
|
|
85
87
|
})
|
|
86
88
|
}
|
|
87
89
|
|
|
@@ -151,6 +153,7 @@ impl RunContext {
|
|
|
151
153
|
run_id,
|
|
152
154
|
started_at,
|
|
153
155
|
run_timer: Instant::now(),
|
|
156
|
+
full_refresh: options.full_refresh,
|
|
154
157
|
})
|
|
155
158
|
}
|
|
156
159
|
}
|
|
@@ -20,6 +20,7 @@ pub(super) struct AcceptedWritePhaseContext<'a> {
|
|
|
20
20
|
pub(super) accepted_target: &'a Target,
|
|
21
21
|
pub(super) temp_dir: Option<&'a Path>,
|
|
22
22
|
pub(super) write_mode: config::WriteMode,
|
|
23
|
+
pub(super) full_refresh: bool,
|
|
23
24
|
pub(super) perf_enabled: bool,
|
|
24
25
|
pub(super) phase_timings: &'a mut EntityPhaseTimings,
|
|
25
26
|
pub(super) pending_input_count: usize,
|
|
@@ -37,6 +38,7 @@ pub(super) fn run_accepted_write_phase(
|
|
|
37
38
|
accepted_target,
|
|
38
39
|
temp_dir,
|
|
39
40
|
write_mode,
|
|
41
|
+
full_refresh,
|
|
40
42
|
perf_enabled,
|
|
41
43
|
phase_timings,
|
|
42
44
|
pending_input_count,
|
|
@@ -47,7 +49,7 @@ pub(super) fn run_accepted_write_phase(
|
|
|
47
49
|
crate::io::write::strategy::merge::shared::default_schema_evolution_summary(
|
|
48
50
|
entity, write_mode,
|
|
49
51
|
);
|
|
50
|
-
if pending_input_count == 0 {
|
|
52
|
+
if pending_input_count == 0 && !(full_refresh && write_mode == config::WriteMode::Overwrite) {
|
|
51
53
|
return Ok(io::format::AcceptedWriteOutput {
|
|
52
54
|
files_written: Some(0),
|
|
53
55
|
schema_evolution: default_schema_evolution,
|
|
@@ -11,7 +11,8 @@ use crate::report::{
|
|
|
11
11
|
};
|
|
12
12
|
use crate::run::RunContext;
|
|
13
13
|
use crate::state::{
|
|
14
|
-
claim_entity_inputs, promote_claimed_entity_state,
|
|
14
|
+
claim_all_entity_inputs, claim_entity_inputs, promote_claimed_entity_state,
|
|
15
|
+
promote_full_refresh_claimed_entity_state, release_claimed_entity_state,
|
|
15
16
|
renew_claimed_entity_state, ClaimedEntityState, EntityFileState, CLAIM_TTL_SECONDS,
|
|
16
17
|
};
|
|
17
18
|
use crate::{config, warnings, FloeResult};
|
|
@@ -28,6 +29,34 @@ pub(super) fn prepare_incremental_context(
|
|
|
28
29
|
entity: &config::EntityConfig,
|
|
29
30
|
input_files: Vec<InputFile>,
|
|
30
31
|
) -> FloeResult<IncrementalContext> {
|
|
32
|
+
if context.full_refresh {
|
|
33
|
+
let pending_state = if entity.incremental_mode == IncrementalMode::File {
|
|
34
|
+
claim_all_entity_inputs(
|
|
35
|
+
&context.storage_resolver,
|
|
36
|
+
cloud,
|
|
37
|
+
entity,
|
|
38
|
+
&context.run_id,
|
|
39
|
+
input_files.clone(),
|
|
40
|
+
)?
|
|
41
|
+
.map(|claimed| {
|
|
42
|
+
PendingEntityState::new(
|
|
43
|
+
claimed,
|
|
44
|
+
context.storage_resolver.clone(),
|
|
45
|
+
entity.name.clone(),
|
|
46
|
+
context.run_id.clone(),
|
|
47
|
+
true,
|
|
48
|
+
)
|
|
49
|
+
})
|
|
50
|
+
} else {
|
|
51
|
+
None
|
|
52
|
+
};
|
|
53
|
+
return Ok(IncrementalContext {
|
|
54
|
+
pending_inputs: input_files,
|
|
55
|
+
skipped_reports: Vec::new(),
|
|
56
|
+
pending_state,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
31
60
|
if entity.incremental_mode != IncrementalMode::File {
|
|
32
61
|
return Ok(IncrementalContext {
|
|
33
62
|
pending_inputs: input_files,
|
|
@@ -104,6 +133,7 @@ pub(super) fn prepare_incremental_context(
|
|
|
104
133
|
context.storage_resolver.clone(),
|
|
105
134
|
entity.name.clone(),
|
|
106
135
|
context.run_id.clone(),
|
|
136
|
+
false,
|
|
107
137
|
)
|
|
108
138
|
}),
|
|
109
139
|
})
|
|
@@ -156,6 +186,7 @@ pub(super) struct PendingEntityState {
|
|
|
156
186
|
run_id: String,
|
|
157
187
|
heartbeat: Option<ClaimHeartbeat>,
|
|
158
188
|
finalized: bool,
|
|
189
|
+
is_full_refresh: bool,
|
|
159
190
|
}
|
|
160
191
|
|
|
161
192
|
impl PendingEntityState {
|
|
@@ -164,6 +195,7 @@ impl PendingEntityState {
|
|
|
164
195
|
resolver: StorageResolver,
|
|
165
196
|
entity_name: String,
|
|
166
197
|
run_id: String,
|
|
198
|
+
is_full_refresh: bool,
|
|
167
199
|
) -> Self {
|
|
168
200
|
let heartbeat = ClaimHeartbeat::start(
|
|
169
201
|
resolver.clone(),
|
|
@@ -178,6 +210,7 @@ impl PendingEntityState {
|
|
|
178
210
|
run_id,
|
|
179
211
|
heartbeat: Some(heartbeat),
|
|
180
212
|
finalized: false,
|
|
213
|
+
is_full_refresh,
|
|
181
214
|
}
|
|
182
215
|
}
|
|
183
216
|
|
|
@@ -188,13 +221,23 @@ impl PendingEntityState {
|
|
|
188
221
|
_entity: &config::EntityConfig,
|
|
189
222
|
) -> FloeResult<()> {
|
|
190
223
|
self.stop_heartbeat();
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
224
|
+
if self.is_full_refresh {
|
|
225
|
+
promote_full_refresh_claimed_entity_state(
|
|
226
|
+
&self.resolver,
|
|
227
|
+
cloud,
|
|
228
|
+
&self.entity_name,
|
|
229
|
+
&self.run_id,
|
|
230
|
+
&self.claimed,
|
|
231
|
+
)?;
|
|
232
|
+
} else {
|
|
233
|
+
promote_claimed_entity_state(
|
|
234
|
+
&self.resolver,
|
|
235
|
+
cloud,
|
|
236
|
+
&self.entity_name,
|
|
237
|
+
&self.run_id,
|
|
238
|
+
&self.claimed,
|
|
239
|
+
)?;
|
|
240
|
+
}
|
|
198
241
|
self.finalized = true;
|
|
199
242
|
Ok(())
|
|
200
243
|
}
|
|
@@ -87,7 +87,12 @@ pub(super) fn run_entity(
|
|
|
87
87
|
let entity_start = perf_enabled.then(Instant::now);
|
|
88
88
|
let mut phase_timings = EntityPhaseTimings::default();
|
|
89
89
|
let input = &entity.source;
|
|
90
|
-
let write_mode =
|
|
90
|
+
let write_mode =
|
|
91
|
+
if context.full_refresh && entity.sink.write_mode == crate::config::WriteMode::Append {
|
|
92
|
+
crate::config::WriteMode::Overwrite
|
|
93
|
+
} else {
|
|
94
|
+
entity.sink.write_mode
|
|
95
|
+
};
|
|
91
96
|
let input_adapter = runtime.input_adapter(input.format.as_str())?;
|
|
92
97
|
let resolved_targets = plan.resolved_targets;
|
|
93
98
|
let formatter_name = context
|
|
@@ -284,6 +289,7 @@ pub(super) fn run_entity(
|
|
|
284
289
|
accepted_target: &accepted_target,
|
|
285
290
|
temp_dir: temp_dir_path,
|
|
286
291
|
write_mode,
|
|
292
|
+
full_refresh: context.full_refresh,
|
|
287
293
|
perf_enabled,
|
|
288
294
|
phase_timings: &mut phase_timings,
|
|
289
295
|
pending_input_count,
|
|
@@ -175,6 +175,20 @@ fn run_from_context(
|
|
|
175
175
|
let observer = default_observer();
|
|
176
176
|
let perf_enabled = perf::phase_timing_enabled();
|
|
177
177
|
let selected_entities = select_entities(&context, &options);
|
|
178
|
+
if options.full_refresh {
|
|
179
|
+
for entity in &selected_entities {
|
|
180
|
+
if matches!(
|
|
181
|
+
entity.sink.write_mode,
|
|
182
|
+
config::WriteMode::MergeScd1 | config::WriteMode::MergeScd2
|
|
183
|
+
) {
|
|
184
|
+
return Err(Box::new(ConfigError(format!(
|
|
185
|
+
"entity '{}': --full-refresh is not supported with write_mode '{}'",
|
|
186
|
+
entity.name,
|
|
187
|
+
entity.sink.write_mode.as_str()
|
|
188
|
+
))));
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
178
192
|
let resolution_mode = if options.dry_run {
|
|
179
193
|
io::storage::inputs::ResolveInputsMode::ListOnly
|
|
180
194
|
} else {
|
|
@@ -241,6 +241,68 @@ pub fn claim_entity_inputs(
|
|
|
241
241
|
))))
|
|
242
242
|
}
|
|
243
243
|
|
|
244
|
+
/// Full-refresh variant of `claim_entity_inputs`.
|
|
245
|
+
///
|
|
246
|
+
/// Loads existing state to get the current CAS version, then writes a blank
|
|
247
|
+
/// `EntityState` containing fresh claims for ALL `input_files` — discarding
|
|
248
|
+
/// the historical `files` and `claims` maps. On successful commit the state
|
|
249
|
+
/// file will contain only the files processed in this run.
|
|
250
|
+
///
|
|
251
|
+
/// Returns `None` when `input_files` is empty (nothing to claim).
|
|
252
|
+
pub fn claim_all_entity_inputs(
|
|
253
|
+
resolver: &StorageResolver,
|
|
254
|
+
cloud: &mut CloudClient,
|
|
255
|
+
entity: &EntityConfig,
|
|
256
|
+
run_id: &str,
|
|
257
|
+
input_files: Vec<crate::io::format::InputFile>,
|
|
258
|
+
) -> FloeResult<Option<ClaimedEntityState>> {
|
|
259
|
+
let acquired_at = now_rfc3339();
|
|
260
|
+
let expires_at = rfc3339_after_seconds(CLAIM_TTL_SECONDS);
|
|
261
|
+
|
|
262
|
+
for _ in 0..STATE_CAS_RETRIES {
|
|
263
|
+
// Read only to obtain the current CAS version; content is discarded.
|
|
264
|
+
let loaded = load_entity_state(resolver, cloud, entity)?;
|
|
265
|
+
|
|
266
|
+
let mut fresh_state = EntityState::new(&entity.name);
|
|
267
|
+
fresh_state.files = loaded.state.files.clone();
|
|
268
|
+
fresh_state.updated_at = Some(acquired_at.clone());
|
|
269
|
+
for input_file in &input_files {
|
|
270
|
+
fresh_state.claims.insert(
|
|
271
|
+
input_file.source_uri.clone(),
|
|
272
|
+
EntityFileClaim {
|
|
273
|
+
run_id: run_id.to_string(),
|
|
274
|
+
acquired_at: acquired_at.clone(),
|
|
275
|
+
expires_at: expires_at.clone(),
|
|
276
|
+
size: input_file.source_size,
|
|
277
|
+
mtime: input_file.source_mtime.clone(),
|
|
278
|
+
},
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
let fresh_loaded = LoadedEntityState {
|
|
283
|
+
target: loaded.target,
|
|
284
|
+
state: fresh_state,
|
|
285
|
+
version: loaded.version,
|
|
286
|
+
existed: loaded.existed,
|
|
287
|
+
};
|
|
288
|
+
match persist_loaded_state(cloud, resolver, &fresh_loaded)? {
|
|
289
|
+
Some(version) => {
|
|
290
|
+
return Ok(Some(ClaimedEntityState {
|
|
291
|
+
target: fresh_loaded.target,
|
|
292
|
+
state: fresh_loaded.state,
|
|
293
|
+
version,
|
|
294
|
+
}));
|
|
295
|
+
}
|
|
296
|
+
None => continue,
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
Err(Box::new(ConfigError(format!(
|
|
301
|
+
"entity.name={} full-refresh state write conflicted after {STATE_CAS_RETRIES} retries",
|
|
302
|
+
entity.name
|
|
303
|
+
))))
|
|
304
|
+
}
|
|
305
|
+
|
|
244
306
|
pub fn promote_claimed_entity_state(
|
|
245
307
|
resolver: &StorageResolver,
|
|
246
308
|
cloud: &mut CloudClient,
|
|
@@ -272,6 +334,38 @@ pub fn promote_claimed_entity_state(
|
|
|
272
334
|
})
|
|
273
335
|
}
|
|
274
336
|
|
|
337
|
+
pub fn promote_full_refresh_claimed_entity_state(
|
|
338
|
+
resolver: &StorageResolver,
|
|
339
|
+
cloud: &mut CloudClient,
|
|
340
|
+
entity_name: &str,
|
|
341
|
+
run_id: &str,
|
|
342
|
+
claimed: &ClaimedEntityState,
|
|
343
|
+
) -> FloeResult<()> {
|
|
344
|
+
mutate_claimed_state(resolver, cloud, entity_name, claimed, |state, our_uris| {
|
|
345
|
+
let processed_at = now_rfc3339();
|
|
346
|
+
let claimed_files: Vec<String> = state
|
|
347
|
+
.claims
|
|
348
|
+
.iter()
|
|
349
|
+
.filter(|(uri, claim)| claim.run_id == run_id && our_uris.contains(*uri))
|
|
350
|
+
.map(|(uri, _)| uri.clone())
|
|
351
|
+
.collect();
|
|
352
|
+
state.files.clear();
|
|
353
|
+
for source_uri in claimed_files {
|
|
354
|
+
if let Some(claim) = state.claims.remove(&source_uri) {
|
|
355
|
+
state.files.insert(
|
|
356
|
+
source_uri,
|
|
357
|
+
EntityFileState {
|
|
358
|
+
processed_at: processed_at.clone(),
|
|
359
|
+
size: claim.size,
|
|
360
|
+
mtime: claim.mtime,
|
|
361
|
+
},
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
state.updated_at = Some(processed_at);
|
|
366
|
+
})
|
|
367
|
+
}
|
|
368
|
+
|
|
275
369
|
pub fn release_claimed_entity_state(
|
|
276
370
|
resolver: &StorageResolver,
|
|
277
371
|
cloud: &mut CloudClient,
|
|
@@ -105,6 +105,7 @@ fn archive_moves_only_processed_input_not_local_siblings() {
|
|
|
105
105
|
run_id: Some("archive-sibling-it".to_string()),
|
|
106
106
|
entities: Vec::new(),
|
|
107
107
|
dry_run: false,
|
|
108
|
+
full_refresh: false,
|
|
108
109
|
},
|
|
109
110
|
)
|
|
110
111
|
.expect("run config");
|
|
@@ -163,6 +164,7 @@ fn archive_repeated_runs_do_not_overwrite_same_source_filename() {
|
|
|
163
164
|
run_id: Some("archive-run-1".to_string()),
|
|
164
165
|
entities: Vec::new(),
|
|
165
166
|
dry_run: false,
|
|
167
|
+
full_refresh: false,
|
|
166
168
|
},
|
|
167
169
|
)
|
|
168
170
|
.expect("first run");
|
|
@@ -175,6 +177,7 @@ fn archive_repeated_runs_do_not_overwrite_same_source_filename() {
|
|
|
175
177
|
run_id: Some("archive-run-2".to_string()),
|
|
176
178
|
entities: Vec::new(),
|
|
177
179
|
dry_run: false,
|
|
180
|
+
full_refresh: false,
|
|
178
181
|
},
|
|
179
182
|
)
|
|
180
183
|
.expect("second run");
|
|
@@ -227,6 +230,7 @@ fn legacy_archive_config_still_archives_inputs() {
|
|
|
227
230
|
run_id: Some("archive-legacy-compat".to_string()),
|
|
228
231
|
entities: Vec::new(),
|
|
229
232
|
dry_run: false,
|
|
233
|
+
full_refresh: false,
|
|
230
234
|
},
|
|
231
235
|
)
|
|
232
236
|
.expect("run config");
|