Skip to content

Commit 4e36773

Browse files
committed
Added support for database index migrations.
1 parent 25b1d8b commit 4e36773

12 files changed

+627
-559
lines changed

Migrator-vs2008.sln

Lines changed: 0 additions & 81 deletions
This file was deleted.

src/Migrator.Framework/ITransformationProvider.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,5 +503,28 @@ void GenerateForeignKey(string foreignTable, string foreignColumn, string primar
503503
/// <param name="guid"></param>
504504
/// <returns></returns>
505505
string Encode(Guid guid);
506+
507+
/// <summary>
508+
/// Add a multi-column index to a table
509+
/// </summary>
510+
/// <param name="name">The name of the index to add.</param>
511+
/// <param name="table">The name of the table that will get the index.</param>
512+
/// <param name="columns">The name of the column or columns that are in the index.</param>
513+
void AddIndex(string name, string table, params string[] columns);
514+
515+
/// <summary>
516+
/// Check to see if an index exists
517+
/// </summary>
518+
/// <param name="name">The name of the index</param>
519+
/// <param name="table">The table that the index lives on.</param>
520+
/// <returns></returns>
521+
bool IndexExists(string table, string name);
522+
523+
/// <summary>
524+
/// Remove an existing index
525+
/// </summary>
526+
/// <param name="table">The table that contains the index.</param>
527+
/// <param name="name">The name of the index to remove</param>
528+
void RemoveIndex(string table, string name);
506529
}
507530
}

src/Migrator.Providers/Impl/Mysql/MySqlTransformationProvider.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,5 +160,18 @@ public override void RenameColumn(string tableName, string oldColumnName, string
160160
}
161161
}
162162
}
163+
164+
public override void RemoveIndex(string table, string name)
165+
{
166+
if (IndexExists(table, name))
167+
{
168+
ExecuteNonQuery(String.Format("DROP INDEX {1} ON {0}", table, _dialect.Quote(name)));
169+
}
170+
}
171+
172+
public override bool IndexExists(string table, string name)
173+
{
174+
return ConstraintExists(table, name);
175+
}
163176
}
164177
}

src/Migrator.Providers/Impl/Oracle/OracleTransformationProvider.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,5 +324,16 @@ public override string Encode(Guid guid)
324324
foreach (byte b in bytes) hex.AppendFormat("{0:X2}", b);
325325
return hex.ToString();
326326
}
327+
328+
public override bool IndexExists(string table, string name)
329+
{
330+
string sql =
331+
string.Format(
332+
"SELECT COUNT(index_name) FROM user_indexes WHERE lower(index_name) = '{0}' AND lower(table_name) = '{1}'",
333+
name.ToLower(), table.ToLower());
334+
Logger.Log(sql);
335+
object scalar = ExecuteScalar(sql);
336+
return Convert.ToInt32(scalar) == 1;
337+
}
327338
}
328339
}

src/Migrator.Providers/Impl/PostgreSQL/PostgreSQLTransformationProvider.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,5 +132,14 @@ public override Column GetColumnByName(string table, string columnName)
132132
// Duplicate because of the lower case issue
133133
return Array.Find(GetColumns(table), column => column.Name == columnName.ToLower());
134134
}
135+
136+
public override bool IndexExists(string table, string name)
137+
{
138+
using (IDataReader reader =
139+
ExecuteQuery(string.Format("SELECT indexname FROM pg_catalog.pg_indexes WHERE indexname = lower('{0}')", name)))
140+
{
141+
return reader.Read();
142+
}
143+
}
135144
}
136145
}

src/Migrator.Providers/Impl/SQLite/SQLiteTransformationProvider.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,5 +235,14 @@ public bool ColumnMatch(string column, string columnDef)
235235
{
236236
return columnDef.StartsWith(column + " ") || columnDef.StartsWith(_dialect.Quote(column));
237237
}
238+
239+
public override bool IndexExists(string table, string name)
240+
{
241+
using (IDataReader reader =
242+
ExecuteQuery(String.Format("SELECT name FROM sqlite_master WHERE type='index' and name='{0}'", name)))
243+
{
244+
return reader.Read();
245+
}
246+
}
238247
}
239248
}

src/Migrator.Providers/Impl/SqlServer/SqlServerTransformationProvider.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,5 +157,24 @@ INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC
157157
+ "AND col.name = '{1}' AND col.id = object_id('{0}')",
158158
table, column);*/
159159
}
160+
161+
public override bool IndexExists(string table, string name)
162+
{
163+
using (IDataReader reader =
164+
ExecuteQuery(string.Format("SELECT top 1 * FROM sys.indexes WHERE object_id = OBJECT_ID('{0}') AND name = '{1}'", table, name)))
165+
{
166+
return reader.Read();
167+
}
168+
}
169+
170+
public override void RemoveIndex(string table, string name)
171+
{
172+
if (TableExists(table) && IndexExists(table, name))
173+
{
174+
table = _dialect.TableNameNeedsQuote ? _dialect.Quote(table) : table;
175+
name = _dialect.ConstraintNameNeedsQuote ? _dialect.Quote(name) : name;
176+
ExecuteNonQuery(String.Format("DROP INDEX {0} ON {1}", name, table));
177+
}
178+
}
160179
}
161180
}

src/Migrator.Providers/NoOpTransformationProvider.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,5 +355,20 @@ public int Insert(string table, string[] columns, string[] columnValues)
355355
protected void CreateSchemaInfoTable()
356356
{
357357
}
358+
359+
public void RemoveIndex(string table, string name)
360+
{
361+
// No Op
362+
}
363+
364+
public void AddIndex(string name, string table, params string[] columns)
365+
{
366+
// No Op
367+
}
368+
369+
public bool IndexExists(string table, string name)
370+
{
371+
return false;
372+
}
358373
}
359374
}

src/Migrator.Providers/TransformationProvider.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,5 +1036,26 @@ void QuoteColumnNames(string[] primaryColumns)
10361036
primaryColumns[i] = QuoteColumnNameIfRequired(primaryColumns[i]);
10371037
}
10381038
}
1039+
1040+
public virtual void RemoveIndex(string table, string name)
1041+
{
1042+
if (TableExists(table) && IndexExists(table, name))
1043+
{
1044+
name = _dialect.ConstraintNameNeedsQuote ? _dialect.Quote(name) : name;
1045+
ExecuteNonQuery(String.Format("DROP INDEX {0}", name));
1046+
}
1047+
}
1048+
1049+
public virtual void AddIndex(string name, string table, params string[] columns)
1050+
{
1051+
if (IndexExists(table, name))
1052+
{
1053+
Logger.Warn("Index {0} already exists", name);
1054+
return;
1055+
}
1056+
ExecuteNonQuery(String.Format("CREATE INDEX {0} ON {1} ({2}) ", name, table, string.Join(", ", columns)));
1057+
}
1058+
1059+
public abstract bool IndexExists(string table, string name);
10391060
}
10401061
}

src/Migrator.Tests/Providers/GenericProviderTests.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,10 @@ public override bool ConstraintExists(string table, string name)
2626
{
2727
return false;
2828
}
29+
30+
public override bool IndexExists(string table, string name)
31+
{
32+
return false;
33+
}
2934
}
3035
}

0 commit comments

Comments
 (0)