1 package com.quadcap.sql.types; 2 3 40 41 import java.io.ByteArrayInputStream ; 42 import java.io.Externalizable ; 43 import java.io.IOException ; 44 import java.io.InputStream ; 45 import java.io.ObjectInput ; 46 import java.io.ObjectOutput ; 47 import java.io.Reader ; 48 import java.io.StringReader ; 49 50 import java.sql.Types ; 51 52 import com.quadcap.sql.io.Extern; 53 import com.quadcap.sql.io.Externable; 54 import com.quadcap.sql.io.ExternalizeProxy; 55 import com.quadcap.sql.io.ExternProxyString; 56 57 import com.quadcap.util.Debug; 58 59 64 public class ValueString extends Value 65 implements Externalizable , ExternalizeProxy, Externable 66 { 67 static ExternProxyString proxy = new ExternProxyString(); 68 69 String val; 70 71 74 public ValueString() {} 75 76 79 public ValueString(boolean quoted, String val) { 80 if (quoted) { 81 boolean quote = false; 82 StringBuffer sb = new StringBuffer (); 83 for (int i = 1; i < val.length() - 1; i++) { 84 char c = val.charAt(i); 85 if (c == '\'') { 86 if (!quote) { 87 sb.append(c); 88 quote = true; 89 } else { 90 quote = false; 91 } 92 } else { 93 quote = false; 94 sb.append(c); 95 } 96 } 97 this.val = sb.toString(); 98 } else { 99 this.val = val; 100 } 101 } 102 103 106 public ValueString(String val) { this.val = val; } 107 108 111 public String stringValue() { return val; } 112 113 116 public String toString() { 117 return "'" + val + "'"; 118 } 119 120 123 public Value unop(int op) throws ValueException { 124 switch (op) { 125 case Op.NULL: return ValueBoolean.falseBoolean; 127 case Op.PATTERN: return new ValuePattern(val, ValuePattern.defaultEscape); 129 default: 130 throw new ValueException("Unary op: " + Op.toString(op) + 131 " not implemented for this type"); 132 } 133 } 134 135 138 public Value binop(int op, Value l) throws ValueException { 139 return l.binop(op, this); 140 } 141 142 145 public Value binop(int op, ValueDate r) throws ValueException { 146 try { 147 return ValueDateTime.binop(op, new ValueDate(val), r); 148 } catch (antlr.RecognitionException e) { 149 throw new ValueException("Not a date: " + val); 150 } 151 } 152 153 156 public Value binop(int op, ValueTime r) throws ValueException { 157 try { 158 return ValueDateTime.binop(op, new ValueTime(val), r); 159 } catch (antlr.RecognitionException e) { 160 throw new ValueException("Not a date: " + val); 161 } 162 } 163 164 167 public Value binop(int op, ValueTimestamp r) throws ValueException { 168 try { 169 return ValueDateTime.binop(op, new ValueTimestamp(val), r); 170 } catch (antlr.RecognitionException e) { 171 throw new ValueException("Not a date: " + val); 172 } 173 } 174 175 178 public Value binop(int op, ValueNull r) throws ValueException { 179 switch (op) { 180 case Op.EQ: 181 case Op.NE: 182 case Op.LT: 183 case Op.LE: 184 case Op.GT: 185 case Op.GE: 186 return ValueUnknown.valueUnknown; 187 case Op.COMPARE: 188 return r.valCmpNull(); 189 default: 190 throw badBinop(op, r); 191 } 192 } 193 194 197 public Value binop(int op, ValuePattern r) throws ValueException { 198 return ValuePattern.binop(op, this, r); 199 } 200 201 204 public static Value binop_convert(int op, ValueString l, Value r) 205 throws ValueException 206 { 207 ValueString rv = new ValueString(r.toString()); 208 return l.binop(op, rv); 209 } 210 211 214 static final int compareStrings(final String a, final String b) { 215 if (isCaseSensitive) { 216 return a.compareTo(b); 217 } else { 218 return a.compareToIgnoreCase(b); 219 } 220 } 221 222 225 public Value binop(int op, ValueString r) throws ValueException { 226 return binop(op, this, r); 227 } 228 229 public static Value binop(int op, ValueString l, ValueString r) 230 throws ValueException 231 { 232 String aval = l.val; 234 String bval = r.val; 235 if (op != Op.PATTERN && op != Op.CONCAT) { 236 if (aval.length() < bval.length()) { 237 StringBuffer sb = new StringBuffer (aval); 238 while (sb.length() < bval.length()) sb.append(' '); 239 aval = sb.toString(); 240 } else if (aval.length() > bval.length()) { 241 StringBuffer sb = new StringBuffer (bval); 242 while (sb.length() < aval.length()) sb.append(' '); 243 bval = sb.toString(); 244 } 245 } 246 switch (op) { 247 case Op.EQ: 248 return new ValueBoolean(compareStrings(aval, bval) == 0); 249 case Op.NE: 250 return new ValueBoolean(compareStrings(aval, bval) != 0); 251 case Op.LT: 252 return new ValueBoolean(compareStrings(aval, bval) < 0); 253 case Op.LE: 254 return new ValueBoolean(compareStrings(aval, bval) <= 0); 255 case Op.GT: 256 return new ValueBoolean(compareStrings(aval, bval) > 0); 257 case Op.GE: 258 return new ValueBoolean(compareStrings(aval, bval) >= 0); 259 case Op.CONCAT: 260 return new ValueString(aval + bval); 261 case Op.COMPARE: 262 return new ValueInteger(compareStrings(aval, bval)); 263 case Op.PATTERN: 264 return new ValuePattern(aval, bval); 265 default: 266 throw badBinop(op, l, r); 267 } 268 } 269 270 273 public void readExternal(ObjectInput in) 274 throws IOException , ClassNotFoundException 275 { 276 val = (String )proxy.readObject(in); 277 } 278 279 282 public void writeExternal(ObjectOutput out) 283 throws IOException 284 { 285 proxy.writeObject(out, val); 287 } 288 289 292 public Object readObject(ObjectInput in) 293 throws IOException , ClassNotFoundException 294 { 295 ValueString v = new ValueString(); 296 v.readExternal(in); 297 return v; 298 } 299 300 303 public void writeObject(ObjectOutput out, Object object) 304 throws IOException 305 { 306 ((ValueString)object).writeExternal(out); 307 } 308 309 312 public Object asJavaObject() { 313 return val; 314 } 315 316 319 public void fromJavaObject(Object obj) { 320 val = obj.toString(); 321 } 322 323 326 public InputStream getBinaryStream() { 327 return new ByteArrayInputStream (val.getBytes()); 328 } 329 330 333 public Reader getCharacterStream() { 334 return new StringReader (val); 335 } 336 337 340 public Value convert(TypeTinyInt type) throws ValueException { 341 try { 342 return TypeTinyInt.convertNumber(Double.parseDouble(val)); 343 } catch (NumberFormatException e) { 344 throw new ValueException("Can't convert to TINYINT: " + val); 345 } 346 } 347 348 351 public Value convert(TypeSmallInt type) throws ValueException { 352 try { 353 return TypeSmallInt.convertNumber(Double.parseDouble(val)); 354 } catch (NumberFormatException e) { 355 throw new ValueException("Can't convert to SMALLINT: " + val); 356 } 357 } 358 359 362 public Value convert(TypeInt type) throws ValueException { 363 try { 364 return TypeInt.convertNumber(Double.parseDouble(val)); 365 } catch (Exception e) { 366 throw new ValueException("Can't convert to INTEGER: " + val); 367 } 368 } 369 370 373 public Value convert(TypeBigInt type) throws ValueException { 374 try { 375 return TypeBigInt.convertNumber(Double.parseDouble(val)); 376 } catch (Exception e) { 377 throw new ValueException("Can't convert to BIGINT: " + val); 378 } 379 } 380 381 384 public Value convert(TypeDecimal type) throws ValueException { 385 return new ValueScaledInteger(val); 386 } 387 388 391 public Value convert(TypeReal type) throws ValueException { 392 switch (type.getJDBCType()) { 393 case Types.DOUBLE: 394 return new ValueDouble(val); 395 case Types.FLOAT: 396 if (type.getPrecision() > 31) { 397 return new ValueDouble(val); 398 } else { 399 return new ValueFloat(val); 400 } 401 case Types.REAL: 402 return new ValueFloat(val); 403 } 404 throw new ValueException("Bogus type: " + type); 405 } 406 407 410 public Value convert(TypeChar type) throws ValueException { 411 int max = type.getMax(); 412 if (val.length() < max) { 413 StringBuffer sb = new StringBuffer (val); 415 while (sb.length() < max) sb.append(' '); 416 return new ValueString(sb.toString()); 417 } else if (val.length() > max) { 418 for (int i = val.length() - 1; i >= max; i--) { 420 if (val.charAt(i) != ' ') { 421 throw new ValueException("String too long: " + 422 "(length " + val.length() + 423 ", max " + max + 424 ", c = " + ((int)val.charAt(i)) + 425 ")"); 426 } 427 } 428 return new ValueString(val.substring(0, max)); 429 } else { 430 return this; 431 } 432 } 433 434 437 public Value convert(TypeVarChar type) throws ValueException { 438 int max = type.getMax(); 439 if (max > 0 && val.length() > max) { 440 throw new ValueException("String too long: " + 441 "(length " + val.length() + 442 ", max " + max + ")"); 443 } 444 return this; 445 } 446 447 450 public Value convert(TypeDate type) throws ValueException { 451 try { 452 return new ValueDate(val); 453 } catch (antlr.RecognitionException e) { 454 throw new ValueException("Invalid date format: " + val); 455 } 456 } 457 458 461 public Value convert(TypeTime type) throws ValueException { 462 try { 463 return new ValueTime(val); 464 } catch (antlr.RecognitionException e) { 465 throw new ValueException("Invalid time format: " + val); 466 } 467 } 468 469 472 public Value convert(TypeTimestamp type) throws ValueException { 473 try { 474 return new ValueTimestamp(val); 475 } catch (antlr.RecognitionException e) { 476 throw new ValueException("Invalid timestamp format: " + val); 477 } 478 } 479 480 483 public Value convert(TypeInterval type) throws ValueException { 484 try { 485 return new ValueInterval(val, 1, type); 486 } catch (antlr.RecognitionException e) { 487 throw new ValueException("Invalid timestamp format: " + val); 488 } 489 } 490 491 494 public Value convert(TypeClob type) throws ValueException { 495 return new ValueClob(val); 496 } 497 498 501 public Type getType() { 502 return new TypeChar(val.length()); 503 } 504 505 508 public void serializeKey(KeyStream out) throws IOException { 509 out.writeChars(val); 510 } 511 512 515 static Extern extern = null; 516 public Extern getExtern() { return extern; } 517 public void setExtern(Extern extern) { ValueString.extern = extern; } 518 } 519 | Popular Tags |