1 /* 2 * Copyright (C) 2019, HuntLabs 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 */ 17 18 module hunt.database.driver.postgresql.impl.codec.RowResultDecoder; 19 20 import hunt.database.driver.postgresql.impl.codec.DataFormat; 21 import hunt.database.driver.postgresql.impl.codec.DataType; 22 import hunt.database.driver.postgresql.impl.codec.DataTypeCodec; 23 import hunt.database.driver.postgresql.impl.codec.PgRowDesc; 24 import hunt.database.driver.postgresql.impl.codec.PgColumnDesc; 25 import hunt.database.driver.postgresql.impl.PostgreSQLRowImpl; 26 27 import hunt.database.base.Row; 28 import hunt.database.base.impl.RowDecoder; 29 import hunt.database.base.impl.RowSetImpl; 30 31 import hunt.Exceptions; 32 import hunt.Functions; 33 import hunt.logging; 34 import hunt.net.buffer.ByteBuf; 35 36 import std.variant; 37 38 /** 39 * 40 */ 41 class RowResultDecoder(R) : RowDecoder { 42 43 private int _size; 44 private RowSetImpl container; 45 private Row row; 46 private bool singleton; 47 PgRowDesc desc; 48 49 this(bool singleton, PgRowDesc desc) { 50 this.singleton = singleton; 51 this.desc = desc; 52 } 53 54 int size() { 55 return _size; 56 } 57 58 // override 59 void decodeRow(int len, ByteBuf buffer) { 60 if (container is null) { 61 container = new RowSetImpl(); 62 } 63 64 if (singleton) { 65 if (row is null) { 66 row = new PgRowImpl(desc); 67 } else { 68 row.clear(); 69 } 70 } else { 71 row = new PgRowImpl(desc); 72 } 73 74 version(HUNT_DB_DEBUG_MORE) infof("row: %d, size: %d", _size+1, len); 75 76 Row row = new PgRowImpl(desc); 77 for (int c = 0; c < len; ++c) { 78 int length = buffer.readInt(); 79 Variant decoded = null; 80 if (length != -1) { 81 PgColumnDesc columnDesc = desc.columns[c]; 82 83 version(HUNT_DB_DEBUG_MORE) { 84 tracef(" column[%d]: name=%s, %s, dataFormat=%s", 85 c, columnDesc.name, columnDesc.dataType, columnDesc.dataFormat); 86 } 87 88 if (columnDesc.dataFormat == DataFormat.BINARY) { 89 decoded = DataTypeCodec.decodeBinary(cast(DataType)columnDesc.dataType.id, 90 buffer.readerIndex(), length, buffer); 91 } else { 92 decoded = DataTypeCodec.decodeText(cast(DataType)columnDesc.dataType.id, 93 buffer.readerIndex(), length, buffer); 94 } 95 96 version(HUNT_DB_DEBUG_MORE) { 97 tracef(" colum[%d]: value=%s", c, decoded.toString()); 98 } 99 100 buffer.skipBytes(length); 101 } 102 row.addValue(decoded); 103 } 104 container.append(row); 105 _size++; 106 } 107 108 R complete() { 109 if (container is null) { 110 container = new RowSetImpl(); 111 } 112 return container; 113 } 114 115 void reset() { 116 container = null; 117 _size = 0; 118 } 119 }