3 * Copyright © 2014 František Kučera (frantovo.cz)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 package info.globalcode.sql.dk.batch;
20 import info.globalcode.sql.dk.Parameter;
21 import info.globalcode.sql.dk.SQLCommand;
22 import info.globalcode.sql.dk.SQLCommandNumbered;
23 import java.io.DataInputStream;
24 import java.io.InputStream;
25 import static info.globalcode.sql.dk.batch.BatchConstants.*;
26 import static info.globalcode.sql.dk.Functions.toHex;
27 import info.globalcode.sql.dk.SQLType;
28 import java.io.IOException;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.List;
35 * @author Ing. František Kučera (frantovo.cz)
37 public class BatchDecoder {
39 public Batch decode(InputStream in) throws BatchException {
40 return new BatchFromStream(new DataInputStream(in));
43 private class BatchFromStream implements Batch {
45 private DataInputStream in;
46 private boolean hasNext;
48 public BatchFromStream(DataInputStream in) throws BatchException {
50 hasNext = verifyHeader();
54 public boolean hasNext() throws BatchException {
59 public SQLCommand next() throws BatchException {
61 String sql = readNextString();
63 int paramCount = in.readInt();
64 List<Parameter> parameters = new ArrayList<>(paramCount);
66 for (int i = 0; i < paramCount; i++) {
67 SQLType type = SQLType.valueOf(in.readInt());
68 String value = readNextString();
69 parameters.add(new Parameter(value, type));
72 hasNext = verifyHeader();
74 SQLCommand sqlCommand = new SQLCommandNumbered(sql, parameters);
76 } catch (IOException e) {
77 throw new BatchException("Unable to read batch", e);
81 private String readNextString() throws IOException {
82 byte[] buffer = new byte[in.readInt()];
84 return new String(buffer, CHARSET);
88 * @return true if correct batch header was found | false if EOF was found
89 * @throws BatchException if unexpected data was found (not batch header nor EOF)
91 private boolean verifyHeader() throws BatchException {
93 byte[] buffer = new byte[BATCH_HEADER.length];
94 int bytesRead = in.read(buffer);
96 if (bytesRead == BATCH_HEADER.length && Arrays.equals(buffer, BATCH_HEADER)) {
98 } else if (bytesRead == -1) {
101 throw new BatchException("This is not SQL-DK batch: " + toHex(buffer));
103 } catch (IOException e) {
104 throw new BatchException("Unable to read batch header", e);