/* * Licensed to Crate under one or more contributor license agreements. * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. Crate licenses this file * to you under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may * obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. * * However, if you have executed another commercial license agreement * with Crate these terms will supersede the license and you may use the * software solely pursuant to the terms of the relevant commercial * agreement. */ package io.crate.protocols.postgres; import io.crate.types.DataTypes; import org.apache.lucene.util.BytesRef; import org.jboss.netty.buffer.ChannelBuffer; import java.nio.charset.StandardCharsets; import java.util.List; /** * Class to encode postgres client messages and write them onto a buffer. * * For more information about the messages see {@link Messages} and {@link ConnectionContext} or refer to * the PostgreSQL protocol documentation. */ class ClientMessages { static void sendStartupMessage(ChannelBuffer buffer, String dbName) { byte[] dbKey = "database".getBytes(StandardCharsets.UTF_8); byte[] dbValue = dbName.getBytes(StandardCharsets.UTF_8); buffer.writeInt(8 + dbKey.length + 1 + dbValue.length + 1); buffer.writeInt(3); buffer.writeBytes(dbKey); buffer.writeByte(0); buffer.writeBytes(dbValue); buffer.writeByte(0); } static void sendParseMessage(ChannelBuffer buffer, String stmtName, String query, int[] paramOids) { buffer.writeByte('P'); byte[] stmtNameBytes = stmtName.getBytes(StandardCharsets.UTF_8); byte[] queryBytes = query.getBytes(StandardCharsets.UTF_8); buffer.writeInt( 4 + stmtNameBytes.length + 1 + queryBytes.length + 1 + 2 + paramOids.length * 4); writeCString(buffer, stmtNameBytes); writeCString(buffer, queryBytes); buffer.writeShort(paramOids.length); for (int paramOid : paramOids) { buffer.writeInt(paramOid); } } private static void writeCString(ChannelBuffer buffer, byte[] bytes) { buffer.writeBytes(bytes); buffer.writeByte(0); } static void sendFlush(ChannelBuffer buffer) { buffer.writeByte('H'); buffer.writeInt(4); } static void sendBindMessage(ChannelBuffer buffer, String portalName, String statementName, List<Object> params) { buffer.writeByte('B'); byte[] portalBytes = portalName.getBytes(StandardCharsets.UTF_8); byte[] statementBytes = statementName.getBytes(StandardCharsets.UTF_8); int beforeLengthWriterIndex = buffer.writerIndex(); buffer.writeInt(0); writeCString(buffer, portalBytes); writeCString(buffer, statementBytes); buffer.writeShort(0); // formatCode use 0 to default to text for all buffer.writeShort(params.size()); int paramsLength = 0; for (Object param : params) { BytesRef value = DataTypes.STRING.value(param); buffer.writeInt(value.length + 1); buffer.writeBytes(value.bytes, value.offset, value.length); buffer.writeByte(0); paramsLength += 4 + value.length + 1; } buffer.writeShort(0); // numResultFormatCodes - 0 to default to text for all buffer.setInt(beforeLengthWriterIndex, 4 + portalBytes.length + 1 + statementBytes.length + 1 + 2 + // numFormatCodes 2 + // numParams paramsLength + 2); // numResultColumnFormatCodes } }