2019独角兽企业重金招聘Python工程师标准>>>
postgresql jdbc 连接到postgresql 数据库时,postgresql数据库会返回一些参数来设置jdbc。postgresql 是通过发送类型为S的数据包给客户端的。本文主要讲解jdbc中针对哪些参数进行了使用。
通过搜索jdbc的源码,可以找到只有三个函数中针对参数进行了处理,这三个函数分别为:readStartupMessages,processCopyResults,processResults。第一个函数是处理建立连接时的数据包的。第二个参数从名字看应该是处理copy功能时的函数。第三个参数处理的大部分操作的数据包。
在这三个函数中,readStartupMessages函数处理的参数分别为:server_version_num,client_encoding,standard_conforming_strings,integer_datetimes。processCopyResults和processResults函数中只处理了client_encoding,DateStyle,standard_conforming_strings这三个参数,其他的参数都被忽略掉了。
但是从9.4的postgresql数据库的通信看,传递了很多参数给客户端,下面是通过jdbc的调试功能得到的数据库端设置jdbc端的参数情况:
<=BE ParameterStatus(application_name = )
<=BE ParameterStatus(client_encoding = UTF8)
<=BE ParameterStatus(DateStyle = ISO, YMD)
<=BE ParameterStatus(integer_datetimes = on)
<=BE ParameterStatus(IntervalStyle = postgres)
<=BE ParameterStatus(is_superuser = on)
<=BE ParameterStatus(server_encoding = UTF8)
<=BE ParameterStatus(server_version = 9.4.4)
<=BE ParameterStatus(session_authorization = db_user)
<=BE ParameterStatus(standard_conforming_strings = on)
<=BE ParameterStatus(TimeZone = Asia/Shanghai)
<=BE BackendKeyData(pid=22833,ckey=1140395019)
上面参数中integer_datetimes如果为on,则代表日期可以使用double类型来进行通信。standard_conforming_strings则是针对字符串的处理的设置。如果为on,则不把\当做转义。
下面是上述三个函数的详细代码:
readStartupMessages
case 'S':
// ParameterStatus
int l_len = pgStream.ReceiveInteger4();
String name = pgStream.ReceiveString();
String value = pgStream.ReceiveString();
if (logger.logDebug())
logger.debug(" <=BE ParameterStatus(" + name + " = " + value + ")");
if (name.equals("server_version_num"))
protoConnection.setServerVersionNum(Integer.parseInt(value));
if (name.equals("server_version"))
protoConnection.setServerVersion(value);
else if (name.equals("client_encoding"))
{
if (!value.equals("UTF8"))
throw new PSQLException(GT.tr("Protocol error. Session setup failed."), PSQLState.PROTOCOL_VIOLATION);
pgStream.setEncoding(Encoding.getDatabaseEncoding("UTF8"));
}
else if (name.equals("standard_conforming_strings"))
{
if (value.equals("on"))
protoConnection.setStandardConformingStrings(true);
else if (value.equals("off"))
protoConnection.setStandardConformingStrings(false);
else
throw new PSQLException(GT.tr("Protocol error. Session setup failed."), PSQLState.PROTOCOL_VIOLATION);
}
else if (name.equals("integer_datetimes"))
{
if (value.equals("on"))
protoConnection.setIntegerDateTimes(true);
else if (value.equals("off"))
protoConnection.setIntegerDateTimes(false);
else
throw new PSQLException(GT.tr("Protocol error. Session setup failed."), PSQLState.PROTOCOL_VIOLATION);
}
break;
processCopyResults:
case 'S': // Parameter Status
{
int l_len = pgStream.ReceiveInteger4();
String name = pgStream.ReceiveString();
String value = pgStream.ReceiveString();
if (logger.logDebug())
logger.debug(" <=BE ParameterStatus(" + name + " = " + value + ")");
if (name.equals("client_encoding") && !value.equalsIgnoreCase("UTF8") && !allowEncodingChanges)
{
protoConnection.close(); // we're screwed now; we can't trust any subsequent string.
error = new PSQLException(GT.tr("The server''s client_encoding parameter was changed to {0}. The JDBC driver requires client_encoding to be UTF8 for correct operation.", value), PSQLState.CONNECTION_FAILURE);
endReceiving = true;
}
if (name.equals("DateStyle") && !value.startsWith("ISO,"))
{
protoConnection.close(); // we're screwed now; we can't trust any subsequent date.
error = new PSQLException(GT.tr("The server''s DateStyle parameter was changed to {0}. The JDBC driver requires DateStyle to begin with ISO for correct operation.", value), PSQLState.CONNECTION_FAILURE);
endReceiving = true;
}
if (name.equals("standard_conforming_strings"))
{
if (value.equals("on"))
protoConnection.setStandardConformingStrings(true);
else if (value.equals("off"))
protoConnection.setStandardConformingStrings(false);
else
{
protoConnection.close(); // we're screwed now; we don't know how to escape string literals
error = new PSQLException(GT.tr("The server''s standard_conforming_strings parameter was reported as {0}. The JDBC driver expected on or off.", value), PSQLState.CONNECTION_FAILURE);
endReceiving = true;
}
}
}
processResults
case 'S': // Parameter Status
{
int l_len = pgStream.ReceiveInteger4();
String name = pgStream.ReceiveString();
String value = pgStream.ReceiveString();
if (logger.logDebug())
logger.debug(" <=BE ParameterStatus(" + name + " = " + value + ")");
if (name.equals("client_encoding") && !value.equalsIgnoreCase("UTF8") && !allowEncodingChanges)
{
protoConnection.close(); // we're screwed now; we can't trust any subsequent string.
handler.handleError(new PSQLException(GT.tr("The server''s client_encoding parameter was changed to {0}. The JDBC driver requires client_encoding to be UTF8 for correct operation.", value), PSQLState.CONNECTION_FAILURE));
endQuery = true;
}
if (name.equals("DateStyle") && !value.startsWith("ISO,"))
{
protoConnection.close(); // we're screwed now; we can't trust any subsequent date.
handler.handleError(new PSQLException(GT.tr("The server''s DateStyle parameter was changed to {0}. The JDBC driver requires DateStyle to begin with ISO for correct operation.", value), PSQLState.CONNECTION_FAILURE));
endQuery = true;
}
if (name.equals("standard_conforming_strings"))
{
if (value.equals("on"))
protoConnection.setStandardConformingStrings(true);
else if (value.equals("off"))
protoConnection.setStandardConformingStrings(false);
else
{
protoConnection.close(); // we're screwed now; we don't know how to escape string literals
handler.handleError(new PSQLException(GT.tr("The server''s standard_conforming_strings parameter was reported as {0}. The JDBC driver expected on or off.", value), PSQLState.CONNECTION_FAILURE));
endQuery = true;
}
}
}