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