チェンジセット 1644 (default)


以下の違いを無視:
日時:
2024/05/24 18:22:19 (4ヵ月前)
更新者:
hizuya@…
ログメッセージ:
  • DbDataOperator.Import で (単純な) 変数の展開を可能にした。
場所:
framework/trunk
ファイル:
12個の追加
3個の更新

凡例:

未変更
追加
削除
  • framework/trunk/CoreLibrary/Sources/Data/DbDataOperator.cs

    r1643 r1644  
    3030    using System.Reflection; 
    3131    using System.Text; 
     32    using System.Text.RegularExpressions; 
    3233    using FCSoft.SilverFrost.Framework.Collection; 
    3334    using FCSoft.SilverFrost.Framework.IO; 
     
    13521353            Stream stream) 
    13531354        { 
    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); 
    13551376        } 
    13561377 
     
    18551876        /// <param name="transaction">トランザクション。</param> 
    18561877        /// <param name="stream">インポートするデータを読み込むストリーム。</param> 
     1878        /// <param name="variables">変数名をキーとして埋め込む値を値としたディクショナリ。</param> 
    18571879        /// <returns> 
    18581880        /// インポートした行数。 
     
    18631885        private static int ImportImpl( 
    18641886            ICommonDbTransaction transaction, 
    1865             Stream stream) 
     1887            Stream stream, 
     1888            IDictionary<string, object> variables) 
    18661889        { 
    18671890            using (AutoDetectEncodingStreamReader reader 
     
    19501973 
    19511974                            // データ行 
    1952                             affectedRows += insertCommand.Insert(line); 
     1975                            affectedRows += insertCommand.Insert(line, variables); 
    19531976                        } 
    19541977                        catch (Exception ex) 
     
    23182341            /// </summary> 
    23192342            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); 
    23202351 
    23212352            /// <summary> 
     
    25052536            /// </summary> 
    25062537            /// <param name="line">データ行。</param> 
     2538            /// <param name="variables">変数名をキーとして埋め込む値を値としたディクショナリ。</param> 
    25072539            /// <returns> 
    25082540            /// INSERT した行数。 
    25092541            /// </returns> 
    2510             internal int Insert(string line) 
     2542            internal int Insert(string line, IDictionary<string, object> variables) 
    25112543            { 
    25122544                string[] lineColumns = line.Split(ColumnSeparatorChars, StringSplitOptions.None); 
     
    25412573                        { 
    25422574                            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 
    25482583                            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 
    25542594                            default: 
    2555                                 parameterValue = column; 
     2595                                // 変数の解決 
     2596                                parameterValue = ResolveVariable(column, variables); 
    25562597                                break; 
    25572598                        } 
     
    25592600                    else 
    25602601                    { 
     2602                        // 変数の解決はしない (変数 ${...} の文字数に足りていないので変数ではない) 
    25612603                        parameterValue = column; 
    25622604                    } 
     
    26292671 
    26302672            /// <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> 
    26312700            /// 実行するクエリを準備します。 
    26322701            /// </summary> 
  • framework/trunk/CoreTest/CoreTest.csproj

    r1643 r1644  
    366366    <EmbeddedResource Include="TestResources\Data\DbDataOperatorImportTest\19-ResetEmpty-2.txt" /> 
    367367  </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> 
    368378  <Import Project="$(MSBuildThisFileDirectory)..\MSBuild.Common.targets" /> 
    369379</Project> 
  • framework/trunk/CoreTest/Sources/Data/DbDataOperatorImportTest.cs

    r1643 r1644  
    2222namespace FCSoft.SilverFrost.Framework.Data 
    2323{ 
     24    using System.Collections.Generic; 
    2425    using System.IO; 
    2526    using FCSoft.SilverFrost.Framework.Test; 
     
    6061        /// <param name="initialRows">最初に準備する行数。</param> 
    6162        /// <param name="affectedRows">インポートした行数。</param> 
     63        /// <param name="useVariables"> 
     64        /// 埋め込みに使用する変数を使用する場合は <see langword="true"/>。 
     65        /// それ以外の場合は <see langword="false"/>。 
     66        /// </param> 
    6267        /// <param name="expedtedDataFile">結果のデータ。</param> 
    6368        [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) 
    99112        { 
    100113            string path = UnitTestUtility.NormalizeDataPath(Path.Combine("Import", importFileName)); 
     
    124137                    } 
    125138 
     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 
    126151                    int actualAffectedRows; 
    127152                    using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) 
    128153                    { 
    129                         actualAffectedRows = DbDataOperator.Import(transaction, fileStream); 
     154                        actualAffectedRows = DbDataOperator.Import(transaction, fileStream, variables); 
    130155                    } 
    131156 
詳しい使い方は TracChangeset を参照してください。