diff --git a/.claude/reference/architecture.md b/.claude/reference/architecture.md index 303bd6e..65619f7 100644 --- a/.claude/reference/architecture.md +++ b/.claude/reference/architecture.md @@ -129,7 +129,6 @@ ChunkTimeInterval = "7 days" // ChunkTimeIntervalLong = 604_800_000_000L ReorderPolicyScheduleInterval = "1 day" ReorderPolicyMaxRetries = -1 // indefinite ReorderPolicyMaxRuntime = "00:00:00" // no limit -ReorderPolicyRetryPeriod = "00:05:00" ``` ## Design Library Structure diff --git a/src/Eftdb.Design/Scaffolding/ReorderPolicyAnnotationApplier.cs b/src/Eftdb.Design/Scaffolding/ReorderPolicyAnnotationApplier.cs index d903e61..f13f9a8 100644 --- a/src/Eftdb.Design/Scaffolding/ReorderPolicyAnnotationApplier.cs +++ b/src/Eftdb.Design/Scaffolding/ReorderPolicyAnnotationApplier.cs @@ -40,7 +40,7 @@ public void ApplyAnnotations(DatabaseTable table, object featureInfo) table[ReorderPolicyAnnotations.MaxRetries] = policyInfo.MaxRetries; } - if (policyInfo.RetryPeriod != DefaultValues.ReorderPolicyRetryPeriod) + if (policyInfo.RetryPeriod != DefaultValues.ReorderPolicyScheduleInterval) { table[ReorderPolicyAnnotations.RetryPeriod] = policyInfo.RetryPeriod; } diff --git a/src/Eftdb/DefaultValues.cs b/src/Eftdb/DefaultValues.cs index 74a6255..b0202d1 100644 --- a/src/Eftdb/DefaultValues.cs +++ b/src/Eftdb/DefaultValues.cs @@ -11,6 +11,5 @@ public static class DefaultValues public const string ReorderPolicyScheduleInterval = "1 day"; public const int ReorderPolicyMaxRetries = -1; public const string ReorderPolicyMaxRuntime = "00:00:00"; - public const string ReorderPolicyRetryPeriod = "00:05:00"; } } diff --git a/src/Eftdb/Generators/HypertableOperationGenerator.cs b/src/Eftdb/Generators/HypertableOperationGenerator.cs index 44981d1..cd2ac0f 100644 --- a/src/Eftdb/Generators/HypertableOperationGenerator.cs +++ b/src/Eftdb/Generators/HypertableOperationGenerator.cs @@ -309,16 +309,16 @@ private static string WrapCommunityFeatures(List sqlStatements) /// Escapes existing double quotes. /// Example: TenantId -> "TenantId" /// - private static string QuoteIdentifier(string identifier) + private string QuoteIdentifier(string identifier) { - return $"\"{identifier.Replace("\"", "\"\"")}\""; + return $"{quoteString}{identifier.Replace("\"", "\"\"")}{quoteString}"; } /// /// Quotes the column name within an ORDER BY clause while preserving direction/nulls. /// Example: Timestamp DESC -> "Timestamp" DESC /// - private static string QuoteOrderByList(IEnumerable orderByClauses) + private string QuoteOrderByList(IEnumerable orderByClauses) { return string.Join(", ", orderByClauses.Select(clause => { diff --git a/src/Eftdb/Generators/ReorderPolicyOperationGenerator.cs b/src/Eftdb/Generators/ReorderPolicyOperationGenerator.cs index 294ec4f..8306a47 100644 --- a/src/Eftdb/Generators/ReorderPolicyOperationGenerator.cs +++ b/src/Eftdb/Generators/ReorderPolicyOperationGenerator.cs @@ -90,18 +90,17 @@ public List Generate(DropReorderPolicyOperation operation) private static List BuildAlterJobClauses(AddReorderPolicyOperation operation) { List clauses = []; - // Assuming DefaultValues is accessible or static constants - // Note: You may need to adjust the default value comparisons if DefaultValues isn't available - if (!string.IsNullOrWhiteSpace(operation.ScheduleInterval)) // && operation.ScheduleInterval != DefaultValues.ReorderPolicyScheduleInterval) + + if (!string.IsNullOrWhiteSpace(operation.ScheduleInterval)) clauses.Add($"schedule_interval => INTERVAL '{operation.ScheduleInterval}'"); - if (!string.IsNullOrWhiteSpace(operation.MaxRuntime)) // && operation.MaxRuntime != DefaultValues.ReorderPolicyMaxRuntime) + if (!string.IsNullOrWhiteSpace(operation.MaxRuntime)) clauses.Add($"max_runtime => INTERVAL '{operation.MaxRuntime}'"); - if (operation.MaxRetries != null) // && operation.MaxRetries != DefaultValues.ReorderPolicyMaxRetries) + if (operation.MaxRetries != null) clauses.Add($"max_retries => {operation.MaxRetries}"); - if (!string.IsNullOrWhiteSpace(operation.RetryPeriod)) // && operation.RetryPeriod != DefaultValues.ReorderPolicyRetryPeriod) + if (!string.IsNullOrWhiteSpace(operation.RetryPeriod)) clauses.Add($"retry_period => INTERVAL '{operation.RetryPeriod}'"); return clauses; diff --git a/src/Eftdb/Internals/Features/ReorderPolicies/ReorderPolicyModelExtractor.cs b/src/Eftdb/Internals/Features/ReorderPolicies/ReorderPolicyModelExtractor.cs index 588cefe..d7d5abe 100644 --- a/src/Eftdb/Internals/Features/ReorderPolicies/ReorderPolicyModelExtractor.cs +++ b/src/Eftdb/Internals/Features/ReorderPolicies/ReorderPolicyModelExtractor.cs @@ -40,7 +40,7 @@ public static IEnumerable GetReorderPolicies(IRelatio ScheduleInterval = entityType.FindAnnotation(ReorderPolicyAnnotations.ScheduleInterval)?.Value as string ?? DefaultValues.ReorderPolicyScheduleInterval, MaxRuntime = entityType.FindAnnotation(ReorderPolicyAnnotations.MaxRuntime)?.Value as string ?? DefaultValues.ReorderPolicyMaxRuntime, MaxRetries = entityType.FindAnnotation(ReorderPolicyAnnotations.MaxRetries)?.Value as int? ?? DefaultValues.ReorderPolicyMaxRetries, - RetryPeriod = entityType.FindAnnotation(ReorderPolicyAnnotations.RetryPeriod)?.Value as string ?? DefaultValues.ReorderPolicyRetryPeriod + RetryPeriod = entityType.FindAnnotation(ReorderPolicyAnnotations.RetryPeriod)?.Value as string ?? DefaultValues.ReorderPolicyScheduleInterval }; } } diff --git a/tests/Eftdb.Tests/Extractors/ReorderPolicyModelExtractorTests.cs b/tests/Eftdb.Tests/Extractors/ReorderPolicyModelExtractorTests.cs index 8659bf3..c6c5215 100644 --- a/tests/Eftdb.Tests/Extractors/ReorderPolicyModelExtractorTests.cs +++ b/tests/Eftdb.Tests/Extractors/ReorderPolicyModelExtractorTests.cs @@ -65,7 +65,7 @@ public void Should_Extract_Minimal_ReorderPolicy() Assert.Equal(DefaultValues.ReorderPolicyScheduleInterval, operation.ScheduleInterval); Assert.Equal(DefaultValues.ReorderPolicyMaxRuntime, operation.MaxRuntime); Assert.Equal(DefaultValues.ReorderPolicyMaxRetries, operation.MaxRetries); - Assert.Equal(DefaultValues.ReorderPolicyRetryPeriod, operation.RetryPeriod); + Assert.Equal(DefaultValues.ReorderPolicyScheduleInterval, operation.RetryPeriod); } #endregion @@ -555,7 +555,7 @@ public void Should_Use_Default_RetryPeriod_When_Not_Specified() List operations = [.. ReorderPolicyModelExtractor.GetReorderPolicies(relationalModel)]; Assert.Single(operations); - Assert.Equal(DefaultValues.ReorderPolicyRetryPeriod, operations[0].RetryPeriod); + Assert.Equal(DefaultValues.ReorderPolicyScheduleInterval, operations[0].RetryPeriod); } #endregion diff --git a/tests/Eftdb.Tests/Generators/HypertableOperationGeneratorComprehensiveTests.cs b/tests/Eftdb.Tests/Generators/HypertableOperationGeneratorComprehensiveTests.cs index a98e0d9..e17633e 100644 --- a/tests/Eftdb.Tests/Generators/HypertableOperationGeneratorComprehensiveTests.cs +++ b/tests/Eftdb.Tests/Generators/HypertableOperationGeneratorComprehensiveTests.cs @@ -383,7 +383,7 @@ public void DesignTime_Create_WithCompressionSegmentBy_GeneratesCorrectCode() license := current_setting('timescaledb.license', true); IF license IS NULL OR license != 'apache' THEN - EXECUTE 'ALTER TABLE """"public"""".""""segmented_data"""" SET (timescaledb.compress = true, timescaledb.compress_segmentby = ''""tenant_id"", ""device_id""'')'; + EXECUTE 'ALTER TABLE """"public"""".""""segmented_data"""" SET (timescaledb.compress = true, timescaledb.compress_segmentby = ''""""tenant_id"""", """"device_id""""'')'; ELSE RAISE WARNING 'Skipping Community Edition features (compression, chunk skipping) - not available in Apache Edition'; END IF; @@ -418,7 +418,7 @@ public void DesignTime_Create_WithCompressionOrderBy_GeneratesCorrectCode() license := current_setting('timescaledb.license', true); IF license IS NULL OR license != 'apache' THEN - EXECUTE 'ALTER TABLE """"public"""".""""ordered_data"""" SET (timescaledb.compress = true, timescaledb.compress_orderby = ''""time"" DESC, ""value"" ASC NULLS LAST'')'; + EXECUTE 'ALTER TABLE """"public"""".""""ordered_data"""" SET (timescaledb.compress = true, timescaledb.compress_orderby = ''""""time"""" DESC, """"value"""" ASC NULLS LAST'')'; ELSE RAISE WARNING 'Skipping Community Edition features (compression, chunk skipping) - not available in Apache Edition'; END IF; @@ -862,7 +862,7 @@ public void DesignTime_Alter_AddingCompressionSegmentBy_GeneratesCorrectCode() license := current_setting('timescaledb.license', true); IF license IS NULL OR license != 'apache' THEN - EXECUTE 'ALTER TABLE """"public"""".""""metrics"""" SET (timescaledb.compress = true, timescaledb.compress_segmentby = ''""device_id""'')'; + EXECUTE 'ALTER TABLE """"public"""".""""metrics"""" SET (timescaledb.compress = true, timescaledb.compress_segmentby = ''""""device_id""""'')'; ELSE RAISE WARNING 'Skipping Community Edition features (compression, chunk skipping) - not available in Apache Edition'; END IF; diff --git a/tests/Eftdb.Tests/Generators/HypertableOperationGeneratorTests.cs b/tests/Eftdb.Tests/Generators/HypertableOperationGeneratorTests.cs index cf7ce89..07d30e7 100644 --- a/tests/Eftdb.Tests/Generators/HypertableOperationGeneratorTests.cs +++ b/tests/Eftdb.Tests/Generators/HypertableOperationGeneratorTests.cs @@ -187,7 +187,7 @@ public void Generate_Create_With_Compression_Segment_And_OrderBy_Generates_Corre license := current_setting('timescaledb.license', true); IF license IS NULL OR license != 'apache' THEN - EXECUTE 'ALTER TABLE """"public"""".""""CompressedTable"""" SET (timescaledb.compress = true, timescaledb.compress_segmentby = ''""TenantId"", ""DeviceId""'', timescaledb.compress_orderby = ''""Timestamp"" DESC, ""Value"" ASC NULLS LAST'')'; + EXECUTE 'ALTER TABLE """"public"""".""""CompressedTable"""" SET (timescaledb.compress = true, timescaledb.compress_segmentby = ''""""TenantId"""", """"DeviceId""""'', timescaledb.compress_orderby = ''""""Timestamp"""" DESC, """"Value"""" ASC NULLS LAST'')'; ELSE RAISE WARNING 'Skipping Community Edition features (compression, chunk skipping) - not available in Apache Edition'; END IF; @@ -222,7 +222,7 @@ public void Generate_Alter_Adding_Compression_SegmentBy_Generates_Correct_Sql() license := current_setting('timescaledb.license', true); IF license IS NULL OR license != 'apache' THEN - EXECUTE 'ALTER TABLE """"public"""".""""Metrics"""" SET (timescaledb.compress = true, timescaledb.compress_segmentby = ''""DeviceId""'')'; + EXECUTE 'ALTER TABLE """"public"""".""""Metrics"""" SET (timescaledb.compress = true, timescaledb.compress_segmentby = ''""""DeviceId""""'')'; ELSE RAISE WARNING 'Skipping Community Edition features (compression, chunk skipping) - not available in Apache Edition'; END IF; @@ -257,7 +257,7 @@ public void Generate_Alter_Modifying_Compression_OrderBy_Generates_Correct_Sql() license := current_setting('timescaledb.license', true); IF license IS NULL OR license != 'apache' THEN - EXECUTE 'ALTER TABLE """"public"""".""""Metrics"""" SET (timescaledb.compress_orderby = ''""Timestamp"" DESC'')'; + EXECUTE 'ALTER TABLE """"public"""".""""Metrics"""" SET (timescaledb.compress_orderby = ''""""Timestamp"""" DESC'')'; ELSE RAISE WARNING 'Skipping Community Edition features (compression, chunk skipping) - not available in Apache Edition'; END IF; diff --git a/tests/Eftdb.Tests/Integration/HypertableIntegrationTests.cs b/tests/Eftdb.Tests/Integration/HypertableIntegrationTests.cs index da88670..5e8a3cd 100644 --- a/tests/Eftdb.Tests/Integration/HypertableIntegrationTests.cs +++ b/tests/Eftdb.Tests/Integration/HypertableIntegrationTests.cs @@ -980,7 +980,7 @@ public async Task Should_Handle_LargeDataset() for (int i = 0; i < 100; i++) { DateTime timestamp = baseTime.AddMinutes(i); - valueRows.Add($"('{timestamp:yyyy-MM-dd HH:mm:ss}+00', {i % 10}, {15.0 + i * 0.1})"); + valueRows.Add(FormattableString.Invariant($"('{timestamp:yyyy-MM-dd HH:mm:ss}+00', {i % 10}, {15.0 + i * 0.1})")); } string sql = $@"INSERT INTO ""PerformanceTest"" (""Timestamp"", ""SensorId"", ""Value"") diff --git a/tests/Eftdb.Tests/Scaffolding/ReorderPolicyAnnotationApplierTests.cs b/tests/Eftdb.Tests/Scaffolding/ReorderPolicyAnnotationApplierTests.cs index c86ba75..851fc12 100644 --- a/tests/Eftdb.Tests/Scaffolding/ReorderPolicyAnnotationApplierTests.cs +++ b/tests/Eftdb.Tests/Scaffolding/ReorderPolicyAnnotationApplierTests.cs @@ -27,7 +27,7 @@ public void Should_Apply_Minimal_ReorderPolicy_Annotations() ScheduleInterval: DefaultValues.ReorderPolicyScheduleInterval, MaxRuntime: DefaultValues.ReorderPolicyMaxRuntime, MaxRetries: DefaultValues.ReorderPolicyMaxRetries, - RetryPeriod: DefaultValues.ReorderPolicyRetryPeriod + RetryPeriod: DefaultValues.ReorderPolicyScheduleInterval ); // Act @@ -60,7 +60,7 @@ public void Should_Apply_HasReorderPolicy_Always_True() ScheduleInterval: DefaultValues.ReorderPolicyScheduleInterval, MaxRuntime: DefaultValues.ReorderPolicyMaxRuntime, MaxRetries: DefaultValues.ReorderPolicyMaxRetries, - RetryPeriod: DefaultValues.ReorderPolicyRetryPeriod + RetryPeriod: DefaultValues.ReorderPolicyScheduleInterval ); // Act @@ -88,7 +88,7 @@ public void Should_Apply_IndexName_Annotation() ScheduleInterval: DefaultValues.ReorderPolicyScheduleInterval, MaxRuntime: DefaultValues.ReorderPolicyMaxRuntime, MaxRetries: DefaultValues.ReorderPolicyMaxRetries, - RetryPeriod: DefaultValues.ReorderPolicyRetryPeriod + RetryPeriod: DefaultValues.ReorderPolicyScheduleInterval ); // Act @@ -114,7 +114,7 @@ public void Should_Apply_InitialStart_Annotation() ScheduleInterval: DefaultValues.ReorderPolicyScheduleInterval, MaxRuntime: DefaultValues.ReorderPolicyMaxRuntime, MaxRetries: DefaultValues.ReorderPolicyMaxRetries, - RetryPeriod: DefaultValues.ReorderPolicyRetryPeriod + RetryPeriod: DefaultValues.ReorderPolicyScheduleInterval ); // Act @@ -139,7 +139,7 @@ public void Should_Not_Apply_InitialStart_When_Null() ScheduleInterval: DefaultValues.ReorderPolicyScheduleInterval, MaxRuntime: DefaultValues.ReorderPolicyMaxRuntime, MaxRetries: DefaultValues.ReorderPolicyMaxRetries, - RetryPeriod: DefaultValues.ReorderPolicyRetryPeriod + RetryPeriod: DefaultValues.ReorderPolicyScheduleInterval ); // Act @@ -164,7 +164,7 @@ public void Should_Apply_ScheduleInterval_When_Different_From_Default() ScheduleInterval: "7 days", MaxRuntime: DefaultValues.ReorderPolicyMaxRuntime, MaxRetries: DefaultValues.ReorderPolicyMaxRetries, - RetryPeriod: DefaultValues.ReorderPolicyRetryPeriod + RetryPeriod: DefaultValues.ReorderPolicyScheduleInterval ); // Act @@ -189,7 +189,7 @@ public void Should_Not_Apply_ScheduleInterval_When_Default() ScheduleInterval: DefaultValues.ReorderPolicyScheduleInterval, // "1 day" MaxRuntime: DefaultValues.ReorderPolicyMaxRuntime, MaxRetries: DefaultValues.ReorderPolicyMaxRetries, - RetryPeriod: DefaultValues.ReorderPolicyRetryPeriod + RetryPeriod: DefaultValues.ReorderPolicyScheduleInterval ); // Act @@ -219,7 +219,7 @@ public void Should_Apply_Various_ScheduleInterval_Formats(string scheduleInterva ScheduleInterval: scheduleInterval, MaxRuntime: DefaultValues.ReorderPolicyMaxRuntime, MaxRetries: DefaultValues.ReorderPolicyMaxRetries, - RetryPeriod: DefaultValues.ReorderPolicyRetryPeriod + RetryPeriod: DefaultValues.ReorderPolicyScheduleInterval ); // Act @@ -244,7 +244,7 @@ public void Should_Apply_MaxRuntime_When_Different_From_Default() ScheduleInterval: DefaultValues.ReorderPolicyScheduleInterval, MaxRuntime: "01:00:00", MaxRetries: DefaultValues.ReorderPolicyMaxRetries, - RetryPeriod: DefaultValues.ReorderPolicyRetryPeriod + RetryPeriod: DefaultValues.ReorderPolicyScheduleInterval ); // Act @@ -269,7 +269,7 @@ public void Should_Not_Apply_MaxRuntime_When_Default() ScheduleInterval: DefaultValues.ReorderPolicyScheduleInterval, MaxRuntime: DefaultValues.ReorderPolicyMaxRuntime, // "00:00:00" MaxRetries: DefaultValues.ReorderPolicyMaxRetries, - RetryPeriod: DefaultValues.ReorderPolicyRetryPeriod + RetryPeriod: DefaultValues.ReorderPolicyScheduleInterval ); // Act @@ -294,7 +294,7 @@ public void Should_Apply_MaxRetries_When_Different_From_Default() ScheduleInterval: DefaultValues.ReorderPolicyScheduleInterval, MaxRuntime: DefaultValues.ReorderPolicyMaxRuntime, MaxRetries: 5, - RetryPeriod: DefaultValues.ReorderPolicyRetryPeriod + RetryPeriod: DefaultValues.ReorderPolicyScheduleInterval ); // Act @@ -319,7 +319,7 @@ public void Should_Not_Apply_MaxRetries_When_Default() ScheduleInterval: DefaultValues.ReorderPolicyScheduleInterval, MaxRuntime: DefaultValues.ReorderPolicyMaxRuntime, MaxRetries: DefaultValues.ReorderPolicyMaxRetries, // -1 - RetryPeriod: DefaultValues.ReorderPolicyRetryPeriod + RetryPeriod: DefaultValues.ReorderPolicyScheduleInterval ); // Act @@ -344,7 +344,7 @@ public void Should_Apply_MaxRetries_Zero() ScheduleInterval: DefaultValues.ReorderPolicyScheduleInterval, MaxRuntime: DefaultValues.ReorderPolicyMaxRuntime, MaxRetries: 0, - RetryPeriod: DefaultValues.ReorderPolicyRetryPeriod + RetryPeriod: DefaultValues.ReorderPolicyScheduleInterval ); // Act @@ -373,7 +373,7 @@ public void Should_Apply_MaxRetries_Positive_Values(int maxRetries) ScheduleInterval: DefaultValues.ReorderPolicyScheduleInterval, MaxRuntime: DefaultValues.ReorderPolicyMaxRuntime, MaxRetries: maxRetries, - RetryPeriod: DefaultValues.ReorderPolicyRetryPeriod + RetryPeriod: DefaultValues.ReorderPolicyScheduleInterval ); // Act @@ -423,7 +423,7 @@ public void Should_Not_Apply_RetryPeriod_When_Default() ScheduleInterval: DefaultValues.ReorderPolicyScheduleInterval, MaxRuntime: DefaultValues.ReorderPolicyMaxRuntime, MaxRetries: DefaultValues.ReorderPolicyMaxRetries, - RetryPeriod: DefaultValues.ReorderPolicyRetryPeriod // "00:05:00" + RetryPeriod: DefaultValues.ReorderPolicyScheduleInterval // "00:05:00" ); // Act @@ -598,7 +598,7 @@ public void Should_Preserve_Existing_Table_Properties() ScheduleInterval: DefaultValues.ReorderPolicyScheduleInterval, MaxRuntime: DefaultValues.ReorderPolicyMaxRuntime, MaxRetries: DefaultValues.ReorderPolicyMaxRetries, - RetryPeriod: DefaultValues.ReorderPolicyRetryPeriod + RetryPeriod: DefaultValues.ReorderPolicyScheduleInterval ); // Act @@ -629,7 +629,7 @@ public void Should_Handle_IndexName_With_Schema_Prefix() ScheduleInterval: DefaultValues.ReorderPolicyScheduleInterval, MaxRuntime: DefaultValues.ReorderPolicyMaxRuntime, MaxRetries: DefaultValues.ReorderPolicyMaxRetries, - RetryPeriod: DefaultValues.ReorderPolicyRetryPeriod + RetryPeriod: DefaultValues.ReorderPolicyScheduleInterval ); // Act @@ -655,7 +655,7 @@ public void Should_Handle_Various_InitialStart_DateTimes(DateTime initialStart) ScheduleInterval: DefaultValues.ReorderPolicyScheduleInterval, MaxRuntime: DefaultValues.ReorderPolicyMaxRuntime, MaxRetries: DefaultValues.ReorderPolicyMaxRetries, - RetryPeriod: DefaultValues.ReorderPolicyRetryPeriod + RetryPeriod: DefaultValues.ReorderPolicyScheduleInterval ); // Act