SQL_PREPARED_STATEMENT_GENERATED_FROM_NONCONSTANT_STRING: Invoke nextval() using...
[cfb.git] / prod / net / jaekl / cfb / db / driver / PostgresqlDriver.java
1 package net.jaekl.cfb.db.driver;
2
3 // Copyright (C) 2015 Christian Jaekl
4
5 import java.sql.Connection;
6 import java.sql.DriverManager;
7 import java.sql.PreparedStatement;
8 import java.sql.ResultSet;
9 import java.sql.SQLException;
10 import java.util.Properties;
11
12 import net.jaekl.cfb.db.Sequence;
13 import net.jaekl.cfb.db.Column.Type;
14
15 public class PostgresqlDriver extends DbDriver {
16
17         @Override
18         public void load() throws ClassNotFoundException {
19                 // This should no longer be necessary, so long as we're using 
20                 // JDBC 4 (which came out with JDK 6) and an updated driver.
21                 // But, it shouldn't hurt, either.
22                 Class.forName("org.postgresql.Driver");
23         }
24
25         @Override
26         public Connection connect(String host, int port, String dbName, String user, String pass) throws SQLException {
27                 String url = "jdbc:postgresql://" + host + ":" + port + "/" + dbName;
28                 Properties props = new Properties();
29                 props.setProperty("user", user);
30                 props.setProperty("password", pass);
31                 //props.setProperty("ssl", "true");
32                 return DriverManager.getConnection(url, props);
33         }
34         
35         @Override 
36         public long nextVal(Connection con, Sequence seq) throws SQLException
37         {
38                 String sql = " SELECT NEXTVAL(?) ";
39                 
40                 try (PreparedStatement ps = con.prepareStatement(sql)) 
41                 {
42                         ps.setString(1, seq.getName());
43                         
44                         try (ResultSet rs = ps.executeQuery()) {
45                                 if (rs.next()) {
46                                         return rs.getLong(1);
47                                 }
48                         }
49                 }
50                 
51                 throw new SQLException("No value returned for sequence:  " + sql);
52         }
53         
54         
55         @Override
56         protected String typeName(Type type) {
57                 // Special case:  TIMESTAMPTZ stored as INTEGER (milliseconds since the epoch)
58                 // Reading a TIMESTAMPTZ back from the DB, and converting it to a java.util.Date,
59                 // is fraught with peril.  The best way around this is to store the dates in 
60                 // milliseconds-since-the-epoch (01.01.1970 00:00:00.000 UTC).
61                 if (Type.TIMESTAMPTZ.equals(type)) {
62                         return "BIGINT";
63                 }
64                 
65                 return type.toString();
66         }}