private static List<DatabaseArgument> StoredProcedureArguments(IEnumerable<DataRow> dataView, ArgumentsKeyMap argumentsKeyMap) { List<DatabaseArgument> list = new List<DatabaseArgument>(); foreach (DataRow row in dataView) { var argName = row[argumentsKeyMap.ParameterName].ToString(); //check if it's already there var argument = AddArgumentToList(list, argName); argument.ProcedureName = row[argumentsKeyMap.SprocName].ToString(); argument.SchemaOwner = row[argumentsKeyMap.OwnerKey].ToString(); AddPackage(row, argumentsKeyMap.PackageKey, argument); if (!string.IsNullOrEmpty(argumentsKeyMap.OrdinalKey)) argument.Ordinal = Convert.ToDecimal(row[argumentsKeyMap.OrdinalKey], CultureInfo.CurrentCulture); argument.DatabaseDataType = row[argumentsKeyMap.DatatypeKey].ToString(); AddInOut(row, argumentsKeyMap.InoutKey, argument); if (argumentsKeyMap.Db2ColumnTypeKey != null) ApplyColumnType((string)row[argumentsKeyMap.Db2ColumnTypeKey], argument); //Oracle: these can be decimals, but we'll assume ints if (argumentsKeyMap.LengthKey != null) argument.Length = GetNullableInt(row[argumentsKeyMap.LengthKey]); if (argumentsKeyMap.PrecisionKey != null) argument.Precision = GetNullableInt(row[argumentsKeyMap.PrecisionKey]); if (argumentsKeyMap.ScaleKey != null) argument.Scale = GetNullableInt(row[argumentsKeyMap.ScaleKey]); } return list; }
public void UpdateArguments(DatabaseSchema databaseSchema, DataTable arguments) { if (arguments.Columns.Count == 0) return; //empty datatable var argumentsKeyMap = new ArgumentsKeyMap(arguments); var argumentGrouping = arguments.Rows.OfType<DataRow>() .ToLookup( x => (x[argumentsKeyMap.OwnerKey] ?? string.Empty) + "." + (x[argumentsKeyMap.SprocName] ?? string.Empty)); bool hasPackage = !string.IsNullOrEmpty(argumentsKeyMap.PackageKey); //project the sprocs (which won't have packages) into a distinct view DataTable sprocTable; arguments.DefaultView.Sort = argumentsKeyMap.SprocName; if (!hasPackage) sprocTable = arguments.DefaultView.ToTable(true, argumentsKeyMap.SprocName, argumentsKeyMap.OwnerKey); //distinct else sprocTable = arguments.DefaultView.ToTable(true, argumentsKeyMap.SprocName, argumentsKeyMap.OwnerKey, argumentsKeyMap.PackageKey); var sprocFilter = StoredProcedureFilter; var packFilter = PackageFilter; //go thru all sprocs with arguments- if not in sproc list, add it foreach (DataRow row in sprocTable.Rows) { string name = row[argumentsKeyMap.SprocName].ToString(); //a procedure without a name? if (string.IsNullOrEmpty(name)) continue; if (sprocFilter != null && sprocFilter.Exclude(name)) continue; string owner = row[argumentsKeyMap.OwnerKey].ToString(); if (argumentsKeyMap.IsDb2) { //ignore db2 system sprocs if (IsDb2SystemSchema(owner)) continue; } string package = null; //for non-Oracle, package is always null if (hasPackage) { package = row[argumentsKeyMap.PackageKey].ToString(); if (string.IsNullOrEmpty(package)) package = null; //so we can match easily else if (packFilter != null && packFilter.Exclude(package)) continue; } var rows = argumentGrouping[owner + "." + name]; if (!string.IsNullOrEmpty(argumentsKeyMap.OrdinalKey)) rows = rows.OrderBy(r => r[argumentsKeyMap.OrdinalKey]); List<DatabaseArgument> args = StoredProcedureArguments(rows, argumentsKeyMap); DatabaseStoredProcedure sproc = FindStoredProcedureOrFunction(databaseSchema, name, owner, package); if (sproc == null) //sproc in a package and not found before? { sproc = CreateProcedureOrFunction(databaseSchema, args); sproc.Name = name; sproc.SchemaOwner = owner; sproc.Package = package; } else { //clear any existing arguments before we add them sproc.Arguments.Clear(); } sproc.Arguments.AddRange(args); } }