JAVA   48

MySQL extends SQL92

Guest on 11th May 2022 04:45:40 PM

  1. package de.fuberlin.wiwiss.d2rq.sql.vendor;
  2.  
  3. import java.math.BigInteger;
  4. import java.sql.ResultSet;
  5. import java.sql.SQLException;
  6. import java.sql.Types;
  7. import java.util.Properties;
  8. import java.util.regex.Pattern;
  9.  
  10. import de.fuberlin.wiwiss.d2rq.sql.Quoter;
  11. import de.fuberlin.wiwiss.d2rq.sql.Quoter.PatternDoublingQuoter;
  12. import de.fuberlin.wiwiss.d2rq.sql.types.DataType;
  13. import de.fuberlin.wiwiss.d2rq.sql.types.SQLBit;
  14. import de.fuberlin.wiwiss.d2rq.sql.types.SQLBoolean;
  15. import de.fuberlin.wiwiss.d2rq.sql.types.SQLDate;
  16. import de.fuberlin.wiwiss.d2rq.sql.types.SQLExactNumeric;
  17. import de.fuberlin.wiwiss.d2rq.sql.types.SQLTime;
  18. import de.fuberlin.wiwiss.d2rq.sql.types.SQLTimestamp;
  19.  
  20. /**
  21.  * This syntax class implements MySQL-compatible SQL syntax.
  22.  *
  23.  * @author Richard Cyganiak
  24.  */
  25. public class MySQL extends SQL92 {
  26.  
  27.         public MySQL() {
  28.                 super(true);
  29.         }
  30.        
  31.         @Override
  32.         public String getConcatenationExpression(String[] sqlFragments) {
  33.                 StringBuffer result = new StringBuffer("CONCAT(");
  34.                 for (int i = 0; i < sqlFragments.length; i++) {
  35.                         if (i > 0) {
  36.                                 result.append(", ");
  37.                         }
  38.                         result.append(sqlFragments[i]);
  39.                 }
  40.                 result.append(")");
  41.                 return result.toString();
  42.         }
  43.  
  44.         @Override
  45.         public String quoteIdentifier(String identifier) {
  46.                 return backtickEscaper.quote(identifier);
  47.         }
  48.         private final static Quoter backtickEscaper =
  49.                 new PatternDoublingQuoter(Pattern.compile("([\\\\`])"), "`");
  50.        
  51.         @Override
  52.         public String quoteStringLiteral(String s) {
  53.                 return singleQuoteEscaperWithBackslash.quote(s);
  54.         }
  55.         private final static Quoter singleQuoteEscaperWithBackslash =
  56.                 new PatternDoublingQuoter(Pattern.compile("([\\\\'])"), "'");
  57.        
  58.         @Override
  59.         public Properties getDefaultConnectionProperties() {
  60.                 Properties result = new Properties();
  61.                 result.setProperty("autoReconnect", "true");
  62.                 result.setProperty("zeroDateTimeBehavior", "convertToNull");
  63.                 return result;
  64.         }
  65.  
  66.         @Override
  67.         // TODO: The MySQL JDBC driver reports TINYINT(1) as BIT, should be handled as xsd:boolean?
  68.         public DataType getDataType(int jdbcType, String name, int size) {
  69.  
  70.                 // MySQL reports BIT columns in result sets as VARBINARY,
  71.                 // and formats the value as a number. This makes no sense.
  72.                 if (jdbcType == Types.VARBINARY && "BIT".equals(name)) {
  73.                         return new MySQLCompatibilityBitDataType(this);
  74.                 }
  75.                
  76.                 // TINYINT(1) is conventionally treated as BOOLEAN in MySQL.
  77.                 // MySQL reports TINYINT(1) either as Types.BIT with size 0,
  78.                 // or as Types.BIT with type name still TINYINT. All real BIT
  79.                 // types are reported with a size > 0.
  80.                 if (jdbcType == Types.BIT && ("TINYINT".equals(name) || size == 0)) {
  81.                         return new SQLBoolean(this, name);
  82.                 }
  83.  
  84.                 // MySQL supports UNSIGNED varieties of the integer types
  85.                 if (name.contains("UNSIGNED")) {
  86.                         return new SQLExactNumeric(this, name, jdbcType, true);
  87.                 }
  88.                
  89.                 // The MySQL driver chokes on some values that are supported by the
  90.                 // MySQL database but not by the corresponding Java objects.
  91.                 if (jdbcType == Types.DATE) {
  92.                         return new MySQLCompatibilityDateDataType(this);
  93.                 }
  94.                 if (jdbcType == Types.TIME) {
  95.                         return new MySQLCompatibilityTimeDataType(this);
  96.                 }
  97.                 if (jdbcType == Types.TIMESTAMP) {
  98.                         return new MySQLCompatibilityTimestampDataType(this);
  99.                 }
  100.                
  101.                 return super.getDataType(jdbcType, name, size);
  102.         }
  103.  
  104.         public static class MySQLCompatibilityBitDataType extends SQLBit {
  105.                 public MySQLCompatibilityBitDataType(Vendor syntax) {
  106.                         super(syntax, "BIT");
  107.                 }
  108.                 @Override
  109.                 public String value(ResultSet resultSet, int column) throws SQLException {
  110.                         String value = resultSet.getString(column);
  111.                         if (resultSet.wasNull()) return null;
  112.                         try {
  113.                                 // TODO: We would like to request the actual length of the bit type
  114.                                 // from the type descriptor, and only return the appropriate number
  115.                                 // of binary digits, but metaData.getPrecision() doesn't
  116.                                 // work on streaming result sets (because it requires opening
  117.                                 // a new result set internal to the JDBC driver). So any leading
  118.                                 // zeroes will be dropped.
  119.                                 return new BigInteger(value).toString(2);
  120.                         } catch (NumberFormatException ex) {
  121.                                 log.warn("Expected numeric, got '" + value + "'; treating as null");
  122.                                 return null;
  123.                         }
  124.                 }
  125.         }
  126.        
  127.         public static class MySQLCompatibilityDateDataType extends SQLDate {
  128.                 public MySQLCompatibilityDateDataType(Vendor syntax) {
  129.                         super(syntax, "DATE");
  130.                 }
  131.                 @Override
  132.                 public String value(ResultSet resultSet, int column) throws SQLException {
  133.                         // MySQL JDBC connector 5.1.18 chokes on the zero/error
  134.                         // value 0000-00-00 with a SQLException
  135.                         try {
  136.                                 return super.value(resultSet, column);
  137.                         } catch (SQLException ex) {
  138.                                 return null;
  139.                         }
  140.                 }
  141.         }
  142.        
  143.         public static class MySQLCompatibilityTimeDataType extends SQLTime {
  144.                 public MySQLCompatibilityTimeDataType(Vendor syntax) {
  145.                         super(syntax, "TIME");
  146.                 }
  147.                 @Override
  148.                 public String value(ResultSet resultSet, int column) throws SQLException {
  149.                         // MySQL JDBC connector 5.1.18 chokes on negative or too
  150.                         // large TIME values with a SQLException
  151.                         try {
  152.                                 return super.value(resultSet, column);
  153.                         } catch (SQLException ex) {
  154.                                 log.warn(ex);
  155.                                 return null;
  156.                         }
  157.                 }
  158.         }
  159.        
  160.         public static class MySQLCompatibilityTimestampDataType extends SQLTimestamp {
  161.                 public MySQLCompatibilityTimestampDataType(Vendor syntax) {
  162.                         super(syntax, "TIMESTAMP");
  163.                 }
  164.                 @Override
  165.                 public String value(ResultSet resultSet, int column) throws SQLException {
  166.                         // MySQL JDBC connector 5.1.18 chokes on the zero/error
  167.                         // value 0000-00-00 00:00:00 with a SQLException
  168.                         try {
  169.                                 return super.value(resultSet, column);
  170.                         } catch (SQLException ex) {
  171.                                 return null;
  172.                         }
  173.                 }
  174.         }
  175. }

Raw Paste


Login or Register to edit or fork this paste. It's free.