1 5 package org.h2.index; 6 7 import java.sql.PreparedStatement ; 8 import java.sql.ResultSet ; 9 import java.sql.SQLException ; 10 11 import org.h2.engine.Constants; 12 import org.h2.engine.Session; 13 import org.h2.message.Message; 14 import org.h2.result.Row; 15 import org.h2.result.SearchRow; 16 import org.h2.table.Column; 17 import org.h2.table.TableLink; 18 import org.h2.value.Value; 19 import org.h2.value.ValueNull; 20 21 24 25 public class LinkedIndex extends Index { 26 27 private TableLink link; 28 private String originalTable; 29 30 public LinkedIndex(TableLink table, int id, Column[] columns, IndexType indexType) { 31 super(table, id, null, columns, indexType); 32 link = table; 33 originalTable = link.getOriginalTable(); 34 } 35 36 public String getCreateSQL() { 37 return null; 38 } 39 40 public void close(Session session) throws SQLException { 41 } 42 43 public void add(Session session, Row row) throws SQLException { 44 StringBuffer buff = new StringBuffer ("INSERT INTO "); 45 buff.append(originalTable); 46 buff.append(" VALUES("); 47 for(int i=0, j=0; i<row.getColumnCount(); i++) { 48 Value v = row.getValue(i); 49 if(j>0) { 50 buff.append(','); 51 } 52 j++; 53 if(v != null && v != ValueNull.INSTANCE) { 54 buff.append('?'); 55 } else { 56 buff.append("NULL"); 57 } 58 } 59 buff.append(')'); 60 String sql = buff.toString(); 61 try { 62 PreparedStatement prep = link.getPreparedStatement(sql); 63 for(int i=0, j=0; i<row.getColumnCount(); i++) { 64 Value v = row.getValue(i); 65 if(v != null && v != ValueNull.INSTANCE) { 66 v.set(prep, j+1); 67 j++; 68 } 69 } 70 prep.executeUpdate(); 71 rowCount++; 72 } catch(SQLException e) { 73 throw Message.getSQLException(Message.ERROR_ACCESSING_LINKED_TABLE_1, new String []{sql}, e); 74 } 75 } 76 77 public void remove(Session session, Row row) throws SQLException { 78 StringBuffer buff = new StringBuffer ("DELETE FROM "); 79 buff.append(originalTable); 80 buff.append(" WHERE "); 81 for(int i=0; i<row.getColumnCount(); i++) { 82 if(i>0) { 83 buff.append("AND "); 84 } 85 buff.append(table.getColumn(i).getSQL()); 86 buff.append("=? "); 87 } 88 String sql = buff.toString(); 89 try { 90 PreparedStatement prep = link.getPreparedStatement(sql); 91 for(int i=0, j=0; i<row.getColumnCount(); i++) { 92 Value v = row.getValue(i); 93 if(v != null) { 94 v.set(prep, j+1); 95 j++; 96 } 97 } 98 prep.executeUpdate(); 99 rowCount--; 100 } catch(SQLException e) { 101 throw Message.getSQLException(Message.ERROR_ACCESSING_LINKED_TABLE_1, new String []{sql}, e); 102 } 103 } 104 105 public Cursor find(Session session, SearchRow first, SearchRow last) throws SQLException { 106 StringBuffer buff = new StringBuffer (); 107 for(int i=0; first != null && i<first.getColumnCount(); i++) { 108 Value v = first.getValue(i); 109 if(v != null) { 110 if(buff.length() != 0) { 111 buff.append(" AND "); 112 } 113 buff.append(table.getColumn(i).getSQL()); 114 buff.append(">=?"); 115 } 116 } 117 for(int i=0; last != null && i<last.getColumnCount(); i++) { 118 Value v = last.getValue(i); 119 if(v != null) { 120 if(buff.length() != 0) { 121 buff.append(" AND "); 122 } 123 buff.append(table.getColumn(i).getSQL()); 124 buff.append("<=?"); 125 } 126 } 127 if(buff.length() > 0) { 128 buff.insert(0, " WHERE "); 129 } 130 buff.insert(0, "SELECT * FROM "+originalTable); 131 String sql = buff.toString(); 132 try { 133 PreparedStatement prep = link.getPreparedStatement(sql); 134 int j=0; 135 for(int i=0; first != null && i<first.getColumnCount(); i++) { 136 Value v = first.getValue(i); 137 if(v != null) { 138 v.set(prep, j+1); 139 j++; 140 } 141 } 142 for(int i=0; last != null && i<last.getColumnCount(); i++) { 143 Value v = last.getValue(i); 144 if(v != null) { 145 v.set(prep, j+1); 146 j++; 147 } 148 } 149 ResultSet rs = prep.executeQuery(); 150 return new LinkedCursor(table, rs, session); 151 } catch(SQLException e) { 152 throw Message.getSQLException(Message.ERROR_ACCESSING_LINKED_TABLE_1, new String []{sql}, e); 153 } 154 } 155 156 public int getLookupCost(int rowCount) { 157 for(int i=0, j = 1; ; i++) { 158 j *= 10; 159 if(j>rowCount) { 160 return i+1; 161 } 162 } 163 } 164 165 public int getCost(int[] masks) throws SQLException { 166 return 100 + getCostRangeIndex(masks, rowCount + Constants.COST_ROW_OFFSET); 167 } 168 169 public void remove(Session session) throws SQLException { 170 } 171 172 public void truncate(Session session) throws SQLException { 173 } 174 175 public void checkRename() throws SQLException { 176 throw Message.getUnsupportedException(); 177 } 178 179 public boolean needRebuild() { 180 return false; 181 } 182 183 public boolean canGetFirstOrLast(boolean first) { 184 return false; 185 } 186 187 public Value findFirstOrLast(Session session, boolean first) throws SQLException { 188 throw Message.getUnsupportedException(); 190 } 191 192 } 193 | Popular Tags |