Skip to content

Commit

Permalink
Merge pull request #16 from CirclesUBI/feature/add-views-to-migration
Browse files Browse the repository at this point in the history
Add a SqlMigrationItem and execute it during migration
  • Loading branch information
jaensen authored May 18, 2024
2 parents 3d3cb3f + 1b66f29 commit c12a874
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 24 deletions.
59 changes: 58 additions & 1 deletion Circles.Index.CirclesV2/DatabaseSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,64 @@ public class DatabaseSchema : IDatabaseSchema
new("toAddress", ValueTypes.Address, true),
new("id", ValueTypes.BigInt, true),
new("value", ValueTypes.BigInt, false)
]);
])
{
SqlMigrationItem = new SqlMigrationItem(@"
create or replace view ""V_CrcV2_Transfers"" (
""blockNumber""
, ""timestamp""
, ""transactionIndex""
, ""logIndex""
, ""batchIndex""
, ""transactionHash""
, ""operator""
, ""from""
, ""to""
, ""id""
, ""value""
) as
WITH ""allTransfers"" AS (
SELECT ""CrcV2_TransferSingle"".""blockNumber"",
""CrcV2_TransferSingle"".""timestamp"",
""CrcV2_TransferSingle"".""transactionIndex"",
""CrcV2_TransferSingle"".""logIndex"",
0 AS ""batchIndex"",
""CrcV2_TransferSingle"".""transactionHash"",
""CrcV2_TransferSingle"".operator,
""CrcV2_TransferSingle"".""from"",
""CrcV2_TransferSingle"".""to"",
""CrcV2_TransferSingle"".""id"",
""CrcV2_TransferSingle"".""value""
FROM ""CrcV2_TransferSingle""
UNION ALL
SELECT ""CrcV2_TransferBatch"".""blockNumber"",
""CrcV2_TransferBatch"".""timestamp"",
""CrcV2_TransferBatch"".""transactionIndex"",
""CrcV2_TransferBatch"".""logIndex"",
""CrcV2_TransferBatch"".""batchIndex"",
""CrcV2_TransferBatch"".""transactionHash"",
""CrcV2_TransferBatch"".""operator"",
""CrcV2_TransferBatch"".""fromAddress"",
""CrcV2_TransferBatch"".""toAddress"",
""CrcV2_TransferBatch"".""id"",
""CrcV2_TransferBatch"".""value""
FROM ""CrcV2_TransferBatch""
)
SELECT ""blockNumber"",
""timestamp"",
""transactionIndex"",
""logIndex"",
""batchIndex"",
""transactionHash"",
""operator"",
""from"",
""to"",
""id"",
""value""
FROM ""allTransfers""
ORDER BY ""blockNumber"" DESC, ""transactionIndex"" DESC, ""logIndex"" DESC, ""batchIndex"" DESC;
")
};


public IDictionary<(string Namespace, string Table), EventSchema> Tables { get; } =
Expand Down
2 changes: 2 additions & 0 deletions Circles.Index.Common/EventSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ public record EventFieldSchema(string Column, ValueTypes Type, bool IsIndexed, b

public class EventSchema(string @namespace, string table, byte[] topic, List<EventFieldSchema> columns)
{
public SqlMigrationItem? SqlMigrationItem { get; set; }

public string Namespace { get; } = @namespace;
public byte[] Topic { get; } = topic;
public string Table { get; } = table;
Expand Down
3 changes: 3 additions & 0 deletions Circles.Index.Common/SqlMigrationItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace Circles.Index.Common;

public record SqlMigrationItem(string Sql);
58 changes: 35 additions & 23 deletions Circles.Index.Postgres/PostgresDb.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,38 +122,50 @@ public async Task WriteBatch(string @namespace, string table, IEnumerable<object
private string GetDdl(EventSchema @event)
{
StringBuilder ddlSql = new StringBuilder();
ddlSql.AppendLine($"CREATE TABLE IF NOT EXISTS \"{@event.Namespace}_{@event.Table}\" (");

List<string> columnDefinitions = new List<string>();

foreach (var column in @event.Columns)
if (!@event.Namespace.StartsWith("V_"))
{
string columnType = GetSqlType(column.Type);
string columnName = column.Column;
string columnDefinition = $"\"{columnName}\" {columnType}";
ddlSql.AppendLine($"CREATE TABLE IF NOT EXISTS \"{@event.Namespace}_{@event.Table}\" (");

columnDefinitions.Add(columnDefinition);
}
List<string> columnDefinitions = new List<string>();

ddlSql.AppendLine(string.Join(",\n", columnDefinitions));
ddlSql.AppendLine(");");
ddlSql.AppendLine();
foreach (var column in @event.Columns)
{
string columnType = GetSqlType(column.Type);
string columnName = column.Column;
string columnDefinition = $"\"{columnName}\" {columnType}";

// Generate index creation statements
var indexedColumns = @event.Columns
.Where(column => column.IsIndexed);
columnDefinitions.Add(columnDefinition);
}

foreach (var column in indexedColumns)
{
if (@event.Namespace.StartsWith("V_"))
ddlSql.AppendLine(string.Join(",\n", columnDefinitions));
ddlSql.AppendLine(");");
ddlSql.AppendLine();

// Generate index creation statements
var indexedColumns = @event.Columns
.Where(column => column.IsIndexed);

foreach (var column in indexedColumns)
{
// Dirty way to skip indexes and primary keys for views
continue;
if (@event.Namespace.StartsWith("V_"))
{
// Dirty way to skip indexes and primary keys for views
continue;
}

string indexName = $"idx_{@event.Namespace}_{@event.Table}_{column.Column}";
ddlSql.AppendLine(
$"CREATE INDEX IF NOT EXISTS \"{indexName}\" ON \"{@event.Namespace}_{@event.Table}\" (\"{column.Column}\");");
}
}

string indexName = $"idx_{@event.Namespace}_{@event.Table}_{column.Column}";
ddlSql.AppendLine(
$"CREATE INDEX IF NOT EXISTS \"{indexName}\" ON \"{@event.Namespace}_{@event.Table}\" (\"{column.Column}\");");
// If the event schema has a SqlMigrationItem, execute it
if (@event.SqlMigrationItem != null)
{
ddlSql.AppendLine();
ddlSql.AppendLine(@event.SqlMigrationItem.Sql);
ddlSql.AppendLine(";"); // An additional semicolon doesn't hurt
}

return ddlSql.ToString();
Expand Down

0 comments on commit c12a874

Please sign in to comment.