-
Notifications
You must be signed in to change notification settings - Fork 207
Expand file tree
/
Copy pathTdsMessageCodec.java
More file actions
144 lines (121 loc) · 3.73 KB
/
Copy pathTdsMessageCodec.java
File metadata and controls
144 lines (121 loc) · 3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
* Copyright (c) 2011-2022 Contributors to the Eclipse Foundation
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
*/
package io.vertx.mssqlclient.impl.codec;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.CombinedChannelDuplexHandler;
import io.vertx.sqlclient.ClosedConnectionException;
import io.vertx.sqlclient.impl.command.CommandBase;
import io.vertx.sqlclient.impl.command.CommandResponse;
import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class TdsMessageCodec extends CombinedChannelDuplexHandler<TdsMessageDecoder, TdsMessageEncoder> {
private final ArrayDeque<MSSQLCommandCodec<?, ?>> inflight = new ArrayDeque<>();
private final TdsMessageEncoder encoder;
private final TdsMessageDecoder decoder;
private ChannelHandlerContext chctx;
private ByteBufAllocator alloc;
private long transactionDescriptor;
private Map<String, CursorData> cursorDataMap;
private Throwable failure;
public TdsMessageCodec(int packetSize) {
decoder = new TdsMessageDecoder(this);
encoder = new TdsMessageEncoder(this, packetSize);
init(decoder, encoder);
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
super.handlerAdded(ctx);
chctx = ctx;
alloc = chctx.alloc();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
fail(cause);
super.exceptionCaught(ctx, cause);
}
private void fail(Throwable cause) {
if (failure == null) {
failure = cause;
for (Iterator<MSSQLCommandCodec<?, ?>> it = inflight.iterator(); it.hasNext(); ) {
MSSQLCommandCodec<?, ?> codec = it.next();
it.remove();
fail(codec, cause);
}
}
}
private void fail(MSSQLCommandCodec<?, ?> codec, Throwable cause) {
CommandResponse<Object> failure = CommandResponse.failure(cause);
failure.cmd = (CommandBase) codec.cmd;
chctx.fireChannelRead(failure);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
fail(ClosedConnectionException.INSTANCE);
super.channelInactive(ctx);
}
TdsMessageEncoder encoder() {
return encoder;
}
TdsMessageDecoder decoder() {
return decoder;
}
ChannelHandlerContext chctx() {
return chctx;
}
ByteBufAllocator alloc() {
return alloc;
}
long transactionDescriptor() {
return transactionDescriptor;
}
void setTransactionDescriptor(long transactionDescriptor) {
this.transactionDescriptor = transactionDescriptor;
}
MSSQLCommandCodec<?, ?> peek() {
return inflight.peek();
}
MSSQLCommandCodec<?, ?> poll() {
return inflight.poll();
}
boolean add(MSSQLCommandCodec<?, ?> codec) {
if (failure == null) {
inflight.add(codec);
return true;
} else {
fail(codec, failure);
return false;
}
}
CursorData getOrCreateCursorData(String cursorId) {
if (cursorDataMap == null) {
cursorDataMap = new HashMap<>();
}
CursorData cd = cursorDataMap.get(cursorId);
if (cd == null) {
cd = new CursorData();
cursorDataMap.put(cursorId, cd);
}
return cd;
}
CursorData removeCursorData(String cursorId) {
if (cursorDataMap == null) {
return null;
}
CursorData cd = cursorDataMap.remove(cursorId);
if (cursorDataMap.isEmpty()) {
cursorDataMap = null;
}
return cd;
}
}