1 28 29 package com.caucho.db.table; 30 31 import com.caucho.db.index.BTree; 32 import com.caucho.db.sql.Expr; 33 import com.caucho.db.sql.QueryContext; 34 import com.caucho.db.sql.SelectResult; 35 import com.caucho.db.store.Transaction; 36 import com.caucho.util.CharBuffer; 37 38 import java.sql.SQLException ; 39 40 43 class NumericColumn extends Column { 44 private int _precision; 45 private int _scale; 46 private long _offset; 47 48 54 NumericColumn(Row row, String name, int precision, int scale) 55 { 56 super(row, name); 57 58 _precision = precision; 59 _scale = scale; 60 61 _offset = 1; 62 63 for (int i = 0; i < scale; i++) 64 _offset *= 10; 65 } 66 67 70 public int getTypeCode() 71 { 72 return NUMERIC; 73 } 74 75 78 public int getPrecision() 79 { 80 return _precision; 81 } 82 83 86 public int getScale() 87 { 88 return _scale; 89 } 90 91 94 public Class getJavaType() 95 { 96 return double.class; 97 } 98 99 102 public int getDeclarationSize() 103 { 104 return 8; 105 } 106 107 110 public int getLength() 111 { 112 return 8; 113 } 114 115 122 void setString(Transaction xa, byte []block, int rowOffset, String str) 123 throws SQLException 124 { 125 if (str == null || str.length() == 0) 126 setNull(block, rowOffset); 127 else 128 setDouble(xa, block, rowOffset, Double.parseDouble(str)); 129 } 130 131 137 public String getString(byte []block, int rowOffset) 138 throws SQLException 139 { 140 if (isNull(block, rowOffset)) 141 return null; 142 else { 143 long value = getNumeric(block, rowOffset); 144 145 CharBuffer cb = new CharBuffer(); 146 147 long head = value / _offset; 148 long tail = value % _offset; 149 150 cb.append(head); 151 cb.append('.'); 152 cb.append(tail); 153 154 return cb.toString(); 155 } 156 } 157 158 165 public void setDouble(Transaction xa, byte []block, int rowOffset, double v) 166 throws SQLException 167 { 168 setNumeric(xa, block, rowOffset, (long) (v * _offset + 0.5)); 169 } 170 171 178 public double getDouble(Transaction xa, byte []block, int rowOffset) 179 throws SQLException 180 { 181 return (double) getNumeric(block, rowOffset) / _offset; 182 } 183 184 187 public void evalToResult(byte []block, int rowOffset, SelectResult result) 188 throws SQLException 189 { 190 if (isNull(block, rowOffset)) { 191 result.writeNull(); 192 return; 193 } 194 195 result.writeString(getString(block, rowOffset)); 196 } 197 198 208 int evalToBuffer(byte []block, int rowOffset, 209 byte []buffer, int bufferOffset) 210 throws SQLException 211 { 212 if (isNull(block, rowOffset)) 213 return 0; 214 215 int startOffset = rowOffset + _columnOffset; 216 int len = 8; 217 218 System.arraycopy(block, startOffset, buffer, bufferOffset, len); 219 220 return len; 221 } 222 223 230 void setExpr(Transaction xa, 231 byte []block, int rowOffset, 232 Expr expr, QueryContext context) 233 throws SQLException 234 { 235 if (expr.isNull(null)) 236 setNull(block, rowOffset); 237 else 238 setDouble(xa, block, rowOffset, expr.evalDouble(context)); 239 } 240 241 244 public boolean isEqual(byte []block1, int rowOffset1, 245 byte []block2, int rowOffset2) 246 { 247 if (isNull(block1, rowOffset1) != isNull(block2, rowOffset2)) 248 return false; 249 250 int startOffset1 = rowOffset1 + _columnOffset; 251 int startOffset2 = rowOffset2 + _columnOffset; 252 253 return (block1[startOffset1 + 0] == block2[startOffset2 + 0] && 254 block1[startOffset1 + 1] == block2[startOffset2 + 1] && 255 block1[startOffset1 + 2] == block2[startOffset2 + 2] && 256 block1[startOffset1 + 3] == block2[startOffset2 + 3] && 257 block1[startOffset1 + 4] == block2[startOffset2 + 4] && 258 block1[startOffset1 + 5] == block2[startOffset2 + 5] && 259 block1[startOffset1 + 6] == block2[startOffset2 + 6] && 260 block1[startOffset1 + 7] == block2[startOffset2 + 7]); 261 } 262 263 270 void setIndex(Transaction xa, 271 byte []block, int rowOffset, 272 long rowAddr, QueryContext context) 273 throws SQLException 274 { 275 BTree index = getIndex(); 276 277 if (index == null) 278 return; 279 280 index.insert(block, rowOffset + _columnOffset, 8, rowAddr, xa, false); 281 } 282 283 286 public void set(TableIterator iter, Expr expr, QueryContext context) 287 throws SQLException 288 { 289 iter.setDirty(); 290 setDouble(iter.getTransaction(), iter.getBuffer(), iter.getRowOffset(), 291 expr.evalDouble(context)); 292 } 293 294 301 void delete(Transaction xa, byte []block, int rowOffset) 302 throws SQLException 303 { 304 BTree index = getIndex(); 305 306 if (index != null) 307 index.remove(block, rowOffset + _columnOffset, 8, xa); 308 } 309 310 317 void setNumeric(Transaction xa, byte []block, int rowOffset, long value) 318 { 319 int offset = rowOffset + _columnOffset; 320 321 block[offset++] = (byte) (value >> 56); 322 block[offset++] = (byte) (value >> 48); 323 block[offset++] = (byte) (value >> 40); 324 block[offset++] = (byte) (value >> 32); 325 block[offset++] = (byte) (value >> 24); 326 block[offset++] = (byte) (value >> 16); 327 block[offset++] = (byte) (value >> 8); 328 block[offset++] = (byte) (value); 329 330 setNonNull(block, rowOffset); 331 } 332 333 339 long getNumeric(byte []block, int rowOffset) 340 { 341 if (isNull(block, rowOffset)) 342 return 0; 343 344 int offset = rowOffset + _columnOffset; 345 long value = 0; 346 347 value = (block[offset++] & 0xffL) << 56; 348 value |= (block[offset++] & 0xffL) << 48; 349 value |= (block[offset++] & 0xffL) << 40; 350 value |= (block[offset++] & 0xffL) << 32; 351 value |= (block[offset++] & 0xffL) << 24; 352 value |= (block[offset++] & 0xffL) << 16; 353 value |= (block[offset++] & 0xffL) << 8; 354 value |= (block[offset++] & 0xffL); 355 356 return value; 357 } 358 } 359 | Popular Tags |