1 65 66 67 package org.hsqldb; 68 69 import org.hsqldb.HsqlNameManager.HsqlName; 70 import org.hsqldb.lib.HashMap; 71 import org.hsqldb.lib.HashMappedList; 72 import org.hsqldb.lib.HsqlArrayList; 73 import org.hsqldb.lib.IntValueHashMap; 74 import org.hsqldb.lib.Iterator; 75 import org.hsqldb.lib.StringConverter; 76 77 88 public class DatabaseScript { 89 90 98 public static Result getScript(Database database, boolean indexRoots) { 99 100 Iterator it; 101 Result r = Result.newSingleColumnResult("COMMAND", Types.VARCHAR); 102 103 r.metaData.tableNames[0] = "SYSTEM_SCRIPT"; 104 105 if (database.collation.name != null) { 107 String name = 108 StringConverter.toQuotedString(database.collation.name, '"', 109 true); 110 111 addRow(r, "SET DATABASE COLLATION " + name); 112 } 113 114 it = database.getGranteeManager().getRoleNames().iterator(); 116 117 String role; 118 119 while (it.hasNext()) { 120 role = (String ) it.next(); 121 122 if (!GranteeManager.DBA_ADMIN_ROLE_NAME.equals(role)) { 124 addRow(r, "CREATE ROLE " + role); 125 } 126 } 127 128 HashMap h = database.getAliasMap(); 130 HashMap builtin = Library.getAliasMap(); 131 132 it = h.keySet().iterator(); 133 134 while (it.hasNext()) { 135 String alias = (String ) it.next(); 136 String java = (String ) h.get(alias); 137 String biJava = (String ) builtin.get(alias); 138 139 if (biJava != null && biJava.equals(java)) { 140 continue; 141 } 142 143 StringBuffer buffer = new StringBuffer (64); 144 145 buffer.append(Token.T_CREATE).append(' ').append( 146 Token.T_ALIAS).append(' '); 147 buffer.append(alias); 148 buffer.append(" FOR \""); 149 buffer.append(java); 150 buffer.append('"'); 151 addRow(r, buffer.toString()); 152 } 153 154 addSchemaStatements(database, r, indexRoots); 155 156 addRightsStatements(database, r); 158 159 if (database.logger.hasLog()) { 160 int delay = database.logger.getWriteDelay(); 161 boolean millis = delay < 1000; 162 163 if (millis) { 164 if (delay != 0 && delay < 20) { 165 delay = 20; 166 } 167 } else { 168 delay /= 1000; 169 } 170 171 String statement = "SET WRITE_DELAY " + delay 172 + (millis ? " MILLIS" 173 : ""); 174 175 addRow(r, statement); 176 } 177 178 return r; 179 } 180 181 static void addSchemaStatements(Database database, Result r, 182 boolean indexRoots) { 183 184 Iterator schemas = database.schemaManager.userSchemaNameIterator(); 185 186 while (schemas.hasNext()) { 187 String schemaKey = (String ) schemas.next(); 188 HsqlName schema = 189 database.schemaManager.toSchemaHsqlName(schemaKey); 190 HashMappedList tTable = 191 database.schemaManager.getTables(schema.name); 192 HsqlArrayList forwardFK = new HsqlArrayList(); 193 194 { 196 String ddl = getSchemaCreateDDL(database, schema); 197 198 addRow(r, ddl); 199 } 200 201 208 Iterator it = 209 database.schemaManager.sequenceIterator(schema.name); 210 211 while (it.hasNext()) { 212 NumberSequence seq = (NumberSequence) it.next(); 213 StringBuffer a = new StringBuffer (128); 214 215 a.append(Token.T_CREATE).append(' '); 216 a.append(Token.T_SEQUENCE).append(' '); 217 a.append(seq.getName().statementName).append(' '); 218 a.append(Token.T_AS).append(' '); 219 a.append(Types.getTypeString(seq.getType())).append(' '); 220 a.append(Token.T_START).append(' '); 221 a.append(Token.T_WITH).append(' '); 222 a.append(seq.peek()).append(' '); 223 224 if (seq.getIncrement() != 1) { 225 a.append(Token.T_INCREMENT).append(' '); 226 a.append(Token.T_BY).append(' '); 227 a.append(seq.getIncrement()).append(' '); 228 } 229 230 addRow(r, a.toString()); 231 } 232 233 for (int i = 0, tSize = tTable.size(); i < tSize; i++) { 235 Table t = (Table) tTable.get(i); 236 237 if (t.isView()) { 238 continue; 239 } 240 241 StringBuffer a = new StringBuffer (128); 242 243 getTableDDL(database, t, i, forwardFK, false, a); 244 addRow(r, a.toString()); 245 246 for (int j = 1; j < t.getIndexCount(); j++) { 248 Index index = t.getIndex(j); 249 250 if (HsqlName.isReservedIndexName(index.getName().name)) { 251 252 continue; 257 } 258 259 a = new StringBuffer (64); 260 261 a.append(Token.T_CREATE).append(' '); 262 263 if (index.isUnique()) { 264 a.append(Token.T_UNIQUE).append(' '); 265 } 266 267 a.append(Token.T_INDEX).append(' '); 268 a.append(index.getName().statementName); 269 a.append(' ').append(Token.T_ON).append(' '); 270 a.append(t.getName().statementName); 271 272 int[] col = index.getColumns(); 273 int len = index.getVisibleColumns(); 274 275 getColumnList(t, col, len, a); 276 addRow(r, a.toString()); 277 } 278 279 if (t.isText() && t.isDataReadOnly()) { 281 a = new StringBuffer (64); 282 283 a.append(Token.T_SET).append(' ').append( 284 Token.T_TABLE).append(' '); 285 a.append(t.getName().statementName); 286 a.append(' ').append(Token.T_READONLY).append(' ').append( 287 Token.T_TRUE); 288 addRow(r, a.toString()); 289 } 290 291 String dataSource = getDataSource(t); 293 294 if (dataSource != null) { 295 addRow(r, dataSource); 296 } 297 298 String header = getDataSourceHeader(t); 300 301 if (!indexRoots && header != null) { 302 addRow(r, header); 303 } 304 305 int numTrigs = TriggerDef.NUM_TRIGS; 307 308 for (int tv = 0; tv < numTrigs; tv++) { 309 HsqlArrayList trigVec = t.triggerLists[tv]; 310 311 if (trigVec == null) { 312 continue; 313 } 314 315 int trCount = trigVec.size(); 316 317 for (int k = 0; k < trCount; k++) { 318 a = ((TriggerDef) trigVec.get(k)).getDDL(); 319 320 addRow(r, a.toString()); 321 } 322 } 323 } 324 325 for (int i = 0, tSize = forwardFK.size(); i < tSize; i++) { 327 Constraint c = (Constraint) forwardFK.get(i); 328 StringBuffer a = new StringBuffer (128); 329 330 a.append(Token.T_ALTER).append(' ').append( 331 Token.T_TABLE).append(' '); 332 a.append(c.getRef().getName().statementName); 333 a.append(' ').append(Token.T_ADD).append(' '); 334 getFKStatement(c, a); 335 addRow(r, a.toString()); 336 } 337 338 Session sysSession = database.sessionManager.getSysSession(); 340 341 for (int i = 0, tSize = tTable.size(); i < tSize; i++) { 342 Table t = (Table) tTable.get(i); 343 344 if (indexRoots && t.isIndexCached() 345 &&!t.isEmpty(sysSession)) { 346 addRow(r, getIndexRootsDDL((Table) tTable.get(i))); 347 } 348 } 349 350 for (int i = 0, tSize = tTable.size(); i < tSize; i++) { 352 Table t = (Table) tTable.get(i); 353 354 if (!t.isTemp()) { 355 String ddl = getIdentityUpdateDDL(t); 356 357 addRow(r, ddl); 358 } 359 } 360 361 for (int i = 0, tSize = tTable.size(); i < tSize; i++) { 363 Table t = (Table) tTable.get(i); 364 365 if (t.isView()) { 366 View v = (View) tTable.get(i); 367 StringBuffer a = new StringBuffer (128); 368 369 a.append(Token.T_CREATE).append(' ').append( 370 Token.T_VIEW).append(' '); 371 a.append(v.getName().statementName).append(' ').append( 372 '('); 373 374 int count = v.getColumnCount(); 375 376 for (int j = 0; j < count; j++) { 377 a.append(v.getColumn(j).columnName.statementName); 378 379 if (j < count - 1) { 380 a.append(','); 381 } 382 } 383 384 a.append(')').append(' ').append(Token.T_AS).append(' '); 385 a.append(v.getStatement()); 386 addRow(r, a.toString()); 387 } 388 } 389 } 390 } 391 392 static String getIdentityUpdateDDL(Table t) { 393 394 if (t.identityColumn == -1) { 395 return ""; 396 } else { 397 String tablename = t.getName().statementName; 398 String colname = 399 t.getColumn(t.identityColumn).columnName.statementName; 400 long idval = t.identitySequence.peek(); 401 StringBuffer a = new StringBuffer (128); 402 403 a.append(Token.T_ALTER).append(' ').append(Token.T_TABLE).append( 404 ' ').append(tablename).append(' ').append( 405 Token.T_ALTER).append(' ').append(Token.T_COLUMN).append( 406 ' ').append(colname).append(' ').append( 407 Token.T_RESTART).append(' ').append(Token.T_WITH).append( 408 ' ').append(idval); 409 410 return a.toString(); 411 } 412 } 413 414 static String getIndexRootsDDL(Table t) { 415 416 StringBuffer a = new StringBuffer (128); 417 418 a.append(Token.T_SET).append(' ').append(Token.T_TABLE).append(' '); 419 a.append(t.getName().statementName); 420 a.append(' ').append(Token.T_INDEX).append('\''); 421 a.append(t.getIndexRoots()); 422 a.append('\''); 423 424 return a.toString(); 425 } 426 427 static String getSchemaCreateDDL(Database database, HsqlName schemaName) { 428 429 StringBuffer ab = new StringBuffer (128); 430 431 ab.append(Token.T_CREATE).append(' '); 432 ab.append(Token.T_SCHEMA).append(' '); 433 ab.append(schemaName.statementName).append(' '); 434 ab.append(Token.T_AUTHORIZATION).append(' '); 435 ab.append(GranteeManager.DBA_ADMIN_ROLE_NAME); 436 437 return ab.toString(); 438 } 439 440 static void getTableDDL(Database database, Table t, int i, 441 HsqlArrayList forwardFK, boolean useSchema, 442 StringBuffer a) { 443 444 a.append(Token.T_CREATE).append(' '); 445 446 if (t.isTemp) { 447 a.append(Token.T_GLOBAL).append(' '); 448 a.append(Token.T_TEMPORARY).append(' '); 449 } 450 451 if (t.isText()) { 452 a.append(Token.T_TEXT).append(' '); 453 } else if (t.isCached()) { 454 a.append(Token.T_CACHED).append(' '); 455 } else { 456 a.append(Token.T_MEMORY).append(' '); 457 } 458 459 a.append(Token.T_TABLE).append(' '); 460 461 if (useSchema) { 462 a.append(t.getName().schema.statementName).append('.'); 463 } 464 465 a.append(t.getName().statementName); 466 a.append('('); 467 468 int columns = t.getColumnCount(); 469 int[] pk = t.getPrimaryKey(); 470 HsqlName pkName = null; 471 Constraint pkConst = t.getPrimaryConstraint(); 472 473 if (pkConst != null &&!pkConst.getName().isReservedIndexName()) { 474 pkName = pkConst.getName(); 475 } 476 477 for (int j = 0; j < columns; j++) { 478 Column column = t.getColumn(j); 479 String colname = column.columnName.statementName; 480 481 a.append(colname); 482 a.append(' '); 483 484 String sType = Types.getTypeString(column.getType()); 485 486 a.append(sType); 487 488 boolean hasSize = false; 490 491 if (column.getType() == Types.TIMESTAMP) { 492 if (column.getSize() != 6) { 493 hasSize = true; 494 } 495 } else { 496 hasSize = column.getSize() > 0; 497 } 498 499 if (hasSize) { 500 a.append('('); 501 a.append(column.getSize()); 502 503 if (column.getScale() > 0) { 504 a.append(','); 505 a.append(column.getScale()); 506 } 507 508 a.append(')'); 509 } 510 511 String defaultString = column.getDefaultDDL(); 512 513 if (defaultString != null) { 514 a.append(' ').append(Token.T_DEFAULT).append(' '); 515 a.append(defaultString); 516 } 517 518 if (j == t.getIdentityColumn()) { 519 a.append(" GENERATED BY DEFAULT AS IDENTITY(START WITH "); 520 a.append(column.identityStart); 521 522 if (column.identityIncrement != 1) { 523 a.append(Token.T_COMMA).append(Token.T_INCREMENT).append( 524 ' ').append(Token.T_BY).append(' '); 525 a.append(column.identityIncrement); 526 } 527 528 a.append(")"); 529 } 530 531 if (!column.isNullable()) { 532 a.append(' ').append(Token.T_NOT).append(' ').append( 533 Token.T_NULL); 534 } 535 536 if ((pk.length == 1) && (j == pk[0]) && pkName == null) { 537 a.append(' ').append(Token.T_PRIMARY).append(' ').append( 538 Token.T_KEY); 539 } 540 541 if (j < columns - 1) { 542 a.append(','); 543 } 544 } 545 546 if (pk.length > 1 || (pk.length == 1 && pkName != null)) { 547 a.append(','); 548 549 if (pkName != null) { 550 a.append(Token.T_CONSTRAINT).append(' '); 551 a.append(pkName.statementName).append(' '); 552 } 553 554 a.append(Token.T_PRIMARY).append(' ').append(Token.T_KEY); 555 getColumnList(t, pk, pk.length, a); 556 } 557 558 Constraint[] v = t.getConstraints(); 559 560 for (int j = 0, vSize = v.length; j < vSize; j++) { 561 Constraint c = v[j]; 562 563 switch (c.getType()) { 564 565 case Constraint.UNIQUE : 566 a.append(',').append(Token.T_CONSTRAINT).append(' '); 567 a.append(c.getName().statementName); 568 a.append(' ').append(Token.T_UNIQUE); 569 570 int[] col = c.getMainColumns(); 571 572 getColumnList(c.getMain(), col, col.length, a); 573 break; 574 575 case Constraint.FOREIGN_KEY : 576 577 Table maintable = c.getMain(); 579 int maintableindex = 580 database.schemaManager.getTableIndex(maintable); 581 582 if (maintableindex > i) { 583 forwardFK.add(c); 584 } else { 585 a.append(','); 586 getFKStatement(c, a); 587 } 588 break; 589 590 case Constraint.CHECK : 591 try { 592 a.append(',').append(Token.T_CONSTRAINT).append(' '); 593 a.append(c.getName().statementName); 594 a.append(' ').append(Token.T_CHECK).append('('); 595 a.append(c.core.check.getDDL()); 596 a.append(')'); 597 } catch (HsqlException e) { 598 599 } 601 break; 602 } 603 } 604 605 a.append(')'); 606 607 if (t.onCommitPreserve) { 608 a.append(' ').append(Token.T_ON).append(' '); 609 a.append(Token.T_COMMIT).append(' ').append(Token.T_PRESERVE); 610 a.append(' ').append(Token.T_ROWS); 611 } 612 } 613 614 618 static String getDataSource(Table t) { 619 620 String dataSource = t.getDataSource(); 621 622 if (dataSource == null) { 623 return null; 624 } 625 626 boolean isDesc = t.isDescDataSource(); 627 StringBuffer a = new StringBuffer (128); 628 629 a.append(Token.T_SET).append(' ').append(Token.T_TABLE).append(' '); 630 a.append(t.getName().statementName); 631 a.append(' ').append(Token.T_SOURCE).append(' ').append('"'); 632 a.append(dataSource); 633 a.append('"'); 634 635 if (isDesc) { 636 a.append(' ').append(Token.T_DESC); 637 } 638 639 return a.toString(); 640 } 641 642 646 static String getDataSourceHeader(Table t) { 647 648 String header = t.getHeader(); 649 650 if (header == null) { 651 return null; 652 } 653 654 StringBuffer a = new StringBuffer (128); 655 656 a.append(Token.T_SET).append(' ').append(Token.T_TABLE).append(' '); 657 a.append(t.getName().statementName); 658 a.append(' ').append(Token.T_SOURCE).append(' '); 659 a.append(Token.T_HEADER).append(' '); 660 a.append(header); 661 662 return a.toString(); 663 } 664 665 668 private static void getColumnList(Table t, int[] col, int len, 669 StringBuffer a) { 670 671 a.append('('); 672 673 for (int i = 0; i < len; i++) { 674 a.append(t.getColumn(col[i]).columnName.statementName); 675 676 if (i < len - 1) { 677 a.append(','); 678 } 679 } 680 681 a.append(')'); 682 } 683 684 687 private static void getFKStatement(Constraint c, StringBuffer a) { 688 689 a.append(Token.T_CONSTRAINT).append(' '); 690 a.append(c.getName().statementName); 691 a.append(' ').append(Token.T_FOREIGN).append(' ').append(Token.T_KEY); 692 693 int[] col = c.getRefColumns(); 694 695 getColumnList(c.getRef(), col, col.length, a); 696 a.append(' ').append(Token.T_REFERENCES).append(' '); 697 a.append(c.getMain().getName().statementName); 698 699 col = c.getMainColumns(); 700 701 getColumnList(c.getMain(), col, col.length, a); 702 703 if (c.getDeleteAction() != Constraint.NO_ACTION) { 704 a.append(' ').append(Token.T_ON).append(' ').append( 705 Token.T_DELETE).append(' '); 706 a.append(getFKAction(c.getDeleteAction())); 707 } 708 709 if (c.getUpdateAction() != Constraint.NO_ACTION) { 710 a.append(' ').append(Token.T_ON).append(' ').append( 711 Token.T_UPDATE).append(' '); 712 a.append(getFKAction(c.getUpdateAction())); 713 } 714 } 715 716 719 private static String getFKAction(int action) { 720 721 switch (action) { 722 723 case Constraint.CASCADE : 724 return Token.T_CASCADE; 725 726 case Constraint.SET_DEFAULT : 727 return Token.T_SET + ' ' + Token.T_DEFAULT; 728 729 case Constraint.SET_NULL : 730 return Token.T_SET + ' ' + Token.T_NULL; 731 732 default : 733 return Token.T_NO + ' ' + Token.T_ACTION; 734 } 735 } 736 737 740 private static void addRow(Result r, String sql) { 741 742 if (sql == null || sql.length() == 0) { 743 return; 744 } 745 746 String [] s = new String [1]; 747 748 s[0] = sql; 749 750 r.add(s); 751 } 752 753 765 private static void addRightsStatements(Database dDatabase, Result r) { 766 767 StringBuffer a; 768 HashMappedList userlist = dDatabase.getUserManager().getUsers(); 769 Iterator users = userlist.values().iterator(); 770 GranteeManager gm = dDatabase.getGranteeManager(); 771 Iterator grantees = gm.getGrantees().iterator(); 772 773 for (; users.hasNext(); ) { 774 User u = (User) users.next(); 775 String name = u.getName(); 776 777 if (!name.equals(Token.T_PUBLIC)) { 780 addRow(r, u.getCreateUserDDL()); 781 } 782 } 783 784 for (; grantees.hasNext(); ) { 787 Grantee g = (Grantee) grantees.next(); 788 String name = g.getName(); 789 790 if (name.equals("_SYSTEM") || name.equals("DBA")) { 792 continue; 793 } 794 795 String roleString = g.allRolesString(); 796 797 if (roleString != null) { 798 addRow(r, "GRANT " + roleString + " TO " + name); 799 } 800 801 IntValueHashMap rightsmap = g.getRights(); 802 803 if (rightsmap == null) { 804 continue; 805 } 806 807 Iterator dbobjects = rightsmap.keySet().iterator(); 808 809 while (dbobjects.hasNext()) { 810 Object nameobject = dbobjects.next(); 811 int right = rightsmap.get(nameobject, 0); 812 813 a = new StringBuffer (64); 814 815 a.append(Token.T_GRANT).append(' '); 816 a.append(GranteeManager.getRightsList(right)); 817 a.append(' ').append(Token.T_ON).append(' '); 818 819 if (nameobject instanceof String ) { 820 if (nameobject.equals("java.lang.Math") 821 || nameobject.equals("org.hsqldb.Library")) { 822 continue; 823 } 824 825 a.append("CLASS \""); 826 a.append((String ) nameobject); 827 a.append('\"'); 828 } else { 829 HsqlName hsqlname = (HsqlName) nameobject; 830 831 Table table = dDatabase.schemaManager.findUserTable(null, 833 hsqlname.name, hsqlname.schema.name); 834 835 if (table != null) { 837 a.append(hsqlname.schema.statementName).append( 838 '.').append(hsqlname.statementName); 839 } else { 840 continue; 841 } 842 } 843 844 a.append(' ').append(Token.T_TO).append(' '); 845 a.append(g.getName()); 846 addRow(r, a.toString()); 847 } 848 } 849 } 850 } 851 | Popular Tags |