001
014
015 package com.liferay.portal.dao.db;
016
017 import com.liferay.counter.service.CounterLocalServiceUtil;
018 import com.liferay.portal.dao.orm.common.SQLTransformer;
019 import com.liferay.portal.kernel.dao.db.DB;
020 import com.liferay.portal.kernel.dao.db.Index;
021 import com.liferay.portal.kernel.dao.jdbc.DataAccess;
022 import com.liferay.portal.kernel.exception.SystemException;
023 import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
024 import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
025 import com.liferay.portal.kernel.log.Log;
026 import com.liferay.portal.kernel.log.LogFactoryUtil;
027 import com.liferay.portal.kernel.util.FileUtil;
028 import com.liferay.portal.kernel.util.GetterUtil;
029 import com.liferay.portal.kernel.util.PropertiesUtil;
030 import com.liferay.portal.kernel.util.StringBundler;
031 import com.liferay.portal.kernel.util.StringPool;
032 import com.liferay.portal.kernel.util.StringUtil;
033 import com.liferay.portal.kernel.util.Validator;
034 import com.liferay.portal.util.ClassLoaderUtil;
035 import com.liferay.portal.velocity.VelocityUtil;
036 import com.liferay.util.SimpleCounter;
037
038 import java.io.File;
039 import java.io.FileReader;
040 import java.io.IOException;
041 import java.io.InputStream;
042
043 import java.sql.Connection;
044 import java.sql.SQLException;
045 import java.sql.Statement;
046
047 import java.util.Collections;
048 import java.util.Enumeration;
049 import java.util.HashMap;
050 import java.util.HashSet;
051 import java.util.List;
052 import java.util.Map;
053 import java.util.Properties;
054 import java.util.Set;
055 import java.util.regex.Matcher;
056 import java.util.regex.Pattern;
057
058 import javax.naming.NamingException;
059
060
066 public abstract class BaseDB implements DB {
067
068 @Override
069 public void addIndexes(
070 Connection con, String indexesSQL, Set<String> validIndexNames)
071 throws IOException {
072
073 if (_log.isInfoEnabled()) {
074 _log.info("Adding indexes");
075 }
076
077 UnsyncBufferedReader bufferedReader = new UnsyncBufferedReader(
078 new UnsyncStringReader(indexesSQL));
079
080 String sql = null;
081
082 while ((sql = bufferedReader.readLine()) != null) {
083 if (Validator.isNull(sql)) {
084 continue;
085 }
086
087 int y = sql.indexOf(" on ");
088 int x = sql.lastIndexOf(" ", y - 1);
089
090 String indexName = sql.substring(x + 1, y);
091
092 if (validIndexNames.contains(indexName)) {
093 continue;
094 }
095
096 if (_log.isInfoEnabled()) {
097 _log.info(sql);
098 }
099
100 try {
101 runSQL(con, sql);
102 }
103 catch (Exception e) {
104 if (_log.isWarnEnabled()) {
105 _log.warn(e.getMessage() + ": " + sql);
106 }
107 }
108 }
109 }
110
111 @Override
112 public void buildCreateFile(String sqlDir, String databaseName)
113 throws IOException {
114
115 buildCreateFile(sqlDir, databaseName, POPULATED);
116 buildCreateFile(sqlDir, databaseName, MINIMAL);
117 buildCreateFile(sqlDir, databaseName, SHARDED);
118 }
119
120 @Override
121 public void buildCreateFile(
122 String sqlDir, String databaseName, int population)
123 throws IOException {
124
125 String suffix = getSuffix(population);
126
127 File file = new File(
128 sqlDir + "/create" + suffix + "/create" + suffix + "-" +
129 getServerName() + ".sql");
130
131 if (population != SHARDED) {
132 String content = buildCreateFileContent(
133 sqlDir, databaseName, population);
134
135 if (content != null) {
136 FileUtil.write(file, content);
137 }
138 }
139 else {
140 String content = buildCreateFileContent(
141 sqlDir, databaseName, MINIMAL);
142
143 if (content != null) {
144 FileUtil.write(file, content);
145 }
146
147 content = buildCreateFileContent(
148 sqlDir, databaseName + "1", MINIMAL);
149
150 if (content != null) {
151 FileUtil.write(file, content, false, true);
152 }
153
154 content = buildCreateFileContent(
155 sqlDir, databaseName + "2", MINIMAL);
156
157 if (content != null) {
158 FileUtil.write(file, content, false, true);
159 }
160 }
161 }
162
163 @Override
164 public abstract String buildSQL(String template) throws IOException;
165
166 @Override
167 public void buildSQLFile(String sqlDir, String fileName)
168 throws IOException {
169
170 String template = buildTemplate(sqlDir, fileName);
171
172 if (Validator.isNull(template)) {
173 return;
174 }
175
176 template = buildSQL(template);
177
178 FileUtil.write(
179 sqlDir + "/" + fileName + "/" + fileName + "-" + getServerName() +
180 ".sql",
181 template);
182 }
183
184 @Override
185 @SuppressWarnings("unused")
186 public List<Index> getIndexes(Connection con) throws SQLException {
187 return Collections.emptyList();
188 }
189
190 @Override
191 public String getTemplateFalse() {
192 return getTemplate()[2];
193 }
194
195 @Override
196 public String getTemplateTrue() {
197 return getTemplate()[1];
198 }
199
200 @Override
201 public String getType() {
202 return _type;
203 }
204
205 @Override
206 public long increment() throws SystemException {
207 return CounterLocalServiceUtil.increment();
208 }
209
210 @Override
211 public long increment(String name) throws SystemException {
212 return CounterLocalServiceUtil.increment(name);
213 }
214
215 @Override
216 public boolean isSupportsAlterColumnName() {
217 return _SUPPORTS_ALTER_COLUMN_NAME;
218 }
219
220 @Override
221 public boolean isSupportsAlterColumnType() {
222 return _SUPPORTS_ALTER_COLUMN_TYPE;
223 }
224
225 @Override
226 public boolean isSupportsDateMilliseconds() {
227 return _SUPPORTS_DATE_MILLISECONDS;
228 }
229
230 @Override
231 public boolean isSupportsInlineDistinct() {
232 return _SUPPORTS_INLINE_DISTINCT;
233 }
234
235 @Override
236 public boolean isSupportsScrollableResults() {
237 return _SUPPORTS_SCROLLABLE_RESULTS;
238 }
239
240 @Override
241 public boolean isSupportsStringCaseSensitiveQuery() {
242 return _supportsStringCaseSensitiveQuery;
243 }
244
245 @Override
246 public boolean isSupportsUpdateWithInnerJoin() {
247 return _SUPPORTS_UPDATE_WITH_INNER_JOIN;
248 }
249
250 @Override
251 public void runSQL(Connection con, String sql)
252 throws IOException, SQLException {
253
254 runSQL(con, new String[] {sql});
255 }
256
257 @Override
258 public void runSQL(Connection con, String[] sqls)
259 throws IOException, SQLException {
260
261 Statement s = null;
262
263 try {
264 s = con.createStatement();
265
266 for (int i = 0; i < sqls.length; i++) {
267 String sql = buildSQL(sqls[i]);
268
269 sql = SQLTransformer.transform(sql.trim());
270
271 if (sql.endsWith(";")) {
272 sql = sql.substring(0, sql.length() - 1);
273 }
274
275 if (sql.endsWith("go")) {
276 sql = sql.substring(0, sql.length() - 2);
277 }
278
279 if (_log.isDebugEnabled()) {
280 _log.debug(sql);
281 }
282
283 try {
284 s.executeUpdate(sql);
285 }
286 catch (SQLException sqle) {
287 handleSQLException(sql, sqle);
288 }
289 }
290 }
291 finally {
292 DataAccess.cleanUp(s);
293 }
294 }
295
296 @Override
297 public void runSQL(String sql) throws IOException, SQLException {
298 runSQL(new String[] {sql});
299 }
300
301 @Override
302 public void runSQL(String[] sqls) throws IOException, SQLException {
303 Connection con = DataAccess.getConnection();
304
305 try {
306 runSQL(con, sqls);
307 }
308 finally {
309 DataAccess.cleanUp(con);
310 }
311 }
312
313 @Override
314 public void runSQLTemplate(String path)
315 throws IOException, NamingException, SQLException {
316
317 runSQLTemplate(path, true);
318 }
319
320 @Override
321 public void runSQLTemplate(String path, boolean failOnError)
322 throws IOException, NamingException, SQLException {
323
324 ClassLoader classLoader = ClassLoaderUtil.getContextClassLoader();
325
326 InputStream is = classLoader.getResourceAsStream(
327 "com/liferay/portal/tools/sql/dependencies/" + path);
328
329 if (is == null) {
330 is = classLoader.getResourceAsStream(path);
331 }
332
333 if (is == null) {
334 _log.error("Invalid path " + path);
335
336 if (failOnError) {
337 throw new IOException("Invalid path " + path);
338 }
339 else {
340 return;
341 }
342 }
343
344 String template = StringUtil.read(is);
345
346 is.close();
347
348 boolean evaluate = path.endsWith(".vm");
349
350 runSQLTemplateString(template, evaluate, failOnError);
351 }
352
353 @Override
354 public void runSQLTemplateString(
355 String template, boolean evaluate, boolean failOnError)
356 throws IOException, NamingException, SQLException {
357
358 if (evaluate) {
359 try {
360 template = evaluateVM(template);
361 }
362 catch (Exception e) {
363 _log.error(e, e);
364 }
365 }
366
367 StringBundler sb = new StringBundler();
368
369 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
370 new UnsyncStringReader(template));
371
372 String line = null;
373
374 while ((line = unsyncBufferedReader.readLine()) != null) {
375 if (!line.startsWith("##")) {
376 if (line.startsWith("@include ")) {
377 int pos = line.indexOf(" ");
378
379 String includeFileName = line.substring(pos + 1);
380
381 ClassLoader classLoader =
382 ClassLoaderUtil.getContextClassLoader();
383
384 InputStream is = classLoader.getResourceAsStream(
385 "com/liferay/portal/tools/sql/dependencies/" +
386 includeFileName);
387
388 if (is == null) {
389 is = classLoader.getResourceAsStream(includeFileName);
390 }
391
392 String include = StringUtil.read(is);
393
394 is.close();
395
396 if (includeFileName.endsWith(".vm")) {
397 try {
398 include = evaluateVM(include);
399 }
400 catch (Exception e) {
401 _log.error(e, e);
402 }
403 }
404
405 include = convertTimestamp(include);
406 include = replaceTemplate(include, getTemplate());
407
408 runSQLTemplateString(include, false, true);
409 }
410 else {
411 sb.append(line);
412
413 if (line.endsWith(";")) {
414 String sql = sb.toString();
415
416 sb.setIndex(0);
417
418 try {
419 if (!sql.equals("COMMIT_TRANSACTION;")) {
420 runSQL(sql);
421 }
422 else {
423 if (_log.isDebugEnabled()) {
424 _log.debug("Skip commit sql");
425 }
426 }
427 }
428 catch (IOException ioe) {
429 if (failOnError) {
430 throw ioe;
431 }
432 else if (_log.isWarnEnabled()) {
433 _log.warn(ioe.getMessage());
434 }
435 }
436 catch (SecurityException se) {
437 if (failOnError) {
438 throw se;
439 }
440 else if (_log.isWarnEnabled()) {
441 _log.warn(se.getMessage());
442 }
443 }
444 catch (SQLException sqle) {
445 if (failOnError) {
446 throw sqle;
447 }
448 else if (_log.isWarnEnabled()) {
449 String message = GetterUtil.getString(
450 sqle.getMessage());
451
452 if (!message.startsWith("Duplicate key name")) {
453 _log.warn(message + ": " + buildSQL(sql));
454 }
455
456 if (message.startsWith("Duplicate entry") ||
457 message.startsWith(
458 "Specified key was too long")) {
459
460 _log.error(line);
461 }
462 }
463 }
464 }
465 }
466 }
467 }
468
469 unsyncBufferedReader.close();
470 }
471
472 @Override
473 public void setSupportsStringCaseSensitiveQuery(
474 boolean supportsStringCaseSensitiveQuery) {
475
476 if (_log.isInfoEnabled()) {
477 if (supportsStringCaseSensitiveQuery) {
478 _log.info("Database supports case sensitive queries");
479 }
480 else {
481 _log.info("Database does not support case sensitive queries");
482 }
483 }
484
485 _supportsStringCaseSensitiveQuery = supportsStringCaseSensitiveQuery;
486 }
487
488 @Override
489 public void updateIndexes(
490 Connection con, String tablesSQL, String indexesSQL,
491 String indexesProperties, boolean dropIndexes)
492 throws IOException, SQLException {
493
494 List<Index> indexes = getIndexes(con);
495
496 Set<String> validIndexNames = null;
497
498 if (dropIndexes) {
499 validIndexNames = dropIndexes(
500 con, tablesSQL, indexesSQL, indexesProperties, indexes);
501 }
502 else {
503 validIndexNames = new HashSet<String>();
504
505 for (Index index : indexes) {
506 String indexName = index.getIndexName().toUpperCase();
507
508 validIndexNames.add(indexName);
509 }
510 }
511
512 addIndexes(con, indexesSQL, validIndexNames);
513 }
514
515 protected BaseDB(String type) {
516 _type = type;
517
518 String[] actual = getTemplate();
519
520 for (int i = 0; i < TEMPLATE.length; i++) {
521 _templateMap.put(TEMPLATE[i], actual[i]);
522 }
523 }
524
525 protected String[] buildColumnNameTokens(String line) {
526 String[] words = StringUtil.split(line, ' ');
527
528 String nullable = "";
529
530 if (words.length == 7) {
531 nullable = "not null;";
532 }
533
534 String[] template = {
535 words[1], words[2], words[3], words[4], nullable
536 };
537
538 return template;
539 }
540
541 protected String[] buildColumnTypeTokens(String line) {
542 String[] words = StringUtil.split(line, ' ');
543
544 String nullable = "";
545
546 if (words.length == 6) {
547 nullable = "not null;";
548 }
549 else if (words.length == 5) {
550 nullable = words[4];
551 }
552 else if (words.length == 4) {
553 nullable = "not null;";
554
555 if (words[3].endsWith(";")) {
556 words[3] = words[3].substring(0, words[3].length() - 1);
557 }
558 }
559
560 String[] template = {
561 words[1], words[2], "", words[3], nullable
562 };
563
564 return template;
565 }
566
567 protected abstract String buildCreateFileContent(
568 String sqlDir, String databaseName, int population)
569 throws IOException;
570
571 protected String[] buildTableNameTokens(String line) {
572 String[] words = StringUtil.split(line, StringPool.SPACE);
573
574 return new String[] {words[1], words[2]};
575 }
576
577 protected String buildTemplate(String sqlDir, String fileName)
578 throws IOException {
579
580 String template = readFile(sqlDir + "/" + fileName + ".sql");
581
582 if (fileName.equals("portal") || fileName.equals("portal-minimal") ||
583 fileName.equals("update-5.0.1-5.1.0")) {
584
585 UnsyncBufferedReader unsyncBufferedReader =
586 new UnsyncBufferedReader(new UnsyncStringReader(template));
587
588 StringBundler sb = new StringBundler();
589
590 String line = null;
591
592 while ((line = unsyncBufferedReader.readLine()) != null) {
593 if (line.startsWith("@include ")) {
594 int pos = line.indexOf(" ");
595
596 String includeFileName = line.substring(pos + 1);
597
598 File includeFile = new File(sqlDir + "/" + includeFileName);
599
600 if (!includeFile.exists()) {
601 continue;
602 }
603
604 String include = FileUtil.read(includeFile);
605
606 if (includeFileName.endsWith(".vm")) {
607 try {
608 include = evaluateVM(include);
609 }
610 catch (Exception e) {
611 _log.error(e, e);
612 }
613 }
614
615 include = convertTimestamp(include);
616 include = replaceTemplate(include, getTemplate());
617
618 sb.append(include);
619 sb.append("\n\n");
620 }
621 else {
622 sb.append(line);
623 sb.append("\n");
624 }
625 }
626
627 unsyncBufferedReader.close();
628
629 template = sb.toString();
630 }
631
632 if (fileName.equals("indexes") && (this instanceof SybaseDB)) {
633 template = removeBooleanIndexes(sqlDir, template);
634 }
635
636 return template;
637 }
638
639 protected String convertTimestamp(String data) {
640 String s = null;
641
642 if (this instanceof MySQLDB) {
643 s = StringUtil.replace(data, "SPECIFIC_TIMESTAMP_", "");
644 }
645 else {
646 Matcher matcher = _timestampPattern.matcher(data);
647
648 s = matcher.replaceAll("CURRENT_TIMESTAMP");
649 }
650
651 return s;
652 }
653
654 protected Set<String> dropIndexes(
655 Connection con, String tablesSQL, String indexesSQL,
656 String indexesProperties, List<Index> indexes)
657 throws IOException, SQLException {
658
659 if (_log.isInfoEnabled()) {
660 _log.info("Dropping stale indexes");
661 }
662
663 Set<String> validIndexNames = new HashSet<String>();
664
665 if (indexes.isEmpty()) {
666 return validIndexNames;
667 }
668
669 String tablesSQLLowerCase = tablesSQL.toLowerCase();
670 String indexesSQLLowerCase = indexesSQL.toLowerCase();
671
672 Properties indexesPropertiesObj = PropertiesUtil.load(
673 indexesProperties);
674
675 Enumeration<String> enu =
676 (Enumeration<String>)indexesPropertiesObj.propertyNames();
677
678 while (enu.hasMoreElements()) {
679 String key = enu.nextElement();
680
681 String value = indexesPropertiesObj.getProperty(key);
682
683 indexesPropertiesObj.setProperty(key.toLowerCase(), value);
684 }
685
686 for (Index index : indexes) {
687 String indexNameUpperCase = index.getIndexName().toUpperCase();
688 String indexNameLowerCase = indexNameUpperCase.toLowerCase();
689 String tableName = index.getTableName();
690 String tableNameLowerCase = tableName.toLowerCase();
691 boolean unique = index.isUnique();
692
693 validIndexNames.add(indexNameUpperCase);
694
695 if (indexesPropertiesObj.containsKey(indexNameLowerCase)) {
696 if (unique &&
697 indexesSQLLowerCase.contains(
698 "create unique index " + indexNameLowerCase + " ")) {
699
700 continue;
701 }
702
703 if (!unique &&
704 indexesSQLLowerCase.contains(
705 "create index " + indexNameLowerCase + " ")) {
706
707 continue;
708 }
709 }
710 else if (!tablesSQLLowerCase.contains(
711 "create table " + tableNameLowerCase + " (")) {
712
713 continue;
714 }
715
716 validIndexNames.remove(indexNameUpperCase);
717
718 String sql =
719 "drop index " + indexNameUpperCase + " on " + tableName;
720
721 if (_log.isInfoEnabled()) {
722 _log.info(sql);
723 }
724
725 runSQL(con, sql);
726 }
727
728 return validIndexNames;
729 }
730
731 protected String evaluateVM(String template) throws Exception {
732 Map<String, Object> variables = new HashMap<String, Object>();
733
734 variables.put("counter", new SimpleCounter());
735
736 ClassLoader classLoader = ClassLoaderUtil.getContextClassLoader();
737
738 try {
739 ClassLoaderUtil.setContextClassLoader(
740 ClassLoaderUtil.getPortalClassLoader());
741
742 template = VelocityUtil.evaluate(template, variables);
743 }
744 finally {
745 ClassLoaderUtil.setContextClassLoader(classLoader);
746 }
747
748
749
750 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
751 new UnsyncStringReader(template));
752
753 StringBundler sb = new StringBundler();
754
755 String line = null;
756
757 while ((line = unsyncBufferedReader.readLine()) != null) {
758 line = line.trim();
759
760 sb.append(line);
761 sb.append("\n");
762 }
763
764 unsyncBufferedReader.close();
765
766 template = sb.toString();
767 template = StringUtil.replace(template, "\n\n\n", "\n\n");
768
769 return template;
770 }
771
772 protected String getCreateTablesContent(String sqlDir, String suffix)
773 throws IOException {
774
775 StringBundler sb = new StringBundler(8);
776
777 sb.append(sqlDir);
778
779 if (!sqlDir.endsWith("/WEB-INF/sql")) {
780 sb.append("/portal");
781 sb.append(suffix);
782 sb.append("/portal");
783 }
784 else {
785 sb.append("/tables");
786 sb.append(suffix);
787 sb.append("/tables");
788 }
789
790 sb.append(suffix);
791 sb.append(StringPool.DASH);
792 sb.append(getServerName());
793 sb.append(".sql");
794
795 return readFile(sb.toString());
796 }
797
798 protected abstract String getServerName();
799
800 protected String getSuffix(int type) {
801 if (type == MINIMAL) {
802 return "-minimal";
803 }
804 else if (type == SHARDED) {
805 return "-sharded";
806 }
807 else {
808 return StringPool.BLANK;
809 }
810 }
811
812 protected abstract String[] getTemplate();
813
814 protected void handleSQLException(String sql, SQLException sqle)
815 throws SQLException {
816
817 if (_log.isDebugEnabled()) {
818 StringBundler sb = new StringBundler(18);
819
820 sb.append("SQL: ");
821 sb.append(sql);
822 sb.append("\nSQL state: ");
823 sb.append(sqle.getSQLState());
824 sb.append("\nVendor: ");
825 sb.append(getType());
826 sb.append("\nVendor error code: ");
827 sb.append(sqle.getErrorCode());
828 sb.append("\nVendor error message: ");
829 sb.append(sqle.getMessage());
830
831 _log.debug(sb.toString());
832 }
833
834 throw sqle;
835 }
836
837 protected String readFile(String fileName) throws IOException {
838 if (FileUtil.exists(fileName)) {
839 return FileUtil.read(fileName);
840 }
841 else {
842 return StringPool.BLANK;
843 }
844 }
845
846 protected String readSQL(String fileName, String comments, String eol)
847 throws IOException {
848
849 if (!FileUtil.exists(fileName)) {
850 return StringPool.BLANK;
851 }
852
853 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
854 new FileReader(new File(fileName)));
855
856 StringBundler sb = new StringBundler();
857
858 String line = null;
859
860 while ((line = unsyncBufferedReader.readLine()) != null) {
861 if (!line.startsWith(comments)) {
862 line = StringUtil.replace(
863 line, new String[] {"\n", "\t"}, new String[] {"", ""});
864
865 if (line.endsWith(";")) {
866 sb.append(line.substring(0, line.length() - 1));
867 sb.append(eol);
868 }
869 else {
870 sb.append(line);
871 }
872 }
873 }
874
875 unsyncBufferedReader.close();
876
877 return sb.toString();
878 }
879
880 protected String removeBooleanIndexes(String sqlDir, String data)
881 throws IOException {
882
883 String portalData = readFile(sqlDir + "/portal-tables.sql");
884
885 if (Validator.isNull(portalData)) {
886 return StringPool.BLANK;
887 }
888
889 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
890 new UnsyncStringReader(data));
891
892 StringBundler sb = new StringBundler();
893
894 String line = null;
895
896 while ((line = unsyncBufferedReader.readLine()) != null) {
897 boolean append = true;
898
899 int x = line.indexOf(" on ");
900
901 if (x != -1) {
902 int y = line.indexOf(" (", x);
903
904 String table = line.substring(x + 4, y);
905
906 x = y + 2;
907 y = line.indexOf(")", x);
908
909 String[] columns = StringUtil.split(line.substring(x, y));
910
911 x = portalData.indexOf("create table " + table + " (");
912 y = portalData.indexOf(");", x);
913
914 String portalTableData = portalData.substring(x, y);
915
916 for (int i = 0; i < columns.length; i++) {
917 if (portalTableData.contains(
918 columns[i].trim() + " BOOLEAN")) {
919
920 append = false;
921
922 break;
923 }
924 }
925 }
926
927 if (append) {
928 sb.append(line);
929 sb.append("\n");
930 }
931 }
932
933 unsyncBufferedReader.close();
934
935 return sb.toString();
936 }
937
938 protected String removeInserts(String data) throws IOException {
939 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
940 new UnsyncStringReader(data));
941
942 StringBundler sb = new StringBundler();
943
944 String line = null;
945
946 while ((line = unsyncBufferedReader.readLine()) != null) {
947 if (!line.startsWith("insert into ") &&
948 !line.startsWith("update ")) {
949
950 sb.append(line);
951 sb.append("\n");
952 }
953 }
954
955 unsyncBufferedReader.close();
956
957 return sb.toString();
958 }
959
960 protected String removeLongInserts(String data) throws IOException {
961 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
962 new UnsyncStringReader(data));
963
964 StringBundler sb = new StringBundler();
965
966 String line = null;
967
968 while ((line = unsyncBufferedReader.readLine()) != null) {
969 if (!line.startsWith("insert into Image (") &&
970 !line.startsWith("insert into JournalArticle (") &&
971 !line.startsWith("insert into JournalStructure (") &&
972 !line.startsWith("insert into JournalTemplate (")) {
973
974 sb.append(line);
975 sb.append("\n");
976 }
977 }
978
979 unsyncBufferedReader.close();
980
981 return sb.toString();
982 }
983
984 protected String removeNull(String content) {
985 content = StringUtil.replace(content, " = null", " = NULL");
986 content = StringUtil.replace(content, " is null", " IS NULL");
987 content = StringUtil.replace(content, " not null", " not_null");
988 content = StringUtil.replace(content, " null", "");
989 content = StringUtil.replace(content, " not_null", " not null");
990
991 return content;
992 }
993
994 protected String replaceTemplate(String template, String[] actual) {
995 if ((template == null) || (TEMPLATE == null) || (actual == null)) {
996 return null;
997 }
998
999 if (TEMPLATE.length != actual.length) {
1000 return template;
1001 }
1002
1003 StringBundler sb = null;
1004
1005 int endIndex = 0;
1006
1007 Matcher matcher = _templatePattern.matcher(template);
1008
1009 while (matcher.find()) {
1010 int startIndex = matcher.start();
1011
1012 if (sb == null) {
1013 sb = new StringBundler();
1014 }
1015
1016 sb.append(template.substring(endIndex, startIndex));
1017
1018 endIndex = matcher.end();
1019
1020 String matched = template.substring(startIndex, endIndex);
1021
1022 sb.append(_templateMap.get(matched));
1023 }
1024
1025 if (sb == null) {
1026 return template;
1027 }
1028
1029 if (template.length() > endIndex) {
1030 sb.append(template.substring(endIndex));
1031 }
1032
1033 return sb.toString();
1034 }
1035
1036 protected abstract String reword(String data) throws IOException;
1037
1038 protected static final String ALTER_COLUMN_NAME = "alter_column_name ";
1039
1040 protected static final String ALTER_COLUMN_TYPE = "alter_column_type ";
1041
1042 protected static final String ALTER_TABLE_NAME = "alter_table_name ";
1043
1044 protected static final String DROP_INDEX = "drop index";
1045
1046 protected static final String DROP_PRIMARY_KEY = "drop primary key";
1047
1048 protected static final String[] RENAME_TABLE_TEMPLATE = {
1049 "@old-table@", "@new-table@"
1050 };
1051
1052 protected static final String[] REWORD_TEMPLATE = {
1053 "@table@", "@old-column@", "@new-column@", "@type@", "@nullable@"
1054 };
1055
1056 protected static final String[] TEMPLATE = {
1057 "##", "TRUE", "FALSE", "'01/01/1970'", "CURRENT_TIMESTAMP", " BLOB",
1058 " SBLOB", " BOOLEAN", " DATE", " DOUBLE", " INTEGER", " LONG",
1059 " STRING", " TEXT", " VARCHAR", " IDENTITY", "COMMIT_TRANSACTION"
1060 };
1061
1062 private static final boolean _SUPPORTS_ALTER_COLUMN_NAME = true;
1063
1064 private static final boolean _SUPPORTS_ALTER_COLUMN_TYPE = true;
1065
1066 private static final boolean _SUPPORTS_DATE_MILLISECONDS = true;
1067
1068 private static final boolean _SUPPORTS_INLINE_DISTINCT = true;
1069
1070 private static final boolean _SUPPORTS_SCROLLABLE_RESULTS = true;
1071
1072 private static final boolean _SUPPORTS_UPDATE_WITH_INNER_JOIN = true;
1073
1074 private static Log _log = LogFactoryUtil.getLog(BaseDB.class);
1075
1076 private static Pattern _templatePattern;
1077 private static Pattern _timestampPattern = Pattern.compile(
1078 "SPECIFIC_TIMESTAMP_\\d+");
1079
1080 private boolean _supportsStringCaseSensitiveQuery;
1081 private Map<String, String> _templateMap = new HashMap<String, String>();
1082 private String _type;
1083
1084 static {
1085 StringBundler sb = new StringBundler(TEMPLATE.length * 3 - 3);
1086
1087 for (int i = 0; i < TEMPLATE.length; i++) {
1088 String variable = TEMPLATE[i];
1089
1090 if (variable.equals("##") || variable.equals("'01/01/1970'")) {
1091 sb.append(variable);
1092 }
1093 else {
1094 sb.append(variable);
1095 sb.append("\\b");
1096 }
1097
1098 if (i < (TEMPLATE.length - 1)) {
1099 sb.append(StringPool.PIPE);
1100 }
1101 }
1102
1103 _templatePattern = Pattern.compile(sb.toString());
1104 }
1105
1106 }