java/sql-dk/src/info/globalcode/sql/dk/batch/BatchDecoder.java
author František Kučera <franta-hg@frantovo.cz>
Sat, 16 May 2015 21:42:52 +0200
branchv_0
changeset 189 f4d879cbcee1
parent 148 1b2f40cd432b
permissions -rw-r--r--
separate configuration loading into the Loader class
franta-hg@146
     1
/**
franta-hg@146
     2
 * SQL-DK
franta-hg@146
     3
 * Copyright © 2014 František Kučera (frantovo.cz)
franta-hg@146
     4
 *
franta-hg@146
     5
 * This program is free software: you can redistribute it and/or modify
franta-hg@146
     6
 * it under the terms of the GNU General Public License as published by
franta-hg@146
     7
 * the Free Software Foundation, either version 3 of the License, or
franta-hg@146
     8
 * (at your option) any later version.
franta-hg@146
     9
 *
franta-hg@146
    10
 * This program is distributed in the hope that it will be useful,
franta-hg@146
    11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
franta-hg@146
    12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
franta-hg@146
    13
 * GNU General Public License for more details.
franta-hg@146
    14
 *
franta-hg@146
    15
 * You should have received a copy of the GNU General Public License
franta-hg@146
    16
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
franta-hg@146
    17
 */
franta-hg@146
    18
package info.globalcode.sql.dk.batch;
franta-hg@146
    19
franta-hg@146
    20
import info.globalcode.sql.dk.Parameter;
franta-hg@146
    21
import info.globalcode.sql.dk.SQLCommand;
franta-hg@146
    22
import info.globalcode.sql.dk.SQLCommandNumbered;
franta-hg@146
    23
import java.io.DataInputStream;
franta-hg@146
    24
import java.io.InputStream;
franta-hg@146
    25
import static info.globalcode.sql.dk.batch.BatchConstants.*;
franta-hg@146
    26
import static info.globalcode.sql.dk.Functions.toHex;
franta-hg@146
    27
import info.globalcode.sql.dk.SQLType;
franta-hg@146
    28
import java.io.IOException;
franta-hg@146
    29
import java.util.ArrayList;
franta-hg@146
    30
import java.util.Arrays;
franta-hg@146
    31
import java.util.List;
franta-hg@146
    32
franta-hg@146
    33
/**
franta-hg@146
    34
 *
franta-hg@146
    35
 * @author Ing. František Kučera (frantovo.cz)
franta-hg@146
    36
 */
franta-hg@146
    37
public class BatchDecoder {
franta-hg@146
    38
franta-hg@146
    39
	public Batch decode(InputStream in) throws BatchException {
franta-hg@146
    40
		return new BatchFromStream(new DataInputStream(in));
franta-hg@146
    41
	}
franta-hg@146
    42
franta-hg@146
    43
	private class BatchFromStream implements Batch {
franta-hg@146
    44
franta-hg@146
    45
		private DataInputStream in;
franta-hg@146
    46
		private boolean hasNext;
franta-hg@146
    47
franta-hg@146
    48
		public BatchFromStream(DataInputStream in) throws BatchException {
franta-hg@146
    49
			this.in = in;
franta-hg@146
    50
			hasNext = verifyHeader();
franta-hg@146
    51
		}
franta-hg@146
    52
franta-hg@146
    53
		@Override
franta-hg@146
    54
		public boolean hasNext() throws BatchException {
franta-hg@146
    55
			return hasNext;
franta-hg@146
    56
		}
franta-hg@146
    57
franta-hg@146
    58
		@Override
franta-hg@146
    59
		public SQLCommand next() throws BatchException {
franta-hg@146
    60
			try {
franta-hg@146
    61
				String sql = readNextString();
franta-hg@146
    62
franta-hg@146
    63
				int paramCount = in.readInt();
franta-hg@146
    64
				List<Parameter> parameters = new ArrayList<>(paramCount);
franta-hg@146
    65
franta-hg@146
    66
				for (int i = 0; i < paramCount; i++) {
franta-hg@146
    67
					SQLType type = SQLType.valueOf(in.readInt());
franta-hg@146
    68
					String value = readNextString();
franta-hg@146
    69
					parameters.add(new Parameter(value, type));
franta-hg@146
    70
				}
franta-hg@146
    71
franta-hg@146
    72
				hasNext = verifyHeader();
franta-hg@146
    73
franta-hg@146
    74
				SQLCommand sqlCommand = new SQLCommandNumbered(sql, parameters);
franta-hg@146
    75
				return sqlCommand;
franta-hg@146
    76
			} catch (IOException e) {
franta-hg@146
    77
				throw new BatchException("Unable to read batch", e);
franta-hg@146
    78
			}
franta-hg@146
    79
		}
franta-hg@146
    80
franta-hg@146
    81
		private String readNextString() throws IOException {
franta-hg@146
    82
			byte[] buffer = new byte[in.readInt()];
franta-hg@146
    83
			in.read(buffer);
franta-hg@146
    84
			return new String(buffer, CHARSET);
franta-hg@146
    85
		}
franta-hg@146
    86
franta-hg@146
    87
		/**
franta-hg@146
    88
		 * @return true if correct batch header was found | false if EOF was found
franta-hg@146
    89
		 * @throws BatchException if unexpected data was found (not batch header nor EOF)
franta-hg@146
    90
		 */
franta-hg@146
    91
		private boolean verifyHeader() throws BatchException {
franta-hg@146
    92
			try {
franta-hg@146
    93
				byte[] buffer = new byte[BATCH_HEADER.length];
franta-hg@146
    94
				int bytesRead = in.read(buffer);
franta-hg@146
    95
franta-hg@146
    96
				if (bytesRead == BATCH_HEADER.length && Arrays.equals(buffer, BATCH_HEADER)) {
franta-hg@146
    97
					return true;
franta-hg@146
    98
				} else if (bytesRead == -1) {
franta-hg@146
    99
					return false;
franta-hg@146
   100
				} else {
franta-hg@146
   101
					throw new BatchException("This is not SQL-DK batch: " + toHex(buffer));
franta-hg@146
   102
				}
franta-hg@146
   103
			} catch (IOException e) {
franta-hg@146
   104
				throw new BatchException("Unable to read batch header", e);
franta-hg@146
   105
			}
franta-hg@146
   106
		}
franta-hg@146
   107
	}
franta-hg@146
   108
}