Skip to content

Commit b556416

Browse files
committed
Expand "Procedures" schema collection.
Return the same columns as Connector/NET, populated from the INFORMATION_SCHEMA.ROUTINES table.
1 parent 312e562 commit b556416

File tree

2 files changed

+72
-9
lines changed

2 files changed

+72
-9
lines changed

src/MySqlConnector/MySqlClient/SchemaProvider.cs

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System;
33
using System.Collections.Generic;
44
using System.Data;
5+
using System.Linq;
56
using MySql.Data.MySqlClient.Types;
67

78
namespace MySql.Data.MySqlClient
@@ -129,10 +130,28 @@ private void FillDataTypes(DataTable dataTable)
129130

130131
private void FillProcedures(DataTable dataTable)
131132
{
132-
dataTable.Columns.AddRange(new[] {
133-
new DataColumn("ROUTINE_TYPE"),
134-
new DataColumn("ROUTINE_SCHEMA"),
135-
new DataColumn("SPECIFIC_NAME")
133+
dataTable.Columns.AddRange(new[]
134+
{
135+
new DataColumn("SPECIFIC_NAME", typeof(string)),
136+
new DataColumn("ROUTINE_CATALOG", typeof(string)),
137+
new DataColumn("ROUTINE_SCHEMA", typeof(string)),
138+
new DataColumn("ROUTINE_NAME", typeof(string)),
139+
new DataColumn("ROUTINE_TYPE", typeof(string)),
140+
new DataColumn("DTD_IDENTIFIER", typeof(string)),
141+
new DataColumn("ROUTINE_BODY", typeof(string)),
142+
new DataColumn("ROUTINE_DEFINITION", typeof(string)),
143+
new DataColumn("EXTERNAL_NAME", typeof(string)),
144+
new DataColumn("EXTERNAL_LANGUAGE", typeof(string)),
145+
new DataColumn("PARAMETER_STYLE", typeof(string)),
146+
new DataColumn("IS_DETERMINISTIC", typeof(string)),
147+
new DataColumn("SQL_DATA_ACCESS", typeof(string)),
148+
new DataColumn("SQL_PATH", typeof(string)),
149+
new DataColumn("SECURITY_TYPE", typeof(string)),
150+
new DataColumn("CREATED", typeof(DateTime)),
151+
new DataColumn("LAST_ALTERED", typeof(DateTime)),
152+
new DataColumn("SQL_MODE", typeof(string)),
153+
new DataColumn("ROUTINE_COMMENT", typeof(string)),
154+
new DataColumn("DEFINER", typeof(string)),
136155
});
137156

138157
Action close = null;
@@ -142,12 +161,18 @@ private void FillProcedures(DataTable dataTable)
142161
close = m_connection.Close;
143162
}
144163

145-
var procsQuery = "SELECT ROUTINE_TYPE, ROUTINE_SCHEMA, SPECIFIC_NAME FROM INFORMATION_SCHEMA.ROUTINES;";
146-
using (var command = new MySqlCommand(procsQuery, m_connection))
147-
using (var reader = command.ExecuteReader())
164+
using (var command = m_connection.CreateCommand())
148165
{
149-
while (reader.Read())
150-
dataTable.Rows.Add(reader.GetString(0), reader.GetString(1), reader.GetString(2));
166+
command.CommandText = "SELECT " + string.Join(", ", dataTable.Columns.Cast<DataColumn>().Select(x => x.ColumnName)) + " FROM INFORMATION_SCHEMA.ROUTINES;";
167+
using (var reader = command.ExecuteReader())
168+
{
169+
while (reader.Read())
170+
{
171+
var rowValues = new object[dataTable.Columns.Count];
172+
reader.GetValues(rowValues);
173+
dataTable.Rows.Add(rowValues);
174+
}
175+
}
151176
}
152177

153178
close?.Invoke();

tests/SideBySide/StoredProcedureTests.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Data;
33
using System.Data.Common;
4+
using System.Linq;
45
using System.Threading.Tasks;
56
using MySql.Data.MySqlClient;
67
using Xunit;
@@ -401,6 +402,43 @@ public async Task DottedName(bool useDatabaseName)
401402
}
402403
}
403404

405+
#if !NETCOREAPP1_1_2
406+
[Theory]
407+
[InlineData("echof", "FUNCTION", "varchar(63)", "BEGIN RETURN name; END", "NO", "CONTAINS SQL")]
408+
[InlineData("echop", "PROCEDURE", null, "BEGIN SELECT name; END", "NO", "CONTAINS SQL")]
409+
[InlineData("failing_function", "FUNCTION", "int(11)", "BEGIN DECLARE v1 INT; SELECT c1 FROM table_that_does_not_exist INTO v1; RETURN v1; END", "NO", "CONTAINS SQL")]
410+
public void ProceduresSchema(string procedureName, string procedureType, string dtdIdentifier, string routineDefinition, string isDeterministic, string dataAccess)
411+
{
412+
var dataTable = m_database.Connection.GetSchema("Procedures");
413+
var schema = m_database.Connection.Database;
414+
var row = dataTable.Rows.Cast<DataRow>().Single(x => schema.Equals(x["ROUTINE_SCHEMA"]) && procedureName.Equals(x["ROUTINE_NAME"]));
415+
416+
Assert.Equal(procedureName, row["SPECIFIC_NAME"]);
417+
Assert.Equal(procedureType, row["ROUTINE_TYPE"]);
418+
if (dtdIdentifier == null)
419+
Assert.Equal(DBNull.Value, row["DTD_IDENTIFIER"]);
420+
else
421+
Assert.Equal(dtdIdentifier, ((string) row["DTD_IDENTIFIER"]).Split(' ')[0]);
422+
Assert.Equal(routineDefinition, NormalizeSpaces((string) row["ROUTINE_DEFINITION"]));
423+
Assert.Equal(isDeterministic, row["IS_DETERMINISTIC"]);
424+
Assert.Equal(dataAccess, ((string) row["SQL_DATA_ACCESS"]).Replace('_', ' '));
425+
}
426+
#endif
427+
428+
private static string NormalizeSpaces(string input)
429+
{
430+
input = input.Replace('\r', ' ');
431+
input = input.Replace('\n', ' ');
432+
input = input.Replace('\t', ' ');
433+
int startingLength;
434+
do
435+
{
436+
startingLength = input.Length;
437+
input = input.Replace(" ", " ");
438+
} while (input.Length != startingLength);
439+
return input;
440+
}
441+
404442
readonly DatabaseFixture m_database;
405443
}
406444
}

0 commit comments

Comments
 (0)