1 29 30 package com.caucho.quercus.lib.db; 31 32 import com.caucho.quercus.annotation.NotNull; 33 import com.caucho.quercus.annotation.Optional; 34 import com.caucho.quercus.annotation.ReturnNullAsFalse; 35 import com.caucho.quercus.env.*; 36 import com.caucho.quercus.module.AbstractQuercusModule; 37 import com.caucho.util.L10N; 38 import com.caucho.util.Log; 39 40 import java.sql.Driver ; 41 import java.sql.DriverManager ; 42 import java.sql.ResultSetMetaData ; 43 import java.sql.SQLException ; 44 import java.sql.Statement ; 45 import java.sql.Types ; 46 import java.util.logging.Level ; 47 import java.util.logging.Logger ; 48 49 50 53 public class MysqlModule extends AbstractQuercusModule { 54 55 private static final Logger log = Log.open(MysqlModule.class); 56 private static final L10N L = new L10N(MysqlModule.class); 57 58 public static final int MYSQL_ASSOC = 0x1; 59 public static final int MYSQL_NUM = 0x2; 60 public static final int MYSQL_BOTH = 0x3; 61 62 public static final int MYSQL_USE_RESULT = 0x0; 63 public static final int MYSQL_STORE_RESULT = 0x1; 64 65 public MysqlModule() 66 { 67 } 68 69 72 public String []getLoadedExtensions() 73 { 74 return new String [] { "mysql" }; 75 } 76 77 80 public int mysql_affected_rows(Env env, @Optional Mysqli conn) 81 { 82 if (conn == null) 83 conn = getConnection(env); 84 85 return conn.affected_rows(); 86 } 87 88 91 public String mysql_client_encoding(Env env, @Optional Mysqli conn) 92 { 93 if (conn == null) 94 conn = getConnection(env); 95 96 return conn.client_encoding(); 97 } 98 99 102 public boolean mysql_close(Env env, @Optional Mysqli conn) 103 { 104 if (conn == null) 105 conn = getConnection(env); 106 107 if (conn != null) { 108 if (conn == getConnection(env)) 109 env.removeSpecialValue("caucho.mysql"); 110 111 conn.close(env); 112 113 return true; 114 } 115 else 116 return false; 117 } 118 119 122 public boolean mysql_create_db(Env env, @NotNull String name, @Optional Mysqli conn) 123 { 124 if (name == null) 125 return false; 126 127 if (conn == null) 128 conn = getConnection(env); 129 130 Statement stmt = null; 131 132 try { 134 try { 135 stmt = conn.validateConnection().getConnection().createStatement(); 136 stmt.setEscapeProcessing(false); 137 stmt.executeUpdate("CREATE DATABASE " + name); 138 } finally { 139 if (stmt != null) 140 stmt.close(); 141 } 142 } catch (SQLException e) { 143 log.log(Level.FINE, e.toString(), e); 144 return false; 145 } 146 147 return true; 148 } 149 150 154 public boolean mysql_data_seek(Env env, 155 @NotNull MysqliResult result, 156 int rowNumber) 157 { 158 if (result == null) 159 return false; 160 161 if (result.seek(env, rowNumber)) { 162 return true; 163 } else { 164 env.warning(L.l("Offset {0} is invalid for MySQL (or the query data is unbuffered)", 165 rowNumber)); 166 return false; 167 } 168 } 169 170 173 public Value mysql_db_name(Env env, 174 @NotNull MysqliResult result, 175 int row, 176 @Optional("0") Value field) 177 { 178 if (result == null) 179 return BooleanValue.FALSE; 180 181 return mysql_result(env, result, row, field); 182 } 183 184 187 public Value mysql_result(Env env, 188 @NotNull MysqliResult result, 189 int row, 190 @Optional("0") Value field) 191 { 192 if (result == null) 193 return BooleanValue.FALSE; 194 195 return result.getResultField(env, row, field); 196 } 197 198 201 public boolean mysql_drop_db(Env env, 202 @NotNull String databaseName, 203 @Optional Mysqli conn) 204 { 205 if (databaseName == null) 206 return false; 207 208 Value value = mysql_query(env, "DROP DATABASE " + databaseName, conn); 209 210 return (value != null && value.toBoolean()); 211 } 212 213 216 public int mysql_errno(Env env, @Optional Mysqli conn) 217 { 218 if (conn == null) 219 conn = getConnection(env); 220 221 return conn.errno(); 222 } 223 224 227 public String mysql_error(Env env, @Optional Mysqli conn) 228 { 229 if (conn == null) 230 conn = getConnection(env); 231 232 String error = conn.error(); 233 234 if (error == null) 235 return ""; 236 237 return error; 238 } 239 240 public Value mysql_escape_string(Env env, StringValue unescapedString) 241 { 242 return mysql_real_escape_string(env, unescapedString, null); 243 } 244 245 252 253 public Value mysql_real_escape_string(Env env, 254 StringValue unescapedString, 255 @Optional Mysqli conn) 256 { 257 if (conn == null) 258 conn = getConnection(env); 259 260 return conn.real_escape_string(unescapedString); 261 } 262 263 266 public Value mysql_fetch_array(Env env, 267 @NotNull MysqliResult result, 268 @Optional("MYSQL_BOTH") int type) 269 { 270 if (result == null) 271 return BooleanValue.FALSE; 272 273 Value value = result.fetch_array(env, type); 274 275 if (value != null) 276 return value; 277 else 278 return BooleanValue.FALSE; 279 } 280 281 284 @ReturnNullAsFalse 285 public ArrayValue mysql_fetch_assoc(Env env, @NotNull MysqliResult result) 286 { 287 if (result == null) 288 return null; 289 290 return result.fetch_array(env, MYSQL_ASSOC); 291 } 292 293 307 public Value mysql_fetch_field(Env env, 308 @NotNull MysqliResult result, 309 @Optional("-1") int fieldOffset) 310 { 311 316 317 if (result == null) 318 return BooleanValue.FALSE; 319 320 322 try { 323 if (fieldOffset == -1) { 324 fieldOffset = result.field_tell(env); 325 result.setFieldOffset(fieldOffset + 1); 326 } 327 328 ResultSetMetaData md = result.getMetaData(); 329 330 if (md.getColumnCount() <= fieldOffset || fieldOffset < 0) { 331 env.invalidArgument("field", fieldOffset); 332 return BooleanValue.FALSE; 333 } 334 335 int jdbcField = fieldOffset + 1; 336 int jdbcColumnType = md.getColumnType(jdbcField); 337 338 String catalogName = md.getCatalogName(jdbcField); 339 String tableName = md.getTableName(jdbcField); 340 String columnName = md.getColumnName(jdbcField); 341 342 JdbcColumnMetaData columnMd = null; 344 345 JdbcConnectionResource conn = getConnection(env).validateConnection(); 346 347 JdbcTableMetaData tableMd 348 = conn.getTableMetaData(catalogName, null, tableName); 349 350 if (tableMd != null) 351 columnMd = tableMd.getColumn(columnName); 352 353 357 int maxLength = 0; 358 int notNull = md.isNullable(jdbcField) == ResultSetMetaData.columnNullable ? 0 : 1; 359 int numeric = JdbcColumnMetaData.isNumeric(jdbcColumnType) ? 1 : 0; 360 int blob = JdbcColumnMetaData.isBlob(jdbcColumnType) ? 1 : 0; 361 String type = JdbcResultResource.getColumnPHPName(jdbcColumnType); 362 int unsigned = md.isSigned(jdbcField) ? 0 : numeric; 363 364 if (jdbcColumnType == Types.BOOLEAN || jdbcColumnType == Types.BIT) 365 unsigned = 0; 366 else if (jdbcColumnType == Types.DECIMAL) 367 numeric = 1; 368 369 int zerofill = 0; 370 int primaryKey = 0; 371 int multipleKey = 0; 372 int uniqueKey = 0; 373 374 if (columnMd != null) { 375 zerofill = columnMd.isZeroFill() ? 1 : 0; 376 primaryKey = columnMd.isPrimaryKey() ? 1 : 0; 377 uniqueKey = columnMd.isUnique() ? 1 : 0; 380 } 381 else 382 notNull = 1; 383 384 ObjectValue fieldResult = env.createObject(); 385 386 fieldResult.putField("name", columnName); 387 fieldResult.putField("table", tableName); 388 fieldResult.putField("def", ""); 389 fieldResult.putField("max_length", maxLength); 390 fieldResult.putField("not_null", notNull); 391 fieldResult.putField("primary_key", primaryKey); 392 fieldResult.putField("multiple_key", multipleKey); 393 fieldResult.putField("unique_key", uniqueKey); 394 fieldResult.putField("numeric", numeric); 395 fieldResult.putField("blob", blob); 396 fieldResult.putField("type", type); 397 fieldResult.putField("unsigned", unsigned); 398 fieldResult.putField("zerofill", zerofill); 399 400 return fieldResult; 401 } catch (SQLException e) { 402 log.log(Level.FINE, e.toString(), e); 403 return BooleanValue.FALSE; 404 } 405 } 406 407 413 public Value mysql_query(Env env, String sql, @Optional Mysqli conn) 414 { 415 if (conn == null) 416 conn = getConnection(env); 417 418 return conn.query(env, sql, MYSQL_STORE_RESULT); 419 } 420 421 424 public Value mysql_fetch_lengths(Env env, @NotNull MysqliResult result) 425 { 426 if (result == null) 427 return BooleanValue.FALSE; 428 429 return result.fetch_lengths(); 430 } 431 432 436 public Value mysql_fetch_object(Env env, @NotNull MysqliResult result) 437 { 438 if (result == null) 439 return BooleanValue.FALSE; 440 441 return result.fetch_object(env); 442 } 443 444 447 @ReturnNullAsFalse 448 public ArrayValue mysql_fetch_row(Env env, @NotNull MysqliResult result) 449 { 450 if (result == null) 451 return null; 452 453 return result.fetch_row(env); 454 } 455 456 474 public Value mysql_field_flags(Env env, 475 @NotNull MysqliResult result, 476 int fieldOffset) 477 { 478 if (result == null) 479 return BooleanValue.FALSE; 480 481 Value fieldName = result.getFieldName(env, fieldOffset); 482 483 if (fieldName == BooleanValue.FALSE) 484 return BooleanValue.FALSE; 485 486 Value fieldTable = result.getFieldTable(env, fieldOffset); 487 488 if (fieldTable == BooleanValue.FALSE) 489 return BooleanValue.FALSE; 490 491 String sql = "SHOW FULL COLUMNS FROM " + fieldTable.toString() + " LIKE \'" + fieldName.toString() + "\'"; 492 493 Mysqli conn = getConnection(env); 494 495 Object metaResult = conn.validateConnection().realQuery(sql); 496 497 if (metaResult instanceof MysqliResult) 498 return ((MysqliResult) metaResult).getFieldFlags(); 499 500 return BooleanValue.FALSE; 501 } 502 503 506 public Value mysql_field_name(Env env, 507 @NotNull MysqliResult result, 508 int fieldOffset) 509 { 510 if (result == null) 511 return BooleanValue.FALSE; 512 513 return result.getFieldName(env, fieldOffset); 514 } 515 516 520 public boolean mysql_field_seek(Env env, 521 @NotNull MysqliResult result, 522 int fieldOffset) 523 { 524 if (result == null) 525 return false; 526 527 return result.field_seek(env, fieldOffset); 528 } 529 530 533 public Value mysql_field_table(Env env, 534 @NotNull MysqliResult result, 535 int fieldOffset) 536 { 537 if (result == null) 538 return BooleanValue.FALSE; 539 540 return result.getFieldTable(env, fieldOffset); 541 } 542 543 546 public static Value mysql_field_type(Env env, 547 @NotNull MysqliResult result, 548 Value fieldOffset) 549 { 550 if (result == null) { 551 return NullValue.NULL; 552 } 553 554 if (! fieldOffset.isset()) 555 return NullValue.NULL; 556 557 return result.getFieldType(env, fieldOffset.toInt()); 558 } 559 560 563 public static Value mysql_fieldlen(Env env, 564 @NotNull MysqliResult result, 565 int fieldOffset) 566 { 567 return mysql_field_len(env, result, fieldOffset); 568 } 569 570 573 public static Value mysql_field_len(Env env, 574 @NotNull MysqliResult result, 575 int fieldOffset) 576 { 577 if (result == null) 578 return BooleanValue.FALSE; 579 580 582 return result.getFieldLength(env, fieldOffset); 583 } 584 585 588 public boolean mysql_free_result(MysqliResult result) 589 { 590 if (result != null) 591 result.close(); 592 593 return true; 594 } 595 596 599 public static String mysql_get_client_info(Env env) 600 { 601 try { 602 Driver driver = DriverManager.getDriver("jdbc:mysql://localhost/"); 603 604 return driver.getMajorVersion() + '.' + 605 driver.getMinorVersion() + ".00"; 606 } 607 catch (SQLException e) { 608 return "0.00.00"; 609 } 610 } 611 612 615 public String mysql_get_host_info(Env env, @Optional Mysqli conn) 616 { 617 if (conn == null) 618 conn = getConnection(env); 619 620 return conn.get_host_info(); 621 } 622 623 627 public int mysql_get_proto_info(Env env, @Optional Mysqli conn) 628 { 629 if (conn == null) 630 conn = getConnection(env); 631 632 return conn.get_proto_info(); 633 } 634 635 638 public String mysql_get_server_info(Env env, @Optional Mysqli conn) 639 { 640 if (conn == null) 641 conn = getConnection(env); 642 643 return conn.get_server_info(); 644 } 645 646 651 public Value mysql_insert_id(Env env, @Optional Mysqli conn) 652 { 653 if (conn == null) 654 conn = getConnection(env); 655 656 return conn.insert_id(); 657 } 658 659 662 public JdbcResultResource mysql_list_dbs(Env env, @Optional Mysqli conn) 663 { 664 if (conn == null) 665 conn = getConnection(env); 666 667 return conn.list_dbs(); 668 } 669 670 673 public Value mysql_list_fields(Env env, 674 String databaseName, 675 String tableName, 676 @Optional Mysqli conn) 677 { 678 if (databaseName == null) 679 return BooleanValue.FALSE; 680 681 if (tableName == null) 682 return BooleanValue.FALSE; 683 684 return mysql_db_query(env, 685 databaseName, 686 "SHOW COLUMNS FROM " + tableName, 687 conn); 688 } 689 690 693 public Value mysql_db_query(Env env, 694 String databaseName, 695 String query, 696 @Optional Mysqli conn) 697 { 698 if (conn == null) 699 conn = getConnection(env); 700 701 if (! conn.select_db(databaseName)) 702 return BooleanValue.FALSE; 703 704 return conn.query(env, query, 1); 705 } 706 707 710 public boolean mysql_select_db(Env env, 711 String name, 712 @Optional Mysqli conn) 713 { 714 if (conn == null) 715 conn = getConnection(env); 716 717 return conn.select_db(name); 718 } 719 720 723 public Object mysql_list_tables(Env env, 724 String databaseName, 725 @Optional Mysqli conn) 726 { 727 return mysql_query(env, "SHOW TABLES FROM " + databaseName, conn); 728 } 729 730 public int mysql_num_fields(Env env, @NotNull MysqliResult result) 731 { 732 if (result == null) 733 return -1; 734 735 return result.num_fields(); 736 } 737 738 741 public Value mysql_num_rows(Env env, @NotNull MysqliResult result) 742 { 743 if (result == null) 744 return BooleanValue.FALSE; 745 746 return result.num_rows(); 747 } 748 749 752 public Value mysql_numrows(Env env, @NotNull MysqliResult result) 753 { 754 return mysql_num_rows(env, result); 755 } 756 757 760 public Value mysql_pconnect(Env env, 761 @Optional String server, 762 @Optional String user, 763 @Optional String password, 764 @Optional Value newLinkV, 765 @Optional Value flagsV) 766 { 767 return mysql_connect(env, server, user, password, newLinkV, flagsV); 768 } 769 770 773 public Value mysql_connect(Env env, 774 @Optional String host, 775 @Optional String userName, 776 @Optional String password, 777 @Optional Value newLinkV, 778 @Optional Value flagsV) 779 { 780 int port = 3306; 781 int length = host.length(); 782 783 if (length == 0) { 784 host = env.getIniString("mysql.default_host"); 785 if (host == null) 786 host = "localhost"; 787 } 788 789 int portIndex = host.lastIndexOf(':'); 790 791 if (portIndex > 0) { 794 port = 0; 795 796 for (int j = portIndex + 1; j < length; j++) { 797 char ch = host.charAt(j); 798 799 if ('0' <= ch && ch <= '9') 800 port = port * 10 + ch - '0'; 801 else 802 break; 803 } 804 805 host = host.substring(0, portIndex); 806 } 807 808 Mysqli mysqli = new Mysqli(env, host, userName, password, "", port, "", 0, null, null); 809 810 if (! mysqli.isConnected()) 811 return BooleanValue.FALSE; 812 813 Value value = env.wrapJava(mysqli); 814 815 env.setSpecialValue("caucho.mysql", mysqli); 816 817 return value; 818 } 819 820 823 public boolean mysql_ping(Env env, @Optional Mysqli conn) 824 { 825 if (conn == null) 826 conn = getConnection(env); 827 828 return conn.ping(); 829 } 830 831 835 public Value mysql_stat(Env env, Mysqli conn) 836 { 837 if (conn == null) 838 conn = getConnection(env); 839 840 Value result = conn.stat(env); 841 842 return result == BooleanValue.FALSE ? NullValue.NULL : result; 843 } 844 845 849 public Value mysql_tablename(Env env, 850 @NotNull MysqliResult result, 851 int i) 852 { 853 if (result == null) 854 return BooleanValue.FALSE; 855 856 return result.getResultField(env, i, LongValue.ZERO); 857 } 858 859 862 public Object mysql_unbuffered_query(Env env, 863 @NotNull String name, 864 @Optional Mysqli conn) 865 { 866 return mysql_query(env, name, conn); 867 } 868 869 874 private Mysqli getConnection(Env env) 875 { 876 Mysqli conn = (Mysqli) env.getSpecialValue("caucho.mysql"); 877 878 if (conn != null) 879 return conn; 880 881 conn = new Mysqli(env, "localhost", "", "", "", 3306, "", 0, null, null); 882 883 env.setSpecialValue("caucho.mysql", conn); 884 885 return conn; 886 } 887 } 888 889 | Popular Tags |