0
|
1 /* Copyright (c) 2012 Tomislav Gountchev <tomi@gountchev.net> */
|
|
2
|
|
3 package jdbcpgbackup;
|
|
4
|
|
5 import java.sql.Connection;
|
|
6 import java.sql.PreparedStatement;
|
|
7 import java.sql.ResultSet;
|
|
8 import java.sql.SQLException;
|
|
9 import java.util.ArrayList;
|
|
10 import java.util.List;
|
|
11
|
|
12 class Index extends DbBackupObject {
|
|
13
|
|
14 static class IndexFactory implements DBOFactory<Index> {
|
|
15
|
|
16 @Override
|
|
17 public Iterable<Index> getDbBackupObjects(Connection con, Schema schema) throws SQLException {
|
|
18 List<Index> indexes = new ArrayList<Index>();
|
|
19 PreparedStatement stmt = null;
|
|
20 try {
|
|
21 stmt = con.prepareStatement(
|
|
22 // "SELECT * FROM pg_indexes WHERE schemaname = ?");
|
|
23 // duplicate the pg_indexes view definition but skipping the primary indexes
|
|
24 "SELECT c.relname AS tablename, i.relname AS indexname, " +
|
|
25 "pg_get_indexdef(i.oid) AS indexdef " +
|
|
26 "FROM pg_index x " +
|
|
27 "JOIN pg_class c ON c.oid = x.indrelid " +
|
|
28 "JOIN pg_class i ON i.oid = x.indexrelid " +
|
|
29 //"LEFT JOIN pg_namespace n ON n.oid = c.relnamespace " +
|
|
30 //"LEFT JOIN pg_tablespace t ON t.oid = i.reltablespace " +
|
|
31 "WHERE c.relkind = 'r'::\"char\" AND i.relkind = 'i'::\"char\" " +
|
|
32 "AND NOT x.indisprimary AND c.relnamespace = ?");
|
|
33 stmt.setInt(1, schema.getOid());
|
|
34 ResultSet rs = stmt.executeQuery();
|
|
35 while (rs.next()) {
|
|
36 indexes.add(new Index(rs.getString("indexname"), schema, rs.getString("tablename"), rs.getString("indexdef")));
|
|
37 }
|
|
38 rs.close();
|
|
39 } finally {
|
|
40 if (stmt != null) stmt.close();
|
|
41 }
|
|
42
|
|
43 /*// too slow, get primary keys from pg_constraint instead, use pg_get_constraintdef()
|
|
44 ZipBackup.timerStart("primary keys");
|
|
45 DatabaseMetaData metaData = con.getMetaData();
|
|
46 rs = metaData.getPrimaryKeys(null, schema.getName(), null);
|
|
47 Map<String,PrimaryKey> pkeys = new HashMap<String,PrimaryKey>();
|
|
48 while (rs.next()) {
|
|
49 String tableName = rs.getString("TABLE_NAME");
|
|
50 String indexName = rs.getString("PK_NAME");
|
|
51 PrimaryKey pkey = pkeys.get(indexName);
|
|
52 if (pkey == null) {
|
|
53 pkey = new PrimaryKey(indexName, schema, tableName);
|
|
54 pkeys.put(indexName, pkey);
|
|
55 }
|
|
56 pkey.columns.put(Integer.valueOf(rs.getInt("KEY_SEQ")), rs.getString("COLUMN_NAME"));
|
|
57 }
|
|
58 rs.close();
|
|
59 indexes.addAll(pkeys.values());
|
|
60 ZipBackup.timerEnd("primary keys");
|
|
61 */
|
|
62 return indexes;
|
|
63 }
|
|
64
|
|
65 @Override
|
|
66 public Index getDbBackupObject(Connection con, String indexName, Schema schema) throws SQLException {
|
|
67 Index index = null;
|
|
68 PreparedStatement stmt = null;
|
|
69 try {
|
|
70 stmt = con.prepareStatement("SELECT * FROM pg_indexes WHERE schemaname = ? " +
|
|
71 "AND indexname = ?");
|
|
72 stmt.setString(1, schema.getName());
|
|
73 stmt.setString(2, indexName);
|
|
74 ResultSet rs = stmt.executeQuery();
|
|
75 if (rs.next()) {
|
|
76 index = new Index(rs.getString("indexname"), schema, rs.getString("tablename"), rs.getString("indexdef"));
|
|
77 } else {
|
|
78 throw new RuntimeException("no such index: " + indexName);
|
|
79 }
|
|
80 rs.close();
|
|
81 } finally {
|
|
82 if (stmt != null) stmt.close();
|
|
83 }
|
|
84 return index;
|
|
85 }
|
|
86 }
|
|
87
|
|
88 static class CachingIndexFactory extends CachingDBOFactory<Index> {
|
|
89
|
|
90 private final Table.CachingTableFactory tableFactory;
|
|
91
|
|
92 protected CachingIndexFactory(Schema.CachingSchemaFactory schemaFactory, Table.CachingTableFactory tableFactory) {
|
|
93 super(schemaFactory);
|
|
94 this.tableFactory = tableFactory;
|
|
95 }
|
|
96
|
|
97 @Override
|
|
98 protected PreparedStatement getAllStatement(Connection con) throws SQLException {
|
|
99 return con.prepareStatement(
|
|
100 "SELECT x.indrelid AS table_oid, i.relname AS indexname, " +
|
|
101 "pg_get_indexdef(i.oid) AS indexdef, " +
|
|
102 "i.relnamespace AS schema_oid " +
|
|
103 "FROM pg_index x " +
|
|
104 "JOIN pg_class i ON i.oid = x.indexrelid " +
|
|
105 "WHERE i.relkind = 'i'::\"char\" " +
|
|
106 "AND NOT x.indisprimary ");
|
|
107 }
|
|
108
|
|
109 @Override
|
|
110 protected Index newDbBackupObject(Connection con, ResultSet rs, Schema schema) throws SQLException {
|
|
111 Table table = tableFactory.getTable(rs.getInt("table_oid"));
|
|
112 return new Index(rs.getString("indexname"), schema, table.getName(), rs.getString("indexdef"));
|
|
113 }
|
|
114
|
|
115 }
|
|
116
|
|
117 protected final String tableName;
|
|
118 private final String definition;
|
|
119
|
|
120 private Index(String name, Schema schema, String tableName, String definition) {
|
|
121 super(name, schema, null); // no owner (always same as table)
|
|
122 this.tableName = tableName;
|
|
123 this.definition = definition;
|
|
124 }
|
|
125
|
|
126 @Override
|
|
127 String getSql(DataFilter dataFilter) {
|
|
128 return definition.replace(" ON " + schema.getName() + ".", " ON ") + " ;\n"; // remove schema name
|
|
129 }
|
|
130
|
|
131 @Override
|
|
132 protected StringBuilder appendCreateSql(StringBuilder buf) {
|
|
133 throw new UnsupportedOperationException();
|
|
134 }
|
|
135
|
|
136 /* not used because too slow getting them
|
|
137 private final static class PrimaryKey extends Index {
|
|
138
|
|
139 private SortedMap<Integer,String> columns = new TreeMap<Integer,String>();
|
|
140
|
|
141 private PrimaryKey(String name, Schema schema, String tableName) {
|
|
142 super(name, schema, tableName, null);
|
|
143 }
|
|
144
|
|
145 @Override
|
|
146 public String getSql() {
|
|
147 StringBuilder buf = new StringBuilder();
|
|
148 buf.append("ALTER TABLE ");
|
|
149 buf.append(tableName);
|
|
150 buf.append(" ADD CONSTRAINT ");
|
|
151 buf.append(name);
|
|
152 buf.append(" PRIMARY KEY (");
|
|
153 for (String column : columns.values()) {
|
|
154 buf.append(column);
|
|
155 buf.append(",");
|
|
156 }
|
|
157 buf.deleteCharAt(buf.length()-1);
|
|
158 buf.append(");\n");
|
|
159 return buf.toString();
|
|
160 }
|
|
161
|
|
162 }
|
|
163 */
|
|
164
|
|
165 }
|