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

future-architect / uroborosql / #743

28 Jun 2024 04:17PM UTC coverage: 90.988% (+0.5%) from 90.484%
#743

push

web-flow
add paramIfNotEmpty method (#318)

* v0.x to master merge

* fix nanoseconds diff (java8 to java11)

* eclipse cleanup and  optimize import

* eclipse format

* optimize Imports

* remove unused annotation

* library version up

* migrate v0.x to master
- update java version 8 to 11
- update junit4 to junit5
- library version update

* fix test failed

* remove unused annotation

* fixed bug

* use var

* fix java8 coding style

* Refactoring TransactionContextManager

* Refactoring SqlAgent

* 途中コミット

* fix testcase

* fix review

* fix javadoc comments

* merge v0.x PR

* cleanup code

* cleanup test code

* change build status badge

* - agent.query, update, proc, batch にそれぞれSupplierを引数にとるメソッドを追加
- SqlQuery.paramとSqlEntityUpdate.setにFunctionを受け取るメソッドを追加

* testcaseの整形

* - SqlFluent と ExtractionCondition の分離
- Arrays.asList -> List.of への変更
- テストの整形

* - v0.x系の不具合対応の追いつき
- ログ出力の整理

* - SqlKindの整理(ENTITY_XXXの追加)
- REPL_LOGの追加
- Deprecatedメソッドの削除(SqlAgent)
- SqlAgent, ExecutionContextでsetterをfluent APIに変更

* DB接続URLの修正

* add and fix testcases.

* add event testcases.

* fix typo

* add paramIfNotEmpty method and StringUtils rename ObjectUtils

* fix review comments.

* remove unused import

1695 of 1958 new or added lines in 97 files covered. (86.57%)

26 existing lines in 10 files now uncovered.

8249 of 9066 relevant lines covered (90.99%)

0.91 hits per line

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

97.7
/src/main/java/jp/co/future/uroborosql/event/subscriber/AuditLogEventSubscriber.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.event.subscriber;
8

9
import java.sql.ResultSet;
10
import java.sql.SQLException;
11

12
import org.slf4j.Logger;
13
import org.slf4j.LoggerFactory;
14

15
import jp.co.future.uroborosql.context.ExecutionContext;
16
import jp.co.future.uroborosql.event.SqlBatchEvent;
17
import jp.co.future.uroborosql.event.SqlQueryEvent;
18
import jp.co.future.uroborosql.event.SqlUpdateEvent;
19

20
/**
21
 * 監査用ログを出力するイベントサブスクライバ
22
 *
23
 * @author H.Sugimoto
24
 * @since v1.0.0
25
 *
26
 */
27
public class AuditLogEventSubscriber extends EventSubscriber {
28
        /** イベントロガー */
29
        private static final Logger EVENT_LOG = LoggerFactory.getLogger("jp.co.future.uroborosql.event");
1✔
30

31
        /** 機能名取得用のパラメータキー名 */
32
        private String funcIdKey = "_funcId";
1✔
33

34
        /** ユーザ名取得用のパラメータキー名 */
35
        private String userNameKey = "_userName";
1✔
36

37
        /** ユーザ名の初期値 */
38
        private static final String DEFAULT_USER_NAME = "UNKNOWN";
39

40
        /** 機能名の初期値 */
41
        private static final String DEFAULT_FUNC_ID = "UNKNOWN";
42

43
        /**
44
         * コンストラクタ
45
         */
46
        public AuditLogEventSubscriber() {
1✔
47
        }
1✔
48

49
        /**
50
         *
51
         * {@inheritDoc}
52
         *
53
         * @see jp.co.future.uroborosql.event.subscriber.EventSubscriber#initialize()
54
         */
55
        @Override
56
        public void initialize() {
57
                sqlQueryListener(this::sqlQuery);
1✔
58
                sqlUpdateListener(this::sqlUpdate);
1✔
59
                sqlBatchListener(this::sqlBatch);
1✔
60
        }
1✔
61

62
        void sqlQuery(final SqlQueryEvent evt) {
63
                var resultSet = evt.getResultSet();
1✔
64
                // カウント初期値
65
                var rowCount = -1;
1✔
66
                try {
67
                        // resultSetのカーソル種別を取得
68
                        // 種別「TYPE_FORWARD_ONLY」の場合、beforeFirstメソッドが効かないため除外
69
                        if (resultSet.getType() != ResultSet.TYPE_FORWARD_ONLY) {
1✔
70
                                // 件数結果取得
71
                                resultSet.last();
1✔
72
                                rowCount = resultSet.getRow();
1✔
73
                                resultSet.beforeFirst();
1✔
74
                        }
NEW
75
                } catch (SQLException ex) {
×
76
                        // ここでの例外は実処理に影響を及ぼさないよう握りつぶす
77
                }
1✔
78

79
                var userName = getParam(evt.getExecutionContext(), userNameKey);
1✔
80
                if (userName == null) {
1✔
81
                        // ユーザ名が設定されていない時
82
                        userName = DEFAULT_USER_NAME;
1✔
83
                }
84

85
                var funcId = getParam(evt.getExecutionContext(), funcIdKey);
1✔
86
                if (funcId == null) {
1✔
87
                        // 機能IDが設定されていない時
88
                        funcId = DEFAULT_FUNC_ID;
1✔
89
                }
90

91
                if (EVENT_LOG.isDebugEnabled()) {
1✔
92
                        EVENT_LOG.debug("AuditData: {}", new AuditData(userName,
1✔
93
                                        funcId,
94
                                        evt.getExecutionContext().getSqlId(),
1✔
95
                                        evt.getExecutionContext().getSqlName(),
1✔
96
                                        evt.getExecutionContext().getExecutableSql(),
1✔
97
                                        rowCount));
98
                }
99
        }
1✔
100

101
        void sqlUpdate(final SqlUpdateEvent evt) {
102
                var userName = getParam(evt.getExecutionContext(), userNameKey);
1✔
103
                if (userName == null) {
1✔
104
                        // ユーザ名が設定されていない時
105
                        userName = DEFAULT_USER_NAME;
1✔
106
                }
107

108
                var funcId = getParam(evt.getExecutionContext(), funcIdKey);
1✔
109
                if (funcId == null) {
1✔
110
                        // 機能IDが設定されていない時
111
                        funcId = DEFAULT_FUNC_ID;
1✔
112
                }
113

114
                if (EVENT_LOG.isDebugEnabled()) {
1✔
115
                        EVENT_LOG.debug("AuditData: {}", new AuditData(userName,
1✔
116
                                        funcId,
117
                                        evt.getExecutionContext().getSqlId(),
1✔
118
                                        evt.getExecutionContext().getSqlName(),
1✔
119
                                        evt.getExecutionContext().getExecutableSql(),
1✔
120
                                        evt.getCount()));
1✔
121
                }
122
        }
1✔
123

124
        void sqlBatch(final SqlBatchEvent evt) {
125
                var userName = getParam(evt.getExecutionContext(), userNameKey);
1✔
126
                if (userName == null) {
1✔
127
                        // ユーザ名が設定されていない時
128
                        userName = DEFAULT_USER_NAME;
1✔
129
                }
130

131
                var funcId = getParam(evt.getExecutionContext(), funcIdKey);
1✔
132
                if (funcId == null) {
1✔
133
                        // 機能IDが設定されていない時
134
                        funcId = DEFAULT_FUNC_ID;
1✔
135
                }
136
                var rowCount = -1;
1✔
137
                if (EVENT_LOG.isDebugEnabled()) {
1✔
138
                        try {
139
                                rowCount = evt.getPreparedStatement().getUpdateCount();
1✔
140
                        } catch (SQLException ex) {
×
141
                                // ここでの例外は実処理に影響を及ぼさないよう握りつぶす
142
                        }
1✔
143
                        EVENT_LOG.debug("AuditData: {}", new AuditData(userName,
1✔
144
                                        funcId,
145
                                        evt.getExecutionContext().getSqlId(),
1✔
146
                                        evt.getExecutionContext().getSqlName(),
1✔
147
                                        evt.getExecutionContext().getExecutableSql(),
1✔
148
                                        rowCount));
149
                }
150
        }
1✔
151

152
        /**
153
         * バインドパラメータに設定した機能IDのキー名を設定する.
154
         *
155
         * @param funcIdKey 機能IDのキー名
156
         * @return AuditLogEventSubscriber
157
         */
158
        public AuditLogEventSubscriber setFuncIdKey(final String funcIdKey) {
159
                this.funcIdKey = funcIdKey;
1✔
160
                return this;
1✔
161
        }
162

163
        /**
164
         * バインドパラメータに設定したユーザ名のキー名を設定する.
165
         *
166
         * @param userNameKey ユーザ名のキー名
167
         * @return AuditLogEventSubscriber
168
         */
169
        public AuditLogEventSubscriber setUserNameKey(final String userNameKey) {
170
                this.userNameKey = userNameKey;
1✔
171
                return this;
1✔
172
        }
173

174
        /**
175
         * パラメータ値を取得する
176
         *
177
         * @param ctx ExecutionContext
178
         * @param key パラメータのキー
179
         * @return パラメータの値。キーに対するパラメータが存在しない場合は<code>null</code>.
180
         */
181
        private String getParam(final ExecutionContext ctx, final String key) {
182
                var param = ctx.getParam(key);
1✔
183
                if (param == null) {
1✔
184
                        return null;
1✔
185
                } else {
186
                        return String.valueOf(param.getValue());
1✔
187
                }
188
        }
189

190
        /**
191
         * 監査用データ
192
         */
193
        private static final class AuditData {
194
                /** SQL文中でJSONとして不正な文字を置換するためのMap */
195
                private static final String[] ESC_CHARS = {
1✔
196
                                "\\\\:\\\\\\\\",
197
                                "\\\":\\\\\\\"",
198
                                "/:\\\\/",
199
                                "\\t:\\\\t",
200
                                "\\f:\\\\f",
201
                                "\\r\\n: ",
202
                                "\\n: ",
203
                                "\\r: "
204
                };
205

206
                private final String userName;
207
                private final String funcId;
208
                private final String sqlId;
209
                private final String sqlName;
210
                private final String sql;
211
                private final int rowCount;
212

213
                /**
214
                 * コンストラクタ
215
                 *
216
                 * @param userName ユーザ名
217
                 * @param funcId 機能ID
218
                 * @param sqlId SQL-ID
219
                 * @param sqlName SQL名
220
                 * @param sql SQL文
221
                 * @param rowCount 件数
222
                 */
223
                private AuditData(final String userName, final String funcId, final String sqlId, final String sqlName,
224
                                final String sql, final int rowCount) {
1✔
225
                        this.userName = userName;
1✔
226
                        this.funcId = funcId;
1✔
227
                        this.sqlId = sqlId;
1✔
228
                        this.sqlName = sqlName;
1✔
229
                        this.sql = sql;
1✔
230
                        this.rowCount = rowCount;
1✔
231
                }
1✔
232

233
                /**
234
                 * JSONとして不正な文字をエスケープする.
235
                 *
236
                 * @param str エスケープ対象文字列
237
                 * @return エスケープ後文字列
238
                 */
239
                private String escapeJson(final String str) {
240
                        if (str == null) {
1✔
241
                                return null;
1✔
242
                        }
243
                        var buff = str;
1✔
244
                        for (var escChar : ESC_CHARS) {
1✔
245
                                var parts = escChar.split(":");
1✔
246
                                buff = buff.replaceAll(parts[0], parts[1]);
1✔
247
                        }
248
                        return buff;
1✔
249
                }
250

251
                /**
252
                 * {@inheritDoc}
253
                 *
254
                 * @see java.lang.Object#toString()
255
                 */
256
                @Override
257
                public String toString() {
258
                        return "{\"userName\":\"" + escapeJson(userName)
1✔
259
                                        + "\",\"funcId\":\"" + escapeJson(funcId)
1✔
260
                                        + "\",\"sqlId\":\"" + escapeJson(sqlId)
1✔
261
                                        + "\",\"sqlName\":\"" + escapeJson(sqlName)
1✔
262
                                        + "\",\"sql\":\"" + escapeJson(sql)
1✔
263
                                        + "\",\"rowCount\":" + rowCount + "}";
264
                }
265

266
        }
267
}
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

© 2025 Coveralls, Inc