Skip to content

Commit 78d61e7

Browse files
fix: implement support for naming conventions
1 parent 3cc9ea0 commit 78d61e7

3 files changed

Lines changed: 89 additions & 35 deletions

File tree

CmdScale.EntityFrameworkCore.TimescaleDB.Example/CmdScale.EntityFrameworkCore.TimescaleDB.Example.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.8" />
11+
<PackageReference Include="EFCore.NamingConventions" Version="9.0.0" />
12+
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.10" />
1213
</ItemGroup>
1314

1415
<ItemGroup>

CmdScale.EntityFrameworkCore.TimescaleDB.Example/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
string? connectionString = builder.Configuration.GetConnectionString("Timescale");
1111
builder.Services.AddDbContext<TimescaleContext>(options =>
12-
options.UseNpgsql(connectionString).UseTimescaleDb());
12+
options.UseNpgsql(connectionString).UseTimescaleDb().UseSnakeCaseNamingConvention());
1313

1414
IHost host = builder.Build();
1515

CmdScale.EntityFrameworkCore.TimescaleDB/TimescaleMigrationsModelDiffer.cs

Lines changed: 86 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -152,36 +152,72 @@ private static IEnumerable<CreateHypertableOperation> GetHypertables(IRelational
152152
{
153153
// Retrieve the annotations set by the convention
154154
bool isHypertable = entityType.FindAnnotation(HypertableAnnotations.IsHypertable)?.Value as bool? ?? false;
155-
string? timeColumnName = entityType.FindAnnotation(HypertableAnnotations.HypertableTimeColumn)?.Value as string;
155+
if (!isHypertable)
156+
{
157+
continue;
158+
}
156159

157-
string chunkTimeInterval = entityType.FindAnnotation(HypertableAnnotations.ChunkTimeInterval)?.Value as string ?? DefaultValues.ChunkTimeInterval;
160+
// Get convention-aware store identifier for the table
161+
StoreObjectIdentifier storeIdentifier = StoreObjectIdentifier.Table(entityType.GetTableName()!, entityType.GetSchema());
162+
163+
string? timeColumnModelName = entityType.FindAnnotation(HypertableAnnotations.HypertableTimeColumn)?.Value as string;
164+
if (string.IsNullOrWhiteSpace(timeColumnModelName))
165+
{
166+
continue;
167+
}
168+
169+
string? timeColumnName = entityType.FindProperty(timeColumnModelName)?.GetColumnName(storeIdentifier);
170+
if (string.IsNullOrWhiteSpace(timeColumnName))
171+
{
172+
continue;
173+
}
158174

175+
159176
string? chunkSkipColumnsString = entityType.FindAnnotation(HypertableAnnotations.ChunkSkipColumns)?.Value as string;
160-
List<string>? chunkSkipColumns = chunkSkipColumnsString?.Split(',', StringSplitOptions.TrimEntries).ToList();
177+
List<string>? chunkSkipColumns = null;
178+
if (!string.IsNullOrWhiteSpace(chunkSkipColumnsString))
179+
{
180+
chunkSkipColumns = chunkSkipColumnsString.Split(',', StringSplitOptions.TrimEntries)
181+
.Select(modelPropName => entityType.FindProperty(modelPropName)?.GetColumnName(storeIdentifier))
182+
.Where(name => name != null)
183+
.ToList()!;
184+
}
161185

162-
bool enableCompression = entityType.FindAnnotation(HypertableAnnotations.EnableCompression)?.Value as bool? ?? false;
163186

164-
IAnnotation? additionalDimensionsAnnotations = entityType.FindAnnotation(HypertableAnnotations.AdditionalDimensions);
165187
List<Dimension>? additionalDimensions = null;
166-
188+
IAnnotation? additionalDimensionsAnnotations = entityType.FindAnnotation(HypertableAnnotations.AdditionalDimensions);
167189
if (additionalDimensionsAnnotations?.Value is string json && !string.IsNullOrWhiteSpace(json))
168190
{
169-
additionalDimensions = JsonSerializer.Deserialize<List<Dimension>>(json);
191+
List<Dimension>? modelDimensions = JsonSerializer.Deserialize<List<Dimension>>(json);
192+
if (modelDimensions != null)
193+
{
194+
additionalDimensions = [];
195+
foreach (Dimension dim in modelDimensions)
196+
{
197+
string? conventionalColumnName = entityType.FindProperty(dim.ColumnName)?.GetColumnName(storeIdentifier);
198+
if (conventionalColumnName != null)
199+
{
200+
Dimension newDimension = JsonSerializer.Deserialize<Dimension>(JsonSerializer.Serialize(dim))!;
201+
newDimension.ColumnName = conventionalColumnName;
202+
additionalDimensions.Add(newDimension);
203+
}
204+
}
205+
}
170206
}
171207

172-
if (isHypertable && !string.IsNullOrWhiteSpace(timeColumnName))
208+
string chunkTimeInterval = entityType.FindAnnotation(HypertableAnnotations.ChunkTimeInterval)?.Value as string ?? DefaultValues.ChunkTimeInterval;
209+
bool enableCompression = entityType.FindAnnotation(HypertableAnnotations.EnableCompression)?.Value as bool? ?? false;
210+
211+
yield return new CreateHypertableOperation
173212
{
174-
yield return new CreateHypertableOperation
175-
{
176-
TableName = entityType.GetTableName()!,
177-
Schema = entityType.GetSchema() ?? DefaultValues.DefaultSchema,
178-
TimeColumnName = timeColumnName,
179-
ChunkTimeInterval = chunkTimeInterval ?? DefaultValues.ChunkTimeInterval,
180-
EnableCompression = enableCompression,
181-
ChunkSkipColumns = chunkSkipColumns,
182-
AdditionalDimensions = additionalDimensions
183-
};
184-
}
213+
TableName = entityType.GetTableName()!,
214+
Schema = entityType.GetSchema() ?? DefaultValues.DefaultSchema,
215+
TimeColumnName = timeColumnName,
216+
ChunkTimeInterval = chunkTimeInterval ?? DefaultValues.ChunkTimeInterval,
217+
EnableCompression = enableCompression,
218+
ChunkSkipColumns = chunkSkipColumns,
219+
AdditionalDimensions = additionalDimensions
220+
};
185221
}
186222
}
187223

@@ -191,27 +227,44 @@ private static IEnumerable<AddReorderPolicyOperation> GetReorderPolicies(IRelati
191227
{
192228
yield break;
193229
}
230+
194231
foreach (IEntityType entityType in relationalModel.Model.GetEntityTypes())
195232
{
196233
// Retrieve the annotations set by the convention
197234
bool hasReorderPolicy = entityType.FindAnnotation(ReorderPolicyAnnotations.HasReorderPolicy)?.Value as bool? ?? false;
198-
string? indexName = entityType.FindAnnotation(ReorderPolicyAnnotations.IndexName)?.Value as string;
199-
DateTime? initialStart = entityType.FindAnnotation(ReorderPolicyAnnotations.InitialStart)?.Value as DateTime?;
235+
if (!hasReorderPolicy)
236+
{
237+
continue;
238+
}
239+
240+
// Get convention-aware store identifier for the table
241+
StoreObjectIdentifier storeIdentifier = StoreObjectIdentifier.Table(entityType.GetTableName()!, entityType.GetSchema());
200242

201-
if (hasReorderPolicy && !string.IsNullOrWhiteSpace(indexName) && !string.IsNullOrWhiteSpace(indexName))
243+
string? indexModelName = entityType.FindAnnotation(ReorderPolicyAnnotations.IndexName)?.Value as string;
244+
if (string.IsNullOrWhiteSpace(indexModelName))
202245
{
203-
yield return new AddReorderPolicyOperation
204-
{
205-
TableName = entityType.GetTableName()!,
206-
Schema = entityType.GetSchema() ?? DefaultValues.DefaultSchema,
207-
IndexName = indexName!,
208-
InitialStart = initialStart,
209-
ScheduleInterval = entityType.FindAnnotation(ReorderPolicyAnnotations.ScheduleInterval)?.Value as string ?? DefaultValues.ReorderPolicyScheduleInterval,
210-
MaxRuntime = entityType.FindAnnotation(ReorderPolicyAnnotations.MaxRuntime)?.Value as string ?? DefaultValues.ReorderPolicyMaxRuntime,
211-
MaxRetries = entityType.FindAnnotation(ReorderPolicyAnnotations.MaxRetries)?.Value as int? ?? DefaultValues.ReorderPolicyMaxRetries,
212-
RetryPeriod = entityType.FindAnnotation(ReorderPolicyAnnotations.RetryPeriod)?.Value as string ?? DefaultValues.ReorderPolicyRetryPeriod
213-
};
246+
continue;
247+
}
248+
249+
string? indexName = entityType.FindIndex(indexModelName)?.GetDatabaseName(storeIdentifier);
250+
if (string.IsNullOrWhiteSpace(indexName))
251+
{
252+
continue;
214253
}
254+
255+
DateTime? initialStart = entityType.FindAnnotation(ReorderPolicyAnnotations.InitialStart)?.Value as DateTime?;
256+
257+
yield return new AddReorderPolicyOperation
258+
{
259+
TableName = entityType.GetTableName()!,
260+
Schema = entityType.GetSchema() ?? DefaultValues.DefaultSchema,
261+
IndexName = indexName!,
262+
InitialStart = initialStart,
263+
ScheduleInterval = entityType.FindAnnotation(ReorderPolicyAnnotations.ScheduleInterval)?.Value as string ?? DefaultValues.ReorderPolicyScheduleInterval,
264+
MaxRuntime = entityType.FindAnnotation(ReorderPolicyAnnotations.MaxRuntime)?.Value as string ?? DefaultValues.ReorderPolicyMaxRuntime,
265+
MaxRetries = entityType.FindAnnotation(ReorderPolicyAnnotations.MaxRetries)?.Value as int? ?? DefaultValues.ReorderPolicyMaxRetries,
266+
RetryPeriod = entityType.FindAnnotation(ReorderPolicyAnnotations.RetryPeriod)?.Value as string ?? DefaultValues.ReorderPolicyRetryPeriod
267+
};
215268
}
216269
}
217270

0 commit comments

Comments
 (0)