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));
44 private class BatchFromStream implements Batch {
46 private DataInputStream in;
47 private boolean hasNext;
49 public BatchFromStream(DataInputStream in) throws BatchException {
51 hasNext = verifyHeader();
55 public boolean hasNext() throws BatchException {
60 public SQLCommand next() throws BatchException {
62 String sql = readNextString();
64 int paramCount = in.readInt();
65 List<Parameter> parameters = new ArrayList<>(paramCount);
67 for (int i = 0; i < paramCount; i++) {
68 SQLType type = SQLType.valueOf(in.readInt());
69 String value = readNextString();
70 parameters.add(new Parameter(value, type));
73 hasNext = verifyHeader();
75 SQLCommand sqlCommand = new SQLCommandNumbered(sql, parameters);
77 } catch (IOException e) {
78 throw new BatchException("Unable to read batch", e);
82 private String readNextString() throws IOException {
83 byte[] buffer = new byte[in.readInt()];
85 return new String(buffer, CHARSET);
89 * @return true if correct batch header was found | false if EOF was found
90 * @throws BatchException if unexpected data was found (not batch header nor EOF)
92 private boolean verifyHeader() throws BatchException {
94 byte[] buffer = new byte[BATCH_HEADER.length];
95 int bytesRead = in.read(buffer);
97 if (bytesRead == BATCH_HEADER.length && Arrays.equals(buffer, BATCH_HEADER)) {
99 } else if (bytesRead == -1) {
102 throw new BatchException("This is not SQL-DK batch: " + toHex(buffer));
104 } catch (IOException e) {
105 throw new BatchException("Unable to read batch header", e);