• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

future-architect / uroborosql / #930

18 Nov 2025 08:54AM UTC coverage: 90.783%. First build
#930

push

Copilot
Add supportsBatchGeneratedKeys() to Dialect and implement fix for SQL Server

Co-authored-by: HidekiSugimoto189 <21981922+HidekiSugimoto189@users.noreply.github.com>

7 of 8 new or added lines in 4 files covered. (87.5%)

9219 of 10155 relevant lines covered (90.78%)

0.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.43
/src/main/java/jp/co/future/uroborosql/dialect/MsSqlDialect.java
1
/**
2
 * Copyright (c) 2017-present, Future Corporation
3
 *
4
 * This source code is licensed under the MIT license found in the
5
 * LICENSE file in the root directory of this source tree.
6
 */
7
package jp.co.future.uroborosql.dialect;
8

9
import java.util.ArrayList;
10
import java.util.List;
11
import java.util.Set;
12
import java.util.stream.Collectors;
13

14
import jp.co.future.uroborosql.enums.ForUpdateType;
15

16
/**
17
 * Microsoft SQLServer用のDialect
18
 *
19
 * @author H.Sugimoto
20
 */
21
public class MsSqlDialect extends AbstractDialect {
22
        private static final char[] WILDCARDS = { '%', '_', '[', ']' };
1✔
23

24
        /**
25
         * 悲観ロックのErrorCode もしくは SqlState. MSSQLの場合はErrorCodeで判定する.
26
         * <pre>SQL Error [1222] [S00045]: ロック要求がタイムアウトしました。 </pre>
27
         */
28
        private static final Set<String> pessimisticLockingErrorCodes = Set.of("1222");
1✔
29

30
        /**
31
         * コンストラクタ
32
         */
33
        public MsSqlDialect() {
34
                super('$', WILDCARDS);
1✔
35
        }
1✔
36

37
        /**
38
         * {@inheritDoc}
39
         *
40
         * @see jp.co.future.uroborosql.dialect.Dialect#getDatabaseName()
41
         */
42
        @Override
43
        public String getDatabaseName() {
44
                return "Microsoft SQL Server";
1✔
45
        }
46

47
        /**
48
         * {@inheritDoc}
49
         *
50
         * @see jp.co.future.uroborosql.dialect.AbstractDialect#getDatabaseType()
51
         */
52
        @Override
53
        public String getDatabaseType() {
54
                return "mssql";
1✔
55
        }
56

57
        /**
58
         * {@inheritDoc}
59
         *
60
         * <br>MSSQLではMerge文で;を使用するため終端文字の削除を行わない
61
         *
62
         * @see jp.co.future.uroborosql.dialect.Dialect#isRemoveTerminator()
63
         *
64
         * @return false
65
         */
66
        @Override
67
        public boolean isRemoveTerminator() {
68
                return false;
1✔
69
        }
70

71
        /**
72
         * {@inheritDoc}
73
         *
74
         * @see jp.co.future.uroborosql.dialect.Dialect#supportsForUpdateWait()
75
         */
76
        @Override
77
        public boolean supportsForUpdateWait() {
78
                return false;
1✔
79
        }
80

81
        /**
82
         * {@inheritDoc}
83
         *
84
         * @see jp.co.future.uroborosql.dialect.Dialect#supportsOptimizerHints()
85
         */
86
        @Override
87
        public boolean supportsOptimizerHints() {
88
                return true;
1✔
89
        }
90

91
        /**
92
         * {@inheritDoc}
93
         *
94
         * @see jp.co.future.uroborosql.dialect.Dialect#needsStrictSqlTypeForNullSetting()
95
         */
96
        @Override
97
        public boolean needsStrictSqlTypeForNullSetting() {
98
                return true;
1✔
99
        }
100

101
        /**
102
         * {@inheritDoc}
103
         *
104
         * @see jp.co.future.uroborosql.dialect.Dialect#getSequenceNextValSql(java.lang.String)
105
         */
106
        @Override
107
        public String getSequenceNextValSql(final String sequenceName) {
108
                return "next value for " + sequenceName;
1✔
109
        }
110

111
        /**
112
         * {@inheritDoc}
113
         *
114
         * @see jp.co.future.uroborosql.dialect.AbstractDialect#addForUpdateClause(java.lang.StringBuilder, jp.co.future.uroborosql.enums.ForUpdateType, int)
115
         */
116
        @Override
117
        public StringBuilder addForUpdateClause(final StringBuilder sql, final ForUpdateType forUpdateType,
118
                        final int waitSeconds) {
119
                var hints = new ArrayList<String>();
1✔
120
                hints.add("UPDLOCK");
1✔
121
                hints.add("ROWLOCK");
1✔
122
                if (forUpdateType == ForUpdateType.NOWAIT) {
1✔
123
                        hints.add("NOWAIT");
1✔
124
                }
125
                var forUpdate = "$1 WITH " + hints.stream()
1✔
126
                                .collect(Collectors.joining(", ", "(", ")")) + System.lineSeparator();
1✔
127
                return new StringBuilder(sql.toString().replaceFirst("((FROM|from)\\s+[^\\s]+)\\s*", forUpdate));
1✔
128
        }
129

130
        /**
131
         * {@inheritDoc}
132
         *
133
         * @see jp.co.future.uroborosql.dialect.Dialect#addOptimizerHints(java.lang.StringBuilder, java.util.List)
134
         */
135
        @Override
136
        public StringBuilder addOptimizerHints(final StringBuilder sql, final List<String> hints) {
137
                if (sql.indexOf("WITH (") > 0) {
1✔
138
                        // forUpdateのヒントが追加されている場合
139
                        var hintStr = "WITH ($1, " + hints.stream()
1✔
140
                                        .collect(Collectors.joining(", ")) + ")";
1✔
141
                        return new StringBuilder(sql.toString().replaceFirst("WITH \\((.+)\\)", hintStr));
1✔
142
                } else {
143
                        var hintStr = "$1 WITH " + hints.stream()
1✔
144
                                        .collect(Collectors.joining(", ", "(", ")")) + System.lineSeparator();
1✔
145
                        return new StringBuilder(sql.toString().replaceFirst("((FROM|from)\\s+[^\\s]+)\\s*", hintStr));
1✔
146
                }
147
        }
148

149
        /**
150
         * {@inheritDoc}
151
         *
152
         * @see jp.co.future.uroborosql.dialect.Dialect#getPessimisticLockingErrorCodes()
153
         */
154
        @Override
155
        public Set<String> getPessimisticLockingErrorCodes() {
156
                return pessimisticLockingErrorCodes;
1✔
157
        }
158

159
        /**
160
         * {@inheritDoc}
161
         *
162
         * SQLServerのJDBCドライバーはexecuteBatch()実行時にgetGeneratedKeys()をサポートしていない
163
         *
164
         * @see jp.co.future.uroborosql.dialect.Dialect#supportsBatchGeneratedKeys()
165
         */
166
        @Override
167
        public boolean supportsBatchGeneratedKeys() {
NEW
168
                return false;
×
169
        }
170
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc