/xbird-db/main/test/junk/xbird/util/jdbc/impl/PGAccessor.java

http://xbird.googlecode.com/ · Java · 162 lines · 91 code · 17 blank · 54 comment · 18 complexity · 36fa9e25a82020be9e5a19ed5280401c MD5 · raw file

  1. /*
  2. * @(#)$Id: PGAccessor.java 3619 2008-03-26 07:23:03Z yui $
  3. *
  4. * Copyright 2006-2008 Makoto YUI
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * Contributors:
  19. * Makoto YUI - initial implementation
  20. */
  21. package xbird.util.jdbc.impl;
  22. import java.sql.SQLException;
  23. import org.apache.commons.logging.Log;
  24. import org.apache.commons.logging.LogFactory;
  25. import xbird.util.jdbc.*;
  26. import xbird.util.jdbc.helper.QueryRunnerFactory;
  27. /**
  28. * This is a utility class managing a database connection.
  29. * <DIV lang="en"></DIV>
  30. * <DIV lang="ja"></DIV>
  31. *
  32. * @author Makoto YUI <yuin405+xbird@gmail.com>
  33. */
  34. public class PGAccessor extends DBAccessor {
  35. private static final Log LOG = LogFactory.getLog(PGAccessor.class);
  36. public PGAccessor() {
  37. super();
  38. }
  39. public String getDatabaseName() {
  40. return "postgres";
  41. }
  42. /**
  43. * Escapes SQL String.
  44. */
  45. public final String escapeString(String inputString) {
  46. int strlen = inputString.length();
  47. if(strlen == 0)
  48. return null;
  49. int len = 2 + strlen + (strlen / 10);
  50. // make enough buffer
  51. StringBuffer output = new StringBuffer(len);
  52. for(int i = 0; i < strlen; ++i) {
  53. char c = inputString.charAt(i);
  54. switch(c) {
  55. case '\\':
  56. case '\'':
  57. output.append('\\');
  58. output.append(c);
  59. break;
  60. case '\n':
  61. output.append("\\n");
  62. case '\t':
  63. output.append("\\t");
  64. break;
  65. case '\0':
  66. throw new IllegalArgumentException("\\0 not allowed");
  67. default:
  68. output.append(c);
  69. }
  70. }
  71. return output.toString();
  72. }
  73. /**
  74. * This is just a wrapper method to
  75. * <code>org.postgresql.util.PGbytea.toPGString()</code>.
  76. * if exception caused, return null.
  77. *
  78. * representation between Java Byte Array and Postgres Bytea is different.
  79. * see detail on <code>org.postgresql.util.PGbytea.toPGString()</code>
  80. *
  81. * @return PG bytea string of the specified byte array.
  82. */
  83. public final String toBytea(byte[] b) {
  84. return toPGString(b);
  85. }
  86. /**
  87. * Converts a java byte[] into a PG bytea string (i.e. the text
  88. * representation of the bytea data type)
  89. */
  90. private static String toPGString(byte[] p_buf) {
  91. if(p_buf == null)
  92. return null;
  93. StringBuffer l_strbuf = new StringBuffer(2 * p_buf.length);
  94. for(int i = 0; i < p_buf.length; i++) {
  95. int l_int = (int) p_buf[i];
  96. if(l_int < 0) {
  97. l_int = 256 + l_int;
  98. }
  99. //we escape the same non-printable characters as the backend
  100. //we must escape all 8bit characters otherwise when convering
  101. //from java unicode to the db character set we may end up with
  102. //question marks if the character set is SQL_ASCII
  103. if(l_int < 040 || l_int > 0176) {
  104. //escape charcter with the form \000, but need two \\ because of
  105. //the parser
  106. l_strbuf.append("\\");
  107. l_strbuf.append((char) (((l_int >> 6) & 0x3) + 48));
  108. l_strbuf.append((char) (((l_int >> 3) & 0x7) + 48));
  109. l_strbuf.append((char) ((l_int & 0x07) + 48));
  110. } else if(p_buf[i] == (byte) '\\') {
  111. //escape the backslash character as \\, but need four \\\\ because
  112. //of the parser
  113. l_strbuf.append("\\\\");
  114. } else {
  115. //other characters are left alone
  116. l_strbuf.append((char) p_buf[i]);
  117. }
  118. }
  119. return l_strbuf.toString();
  120. }
  121. public boolean supportsForUpdate() {
  122. return true;
  123. }
  124. public boolean supportsForBulkload() {
  125. return true;
  126. }
  127. public BulkLoader getBulkLoader() {
  128. return PGLoader.INSTANCE;
  129. }
  130. protected static class PGLoader implements BulkLoader {
  131. private static final PGLoader INSTANCE = new PGLoader();
  132. private static final QueryRunner queryRunner = QueryRunnerFactory.create();
  133. private PGLoader() {}
  134. public void importTable(String tableName, String file) throws SQLException {
  135. if(tableName == null || file == null) {
  136. throw new IllegalArgumentException("Arguments MUST be non-null value.");
  137. }
  138. final String sql = "COPY " + tableName + " FROM '" + file + "'" + " WITH DELIMITER '"
  139. + COLUMN_DELIMITER + "'";
  140. int count = queryRunner.update(sql);
  141. if(LOG.isInfoEnabled())
  142. LOG.info("update the table '" + tableName + "' (" + count + ") successfully.");
  143. }
  144. }
  145. }