1 29 30 package com.caucho.db.table; 31 32 import com.caucho.db.index.BTree; 33 import com.caucho.db.sql.QueryContext; 34 import com.caucho.db.store.Store; 35 import com.caucho.db.store.Transaction; 36 import com.caucho.sql.SQLExceptionWrapper; 37 import com.caucho.util.L10N; 38 39 import java.io.IOException ; 40 import java.sql.SQLException ; 41 42 45 public class UniqueSingleColumnConstraint extends Constraint { 46 private final static L10N L = new L10N(UniqueSingleColumnConstraint.class); 47 private final Column _uniqueColumn; 48 49 52 public UniqueSingleColumnConstraint(Column column) 53 { 54 _uniqueColumn = column; 55 } 56 57 60 public void validate(TableIterator []sourceRows, 61 QueryContext queryContext, Transaction xa) 62 throws SQLException 63 { 64 Column column = _uniqueColumn; 65 int columnOffset = column.getColumnOffset(); 66 67 BTree index = column.getIndex(); 68 69 if (index != null) { 70 validateIndex(sourceRows, queryContext, xa); 71 return; 72 } 73 74 TableIterator sourceRow = sourceRows[0]; 75 String value = null; 76 77 Table table = sourceRow.getTable(); 78 TableIterator iter = table.createTableIterator(); 79 80 try { 81 byte []sourceBuffer = sourceRow.getBuffer(); 82 int sourceOffset = sourceRow.getRowOffset(); 83 84 iter.init(queryContext); 85 86 while (iter.next()) { 87 byte []iterBuffer = iter.getBuffer(); 88 89 iter.prevRow(); 90 91 while (iter.nextRow()) { 92 int iterOffset = iter.getRowOffset(); 93 94 if (iterBuffer == sourceBuffer && iterOffset == sourceOffset) 95 continue; 96 97 if (column.isEqual(iterBuffer, iterOffset, 98 sourceBuffer, sourceOffset)) 99 throw new SQLException (L.l("`{0}' in {1}.{2} fails uniqueness constraint.", 100 column.getString(iterBuffer, iterOffset), 101 table.getName(), 102 column.getName())); 103 } 104 } 105 } catch (IOException e) { 106 throw new SQLExceptionWrapper(e); 107 } finally { 108 iter.free(); 109 } 110 } 111 112 115 private void validateIndex(TableIterator []sourceRows, 116 QueryContext context, Transaction xa) 117 throws SQLException 118 { 119 try { 120 Column column = _uniqueColumn; 121 TableIterator sourceRow = sourceRows[0]; 122 123 byte []sourceBuffer = sourceRow.getBuffer(); 124 int sourceOffset = sourceRow.getRowOffset(); 125 126 byte []buffer = context.getBuffer(); 127 128 BTree index = column.getIndex(); 129 130 141 142 int length = column.getLength(); 144 int offset = sourceOffset + _uniqueColumn.getColumnOffset(); 145 long value = index.lookup(sourceBuffer, offset, length, 146 context.getTransaction()); 147 148 if (value != 0) { 149 Table table = sourceRow.getTable(); 150 151 throw new SQLException (L.l("'{0}' in {1}.{2} fails uniqueness constraint with block address {3}.", 152 column.getString(sourceBuffer, 153 sourceOffset), 154 table.getName(), 155 column.getName(), 156 ("" + (value / Store.BLOCK_SIZE) 157 + "." + (value % Store.BLOCK_SIZE)))); 158 } 159 } catch (IOException e) { 160 throw new SQLExceptionWrapper(e); 161 } 162 } 163 } 164 | Popular Tags |