チェンジセット 1644 (default)
- 日時:
- 2024/05/24 18:22:19 (4ヵ月前)
- 場所:
- framework/trunk
- ファイル:
-
- 12個の追加
- 3個の更新
凡例:
- 未変更
- 追加
- 削除
-
framework/trunk/CoreLibrary/Sources/Data/DbDataOperator.cs
r1643 r1644 30 30 using System.Reflection; 31 31 using System.Text; 32 using System.Text.RegularExpressions; 32 33 using FCSoft.SilverFrost.Framework.Collection; 33 34 using FCSoft.SilverFrost.Framework.IO; … … 1352 1353 Stream stream) 1353 1354 { 1354 return ImportImpl(transaction, stream); 1355 return Import(transaction, stream, null); 1356 } 1357 1358 /// <summary> 1359 /// ストリームからデータをインポートします。 1360 /// </summary> 1361 /// <param name="transaction">トランザクション。</param> 1362 /// <param name="stream">インポートするデータを読み込むストリーム。</param> 1363 /// <param name="variables">変数名をキーとして埋め込む値を値としたディクショナリ。</param> 1364 /// <returns> 1365 /// インポートした行数。 1366 /// </returns> 1367 /// <exception cref="DataFileException"> 1368 /// インポート中に例外が発生しました。 1369 /// </exception> 1370 public static int Import( 1371 ICommonDbTransaction transaction, 1372 Stream stream, 1373 IDictionary<string, object> variables) 1374 { 1375 return ImportImpl(transaction, stream, variables); 1355 1376 } 1356 1377 … … 1855 1876 /// <param name="transaction">トランザクション。</param> 1856 1877 /// <param name="stream">インポートするデータを読み込むストリーム。</param> 1878 /// <param name="variables">変数名をキーとして埋め込む値を値としたディクショナリ。</param> 1857 1879 /// <returns> 1858 1880 /// インポートした行数。 … … 1863 1885 private static int ImportImpl( 1864 1886 ICommonDbTransaction transaction, 1865 Stream stream) 1887 Stream stream, 1888 IDictionary<string, object> variables) 1866 1889 { 1867 1890 using (AutoDetectEncodingStreamReader reader … … 1950 1973 1951 1974 // データ行 1952 affectedRows += insertCommand.Insert(line );1975 affectedRows += insertCommand.Insert(line, variables); 1953 1976 } 1954 1977 catch (Exception ex) … … 2318 2341 /// </summary> 2319 2342 private static readonly char[] ColumnSeparatorChars = { ColumnSeparatorChar }; 2343 2344 /// <summary> 2345 /// 変数を表す正規表現。 2346 /// </summary> 2347 private static readonly Regex VariableRegex 2348 = new Regex( 2349 @"\${(?<name>[^${:}]+)}", 2350 RegexOptions.ExplicitCapture); 2320 2351 2321 2352 /// <summary> … … 2505 2536 /// </summary> 2506 2537 /// <param name="line">データ行。</param> 2538 /// <param name="variables">変数名をキーとして埋め込む値を値としたディクショナリ。</param> 2507 2539 /// <returns> 2508 2540 /// INSERT した行数。 2509 2541 /// </returns> 2510 internal int Insert(string line )2542 internal int Insert(string line, IDictionary<string, object> variables) 2511 2543 { 2512 2544 string[] lineColumns = line.Split(ColumnSeparatorChars, StringSplitOptions.None); … … 2541 2573 { 2542 2574 case '"': 2543 parameterValue 2544 = column[column.Length - 1] == '"' 2545 ? TextUtility.UnquoteCommonString(column) 2546 : column; 2547 break; 2575 // "..." の場合 2576 if (column[column.Length - 1] == '"') 2577 { 2578 column = TextUtility.UnquoteCommonString(column); 2579 } 2580 2581 goto default; 2582 2548 2583 case '`': 2549 parameterValue 2550 = column[column.Length - 1] == '`' 2551 ? GetValue(transaction, column.Substring(1, column.Length - 2)) 2552 : column; 2553 break; 2584 // `...` の場合 2585 if (column[column.Length - 1] == '`') 2586 { 2587 // 変数の解決はしない 2588 parameterValue = GetValue(transaction, column.Substring(1, column.Length - 2)); 2589 break; 2590 } 2591 2592 goto default; 2593 2554 2594 default: 2555 parameterValue = column; 2595 // 変数の解決 2596 parameterValue = ResolveVariable(column, variables); 2556 2597 break; 2557 2598 } … … 2559 2600 else 2560 2601 { 2602 // 変数の解決はしない (変数 ${...} の文字数に足りていないので変数ではない) 2561 2603 parameterValue = column; 2562 2604 } … … 2629 2671 2630 2672 /// <summary> 2673 /// 文字列中の変数を解決して返します。 2674 /// </summary> 2675 /// <param name="value">文字列。</param> 2676 /// <param name="variables">変数名をキーとして埋め込む値を値としたディクショナリ。</param> 2677 /// <returns> 2678 /// 変数を解決した文字列。 2679 /// </returns> 2680 private static object ResolveVariable(string value, IDictionary<string, object> variables) 2681 { 2682 // 変数が未設定の場合や、変数の文字数に足りていない場合 2683 if (variables == null || value.Length < 4) 2684 { 2685 return value; 2686 } 2687 2688 return VariableRegex.Replace( 2689 value, 2690 delegate(Match match) 2691 { 2692 object variableValue; 2693 return variables.TryGetValue(match.Groups["name"].Value, out variableValue) 2694 ? (variableValue != null ? variableValue.ToString() : string.Empty) 2695 : match.Value; 2696 }); 2697 } 2698 2699 /// <summary> 2631 2700 /// 実行するクエリを準備します。 2632 2701 /// </summary> -
framework/trunk/CoreTest/CoreTest.csproj
r1643 r1644 366 366 <EmbeddedResource Include="TestResources\Data\DbDataOperatorImportTest\19-ResetEmpty-2.txt" /> 367 367 </ItemGroup> 368 <ItemGroup> 369 <EmbeddedResource Include="TestResources\Data\DbDataOperatorImportTest\31-QuoteString-0.txt" /> 370 <EmbeddedResource Include="TestResources\Data\DbDataOperatorImportTest\31-QuoteString-2.txt" /> 371 <EmbeddedResource Include="TestResources\Data\DbDataOperatorImportTest\32-Variable-0.txt" /> 372 <EmbeddedResource Include="TestResources\Data\DbDataOperatorImportTest\32-Variable-2.txt" /> 373 <EmbeddedResource Include="TestResources\Data\DbDataOperatorImportTest\33-VariableInQuoteString-0.txt" /> 374 <EmbeddedResource Include="TestResources\Data\DbDataOperatorImportTest\33-VariableInQuoteString-2.txt" /> 375 <EmbeddedResource Include="TestResources\Data\DbDataOperatorImportTest\34-VariableOnlyString-0.txt" /> 376 <EmbeddedResource Include="TestResources\Data\DbDataOperatorImportTest\34-VariableOnlyString-2.txt" /> 377 </ItemGroup> 368 378 <Import Project="$(MSBuildThisFileDirectory)..\MSBuild.Common.targets" /> 369 379 </Project> -
framework/trunk/CoreTest/Sources/Data/DbDataOperatorImportTest.cs
r1643 r1644 22 22 namespace FCSoft.SilverFrost.Framework.Data 23 23 { 24 using System.Collections.Generic; 24 25 using System.IO; 25 26 using FCSoft.SilverFrost.Framework.Test; … … 60 61 /// <param name="initialRows">最初に準備する行数。</param> 61 62 /// <param name="affectedRows">インポートした行数。</param> 63 /// <param name="useVariables"> 64 /// 埋め込みに使用する変数を使用する場合は <see langword="true"/>。 65 /// それ以外の場合は <see langword="false"/>。 66 /// </param> 62 67 /// <param name="expedtedDataFile">結果のデータ。</param> 63 68 [Test] 64 [TestCase(@"01-Append.txt", 0, 2, @"01-Append-0.txt")] 65 [TestCase(@"01-Append.txt", 2, 2, @"01-Append-2.txt")] 66 [TestCase(@"02-Truncate.txt", 0, 2, @"02-Truncate-0.txt")] 67 [TestCase(@"02-Truncate.txt", 2, 2, @"02-Truncate-2.txt")] 68 [TestCase(@"03-Reset.txt", 0, 2, @"03-Reset-0.txt")] 69 [TestCase(@"03-Reset.txt", 2, 2, @"03-Reset-2.txt")] 70 [TestCase(@"06-Condition.txt", 0, 3, @"06-Condition-0.txt")] 71 [TestCase(@"06-Condition.txt", 2, 3, @"06-Condition-2.txt")] 72 [TestCase(@"11-Append.txt", 0, 2, @"11-Append-0.txt")] 73 [TestCase(@"11-Append.txt", 2, 2, @"11-Append-2.txt")] 74 [TestCase(@"12-Truncate.txt", 0, 2, @"12-Truncate-0.txt")] 75 [TestCase(@"12-Truncate.txt", 2, 2, @"12-Truncate-2.txt")] 76 [TestCase(@"13-Reset.txt", 0, 2, @"13-Reset-0.txt")] 77 [TestCase(@"13-Reset.txt", 2, 2, @"13-Reset-2.txt")] 78 [TestCase(@"14-ResetWithValue.txt", 0, 2, @"14-ResetWithValue-0.txt")] 79 [TestCase(@"14-ResetWithValue.txt", 2, 2, @"14-ResetWithValue-2.txt")] 80 [TestCase(@"15-AppendWithValue.txt", 0, 2, @"15-AppendWithValue-0.txt")] 81 [TestCase(@"15-AppendWithValue.txt", 2, 2, @"15-AppendWithValue-2.txt")] 82 [TestCase(@"16-ConditionWithValue.txt", 0, 2, @"16-ConditionWithValue-0.txt")] 83 [TestCase(@"16-ConditionWithValue.txt", 2, 2, @"16-ConditionWithValue-2.txt")] 84 [TestCase(@"17-AppendEmpty.txt", 0, 2, @"17-AppendEmpty-0.txt")] 85 [TestCase(@"17-AppendEmpty.txt", 2, 2, @"17-AppendEmpty-2.txt")] 86 [TestCase(@"18-TruncateEmpty.txt", 0, 2, @"18-TruncateEmpty-0.txt")] 87 [TestCase(@"18-TruncateEmpty.txt", 2, 2, @"18-TruncateEmpty-2.txt")] 88 [TestCase(@"19-ResetEmpty.txt", 0, 2, @"19-ResetEmpty-0.txt")] 89 [TestCase(@"19-ResetEmpty.txt", 2, 2, @"19-ResetEmpty-2.txt")] 90 [TestCase(@"51-MissingColumnData.txt", 0, 3, @"51-MissingColumnData-0.txt")] 91 [TestCase(@"51-MissingColumnData.txt", 2, 3, @"51-MissingColumnData-2.txt")] 92 [TestCase(@"61-SubQuery.txt", 0, 2, @"61-SubQuery-0.txt")] 93 [TestCase(@"61-SubQuery.txt", 2, 2, @"61-SubQuery-2.txt")] 94 [TestCase(@"71-MultiTable.txt", 0, 4, @"71-MultiTable-0.txt")] 95 [TestCase(@"71-MultiTable.txt", 2, 4, @"71-MultiTable-2.txt")] 96 [TestCase(@"81-Command.txt", 0, 2, @"81-Command-0.txt")] 97 [TestCase(@"81-Command.txt", 2, 3, @"81-Command-2.txt")] 98 public void TestImport(string importFileName, int initialRows, int affectedRows, string expedtedDataFile) 69 [TestCase(@"01-Append.txt", 0, 2, false, @"01-Append-0.txt")] 70 [TestCase(@"01-Append.txt", 2, 2, false, @"01-Append-2.txt")] 71 [TestCase(@"02-Truncate.txt", 0, 2, false, @"02-Truncate-0.txt")] 72 [TestCase(@"02-Truncate.txt", 2, 2, false, @"02-Truncate-2.txt")] 73 [TestCase(@"03-Reset.txt", 0, 2, false, @"03-Reset-0.txt")] 74 [TestCase(@"03-Reset.txt", 2, 2, false, @"03-Reset-2.txt")] 75 [TestCase(@"06-Condition.txt", 0, 3, false, @"06-Condition-0.txt")] 76 [TestCase(@"06-Condition.txt", 2, 3, false, @"06-Condition-2.txt")] 77 [TestCase(@"11-Append.txt", 0, 2, false, @"11-Append-0.txt")] 78 [TestCase(@"11-Append.txt", 2, 2, false, @"11-Append-2.txt")] 79 [TestCase(@"12-Truncate.txt", 0, 2, false, @"12-Truncate-0.txt")] 80 [TestCase(@"12-Truncate.txt", 2, 2, false, @"12-Truncate-2.txt")] 81 [TestCase(@"13-Reset.txt", 0, 2, false, @"13-Reset-0.txt")] 82 [TestCase(@"13-Reset.txt", 2, 2, false, @"13-Reset-2.txt")] 83 [TestCase(@"14-ResetWithValue.txt", 0, 2, false, @"14-ResetWithValue-0.txt")] 84 [TestCase(@"14-ResetWithValue.txt", 2, 2, false, @"14-ResetWithValue-2.txt")] 85 [TestCase(@"15-AppendWithValue.txt", 0, 2, false, @"15-AppendWithValue-0.txt")] 86 [TestCase(@"15-AppendWithValue.txt", 2, 2, false, @"15-AppendWithValue-2.txt")] 87 [TestCase(@"16-ConditionWithValue.txt", 0, 2, false, @"16-ConditionWithValue-0.txt")] 88 [TestCase(@"16-ConditionWithValue.txt", 2, 2, false, @"16-ConditionWithValue-2.txt")] 89 [TestCase(@"17-AppendEmpty.txt", 0, 2, false, @"17-AppendEmpty-0.txt")] 90 [TestCase(@"17-AppendEmpty.txt", 2, 2, false, @"17-AppendEmpty-2.txt")] 91 [TestCase(@"18-TruncateEmpty.txt", 0, 2, false, @"18-TruncateEmpty-0.txt")] 92 [TestCase(@"18-TruncateEmpty.txt", 2, 2, false, @"18-TruncateEmpty-2.txt")] 93 [TestCase(@"19-ResetEmpty.txt", 0, 2, false, @"19-ResetEmpty-0.txt")] 94 [TestCase(@"19-ResetEmpty.txt", 2, 2, false, @"19-ResetEmpty-2.txt")] 95 [TestCase(@"31-QuoteString.txt", 0, 2, false, @"31-QuoteString-0.txt")] 96 [TestCase(@"31-QuoteString.txt", 2, 2, false, @"31-QuoteString-2.txt")] 97 [TestCase(@"32-Variable.txt", 0, 2, true, @"32-Variable-0.txt")] 98 [TestCase(@"32-Variable.txt", 2, 2, true, @"32-Variable-2.txt")] 99 [TestCase(@"33-VariableInQuoteString.txt", 0, 2, true, @"33-VariableInQuoteString-0.txt")] 100 [TestCase(@"33-VariableInQuoteString.txt", 2, 2, true, @"33-VariableInQuoteString-2.txt")] 101 [TestCase(@"34-VariableOnlyString.txt", 0, 2, false, @"34-VariableOnlyString-0.txt")] 102 [TestCase(@"34-VariableOnlyString.txt", 2, 2, false, @"34-VariableOnlyString-2.txt")] 103 [TestCase(@"51-MissingColumnData.txt", 0, 3, false, @"51-MissingColumnData-0.txt")] 104 [TestCase(@"51-MissingColumnData.txt", 2, 3, false, @"51-MissingColumnData-2.txt")] 105 [TestCase(@"61-SubQuery.txt", 0, 2, false, @"61-SubQuery-0.txt")] 106 [TestCase(@"61-SubQuery.txt", 2, 2, false, @"61-SubQuery-2.txt")] 107 [TestCase(@"71-MultiTable.txt", 0, 4, false, @"71-MultiTable-0.txt")] 108 [TestCase(@"71-MultiTable.txt", 2, 4, false, @"71-MultiTable-2.txt")] 109 [TestCase(@"81-Command.txt", 0, 2, false, @"81-Command-0.txt")] 110 [TestCase(@"81-Command.txt", 2, 3, false, @"81-Command-2.txt")] 111 public void TestImport(string importFileName, int initialRows, int affectedRows, bool useVariables, string expedtedDataFile) 99 112 { 100 113 string path = UnitTestUtility.NormalizeDataPath(Path.Combine("Import", importFileName)); … … 124 137 } 125 138 139 IDictionary<string, object> variables = null; 140 if (useVariables) 141 { 142 variables = new Dictionary<string, object>() 143 { 144 { "I_111", 111 }, 145 { "I_2", 2 }, 146 { "S_ABC", "ABC" }, 147 { "S_Y", "Y" }, 148 }; 149 } 150 126 151 int actualAffectedRows; 127 152 using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) 128 153 { 129 actualAffectedRows = DbDataOperator.Import(transaction, fileStream );154 actualAffectedRows = DbDataOperator.Import(transaction, fileStream, variables); 130 155 } 131 156
※ 詳しい使い方は
TracChangeset を参照してください。