001/* 002 * Copyright 2018 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.contentio.export.component; 017 018import java.io.IOException; 019import java.sql.Connection; 020import java.sql.PreparedStatement; 021import java.sql.SQLException; 022import java.util.ArrayList; 023import java.util.HashMap; 024import java.util.LinkedHashMap; 025import java.util.List; 026import java.util.Map; 027import java.util.Map.Entry; 028import java.util.regex.Matcher; 029import java.util.regex.Pattern; 030 031import org.apache.avalon.framework.component.Component; 032import org.apache.avalon.framework.context.ContextException; 033import org.apache.avalon.framework.service.ServiceException; 034import org.apache.avalon.framework.service.ServiceManager; 035import org.apache.avalon.framework.service.Serviceable; 036import org.apache.commons.lang.StringUtils; 037 038import org.ametys.cms.contenttype.ContentType; 039import org.ametys.cms.contenttype.ContentTypeExtensionPoint; 040import org.ametys.cms.contenttype.MetadataDefinition; 041import org.ametys.cms.contenttype.MetadataDefinitionHolder; 042import org.ametys.cms.contenttype.MetadataType; 043import org.ametys.cms.contenttype.RepeaterDefinition; 044import org.ametys.cms.languages.LanguagesManager; 045import org.ametys.core.datasource.ConnectionHelper; 046import org.ametys.core.util.I18nUtils; 047import org.ametys.plugins.contentio.export.ExportManager; 048import org.ametys.plugins.contentio.export.object.ExportConfiguration; 049import org.ametys.plugins.contentio.export.object.ExportTableInfo; 050import org.ametys.runtime.config.Config; 051import org.ametys.runtime.i18n.I18nizableText; 052import org.ametys.runtime.plugin.component.AbstractLogEnabled; 053 054/** 055 * Create SQl Table Component 056 */ 057public class CreateSqlTableComponent extends AbstractLogEnabled implements Component, Serviceable 058{ 059 /** The component role */ 060 public static final String ROLE = CreateSqlTableComponent.class.getName(); 061 062 /** Code of default language for comments */ 063 public static final String DEFAULT_LANGUAGE_CODE_FOR_COMMENTS = "fr"; 064 065 /** The engine */ 066 public static final String MYSQL_CONTENT_EXPORT_ENGINE = "MyISAM"; 067 068 /** The encoding */ 069 public static final String MYSQL_CONTENT_EXPORT_CHARSET = "UTF8MB4"; 070 071 /** Prefix for parent table column */ 072 public static final String COLUMN_PARENT_TABLE_PREFIX = "PID_"; 073 074 private static final Pattern _MYSQL_VERSION_NUMBER_EXTRACT = Pattern.compile("^([0-9]+).*$"); 075 076 /** Content type extension point. */ 077 protected ContentTypeExtensionPoint _contentTypeExtensionPoint; 078 079 /** The i18n translator. */ 080 protected I18nUtils _i18nTranslator; 081 082 /** The normalise name component. */ 083 protected NormalizeNameComponent _normalizeNameComponent; 084 085 /** The language manager */ 086 protected LanguagesManager _languageManager; 087 088 private Connection _connection; 089 private String _databaseType; 090 091 private LinkedHashMap<String, ExportTableInfo> _tablesInfos; 092 private int _commentTableMaxLength; 093 private int _commentColumnMaxLength; 094 private String _sqlTablePrefix; 095 private String _sqlPrefixConf; 096 private Map<String, Map<String, String>> _mappingSql; 097 private Map<String, Map<String, String>> _reservedWords; 098 private String _mappingPolicy; 099 private ArrayList<String> _mappingTablesQueries; 100 private boolean _exportNoMultiValuedTable; 101 102 private int _fkIndice; 103 private int _pkIndice; 104 105 @Override 106 public void service(ServiceManager manager) throws ServiceException 107 { 108 _i18nTranslator = (I18nUtils) manager.lookup(I18nUtils.ROLE); 109 _contentTypeExtensionPoint = (ContentTypeExtensionPoint) manager.lookup(ContentTypeExtensionPoint.ROLE); 110 _normalizeNameComponent = (NormalizeNameComponent) manager.lookup(NormalizeNameComponent.ROLE); 111 _languageManager = (LanguagesManager) manager.lookup(LanguagesManager.ROLE); 112 } 113 114 /** 115 * Create sql tables for contents 116 * @param exportConfiguration the content export configuration 117 * @return tablesInfos 118 * @throws SQLException if a sql error occurred 119 * @throws ContextException if a context error occurred 120 * @throws IOException if an IO error occurred 121 */ 122 public synchronized Map<String, ExportTableInfo> createSqlTables(ExportConfiguration exportConfiguration) throws SQLException, ContextException, IOException 123 { 124 // Get from configuration 125 _sqlPrefixConf = exportConfiguration.getTablePrefix(); 126 _sqlTablePrefix = exportConfiguration.getTablePrefix(); 127 _mappingSql = exportConfiguration.getMappingSql(); 128 _mappingPolicy = exportConfiguration.getMappingPolicy(); 129 _reservedWords = exportConfiguration.getReservedWords(); 130 _exportNoMultiValuedTable = exportConfiguration.exportNoMultiValuedTable(); 131 132 // Initialization 133 _fkIndice = 1; 134 _pkIndice = 1; 135 _tablesInfos = new LinkedHashMap<>(); 136 _mappingTablesQueries = new ArrayList<>(); 137 138 try 139 { 140 String datasourceId = Config.getInstance().getValue("org.ametys.plugins.contentio.content.export.datasource"); 141 _connection = ConnectionHelper.getConnection(datasourceId); 142 _databaseType = ConnectionHelper.getDatabaseType(_connection); 143 144 String productVersion = _connection.getMetaData().getDatabaseProductVersion(); 145 initialize(productVersion); 146 147 boolean isInfoEnabled = getLogger().isInfoEnabled(); 148 if (isInfoEnabled) 149 { 150 getLogger().info(_i18nTranslator.translate(new I18nizableText("plugin.contentio", "PLUGINS_CONTENTIO_CONTENT_EXPORT_LOG_ANALYZE_TABLE_CREATE_BEGIN"))); 151 } 152 153 createTablesInfos(exportConfiguration.getContentTypesToExport()); 154 155 if (isInfoEnabled) 156 { 157 getLogger().info(_i18nTranslator.translate(new I18nizableText("plugin.contentio", "PLUGINS_CONTENTIO_CONTENT_EXPORT_LOG_ANALYZE_TABLE_CREATE_END"))); 158 getLogger().info(_i18nTranslator.translate(new I18nizableText("plugin.contentio", "PLUGINS_CONTENTIO_CONTENT_EXPORT_LOG_ANALYZE_TABLE_CREATE_MAPPING_BEGIN"))); 159 } 160 161 createMappingNameTableSql(); 162 163 if (isInfoEnabled) 164 { 165 getLogger().info(_i18nTranslator.translate(new I18nizableText("plugin.contentio", "PLUGINS_CONTENTIO_CONTENT_EXPORT_LOG_ANALYZE_TABLE_CREATE_MAPPING_END"))); 166 } 167 168 createRichTextDataTable(); 169 createContentTable(); 170 171 executeSqlQueries(); 172 } 173 finally 174 { 175 ConnectionHelper.cleanup(_connection); 176 } 177 178 return _tablesInfos; 179 } 180 181 /** 182 * Initialization 183 * @param productVersion The database product version 184 */ 185 protected void initialize(String productVersion) 186 { 187 // Get the maximun number of authorized characters for table and column comments 188 if (_databaseType.equals(ConnectionHelper.DATABASE_MYSQL)) 189 { 190 String[] parts = productVersion.split("\\."); 191 192 int majorVersion = Integer.parseInt(parts[0]); 193 int minorVersion = 0; 194 int patchVersion = 0; 195 if (parts.length > 1) 196 { 197 Matcher matcher = _MYSQL_VERSION_NUMBER_EXTRACT.matcher(parts[1]); 198 if (matcher.matches()) 199 { 200 minorVersion = Integer.parseInt(matcher.group(1)); 201 } 202 } 203 204 if (parts.length > 2) 205 { 206 Matcher matcher = _MYSQL_VERSION_NUMBER_EXTRACT.matcher(parts[2]); 207 if (matcher.matches()) 208 { 209 patchVersion = Integer.parseInt(matcher.group(1)); 210 } 211 } 212 213 if (majorVersion > 5 || (majorVersion >= 5 && minorVersion > 5) || (majorVersion >= 5 && minorVersion >= 5 && patchVersion >= 3)) 214 { 215 // Version 5.5.3 or later 216 _commentTableMaxLength = 2048; 217 _commentColumnMaxLength = 1024; 218 } 219 else 220 { 221 // Version before 5.5.3 222 _commentTableMaxLength = 60; 223 _commentColumnMaxLength = 255; 224 } 225 } 226 else 227 { 228 // No max 229 _commentTableMaxLength = 2048; 230 _commentColumnMaxLength = 1024; 231 } 232 } 233 234 /** 235 * Created all tables informations 236 * @param contents to export 237 * @throws SQLException if a sql error occurred 238 * @throws ContextException if a context error occurred 239 */ 240 protected void createTablesInfos(Map<String, String> contents) throws SQLException, ContextException 241 { 242 for (Entry<String, String> entry : contents.entrySet()) 243 { 244 String contentTypeId = entry.getKey(); 245 246 ContentType contentType = _contentTypeExtensionPoint.getExtension(contentTypeId); 247 if (!contentType.isAbstract()) 248 { 249 String tableName = entry.getValue(); 250 String comment = _i18nTranslator.translate(contentType.getLabel(), DEFAULT_LANGUAGE_CODE_FOR_COMMENTS) + ": " + _i18nTranslator.translate(contentType.getDescription(), DEFAULT_LANGUAGE_CODE_FOR_COMMENTS); 251 createSqlQueriesForTableCreation(contentType, tableName, null, comment, false); 252 } 253 _sqlTablePrefix = _sqlPrefixConf; 254 } 255 256 } 257 258 /** 259 * Create SQL queries to create necessary SQL tables for content type export 260 * @param metadataDef the metadata definition model The component holding metadata definitions 261 * @param tableName the table name The SQL table name 262 * @param tableParentName The SQL parent table name 263 * @param comment the comment 264 * @param isSortTable true if table's rows have to be ordered 265 * @throws ContextException if a context error occurred 266 */ 267 protected void createSqlQueriesForTableCreation(MetadataDefinitionHolder metadataDef, String tableName, String tableParentName, String comment, boolean isSortTable) throws ContextException 268 { 269 ExportTableInfo tableInfo = new ExportTableInfo(tableName); 270 tableInfo.incrementNbColumns(); 271 272 String tableNameNormalized = _normalizeNameComponent.normalizedTableName(_sqlTablePrefix, _mappingPolicy, tableName, _connection); 273 _tablesInfos.put(tableName, tableInfo); 274 275 StringBuilder currentCreateTableSQLQuery = new StringBuilder(); 276 277 currentCreateTableSQLQuery.append("CREATE TABLE "); 278 currentCreateTableSQLQuery.append(tableNameNormalized); 279 currentCreateTableSQLQuery.append(" ("); 280 currentCreateTableSQLQuery.append(_normalizeNameComponent.normalizedColumnName(_mappingPolicy, "id_" + tableName, tableName, _reservedWords, _connection)); 281 currentCreateTableSQLQuery.append(" VARCHAR(250)"); 282 currentCreateTableSQLQuery.append(createPrimaryKeyQuery()); 283 currentCreateTableSQLQuery.append(createCommentQuery(tableName, "id_" + tableName, "Ametys ID")); 284 285 if (StringUtils.isNotEmpty(tableParentName)) 286 { 287 currentCreateTableSQLQuery.append(", "); 288 addColumnParentId(currentCreateTableSQLQuery, tableParentName, tableName); 289 } 290 291 if (isSortTable) 292 { 293 currentCreateTableSQLQuery.append(", "); 294 addSortColumn(currentCreateTableSQLQuery, tableName); 295 } 296 297 addColumnForCompositeMetadata(metadataDef, currentCreateTableSQLQuery, tableName, ""); 298 addAdditionnalContentMetadata(metadataDef, currentCreateTableSQLQuery, tableName); 299 300 currentCreateTableSQLQuery.append(") "); 301 currentCreateTableSQLQuery.append(createEngineQuery()); 302 currentCreateTableSQLQuery.append(createCommentQuery(tableName, null, comment)); 303 304 tableInfo.addCreateQuery(currentCreateTableSQLQuery.toString()); 305 } 306 307 /** 308 * Create table for a multiple metadata 309 * @param metadataDef the metadata definition model 310 * @param tableParentName the table parent name 311 * @param tableName the table name 312 * @throws ContextException if a context error occurred 313 */ 314 protected void createSqlQueryForMultipleMetadata(MetadataDefinition metadataDef, String tableParentName, String tableName) throws ContextException 315 { 316 ExportTableInfo tableInfo = new ExportTableInfo(tableName); 317 tableInfo.incrementNbColumns(); 318 319 String normalizeTableName = _normalizeNameComponent.normalizedTableName(_sqlTablePrefix, _mappingPolicy, tableName, _connection); 320 _tablesInfos.put(tableName, tableInfo); 321 322 String normalizedColumnName = _normalizeNameComponent.normalizedColumnName(_mappingPolicy, COLUMN_PARENT_TABLE_PREFIX + tableParentName, tableName, _reservedWords, _connection); 323 324 StringBuilder currentCreateTableSQLQuery = new StringBuilder(); 325 currentCreateTableSQLQuery.append("CREATE TABLE "); 326 currentCreateTableSQLQuery.append(normalizeTableName); 327 currentCreateTableSQLQuery.append(" ("); 328 currentCreateTableSQLQuery.append(normalizedColumnName); 329 currentCreateTableSQLQuery.append(" VARCHAR(245)"); 330 currentCreateTableSQLQuery.append(createCommentQuery(tableName, COLUMN_PARENT_TABLE_PREFIX + tableParentName, "Parent ID of the multiple metadata")); 331 332 String fkName = normalizedColumnName; 333 String fkTableName = _normalizeNameComponent.normalizedTableName(_sqlTablePrefix, _mappingPolicy, tableParentName, _connection); 334 String fkColumnName = _normalizeNameComponent.normalizedColumnName(_mappingPolicy, "id_" + tableParentName, tableParentName, _reservedWords, _connection); 335 currentCreateTableSQLQuery.append(createForeignKeyQuery(fkName, fkTableName, fkColumnName)); 336 337 addColumnForSingleMetadata(metadataDef, currentCreateTableSQLQuery, tableName, metadataDef.getName()); 338 339 currentCreateTableSQLQuery.append(", "); 340 addSortColumn(currentCreateTableSQLQuery, tableName); 341 342 String primaryKey = "pk_" + _pkIndice; 343 _pkIndice++; 344 345 currentCreateTableSQLQuery.append(", CONSTRAINT "); 346 currentCreateTableSQLQuery.append(primaryKey); 347 currentCreateTableSQLQuery.append(" PRIMARY KEY ("); 348 currentCreateTableSQLQuery.append(normalizedColumnName); 349 currentCreateTableSQLQuery.append(", position)"); 350 currentCreateTableSQLQuery.append(") "); 351 currentCreateTableSQLQuery.append(createEngineQuery()); 352 353 String comment = "Multiple metadata " + metadataDef.getName() + " linked to the table" + _normalizeNameComponent.normalizedTableName(_sqlTablePrefix, _mappingPolicy, tableParentName, _connection); 354 currentCreateTableSQLQuery.append(createCommentQuery(tableName, null, comment)); 355 356 tableInfo.addCreateQuery(currentCreateTableSQLQuery.toString()); 357 } 358 359 /** 360 * Create table for images in rich text 361 * @throws ContextException if a context error occurred 362 */ 363 protected void createRichTextDataTable() throws ContextException 364 { 365 String dataTableName = _sqlTablePrefix + ExportManager.RICH_TEXT_DATA_TABLE_NAME; 366 ExportTableInfo tableInfo = new ExportTableInfo(dataTableName); 367 tableInfo.incrementNbColumns(8); 368 369 String dateTableNameNormalized = _normalizeNameComponent.normalizedTableName(_sqlTablePrefix, "FULL", dataTableName, _connection); 370 _tablesInfos.put(dataTableName, tableInfo); 371 372 StringBuilder currentCreateTableSQLQuery = new StringBuilder(); 373 374 currentCreateTableSQLQuery.append("CREATE TABLE "); 375 currentCreateTableSQLQuery.append(dateTableNameNormalized); 376 currentCreateTableSQLQuery.append(" (id_data VARCHAR(250)"); 377 currentCreateTableSQLQuery.append(createPrimaryKeyQuery()); 378 currentCreateTableSQLQuery.append(createCommentQuery(dataTableName, "id_data", "Data ID")); 379 currentCreateTableSQLQuery.append(", id_content VARCHAR(255)"); 380 currentCreateTableSQLQuery.append(createCommentQuery(dataTableName, "id_content", "Parent ID")); 381 382 currentCreateTableSQLQuery.append(", metadata_name "); 383 currentCreateTableSQLQuery.append(convertMetadataTypeToSql("string")); 384 currentCreateTableSQLQuery.append(createCommentQuery(dataTableName, "metadata_name", "Richtext metadata name")); 385 currentCreateTableSQLQuery.append(", data_name "); 386 currentCreateTableSQLQuery.append(convertMetadataTypeToSql("string")); 387 currentCreateTableSQLQuery.append(createCommentQuery(dataTableName, "data_name", "Name")); 388 389 currentCreateTableSQLQuery.append(", data "); 390 currentCreateTableSQLQuery.append(convertMetadataTypeToSql("file")); 391 currentCreateTableSQLQuery.append(createCommentQuery(dataTableName, "data", "Data")); 392 currentCreateTableSQLQuery.append(", data_mimetype VARCHAR(255)"); 393 currentCreateTableSQLQuery.append(createCommentQuery(dataTableName, "data_mimetype", "Mime type")); 394 currentCreateTableSQLQuery.append(", data_size INT"); 395 currentCreateTableSQLQuery.append(createCommentQuery(dataTableName, "data_size", "Size")); 396 currentCreateTableSQLQuery.append(", data_lastmodified "); 397 currentCreateTableSQLQuery.append(convertMetadataTypeToSql("datetime")); 398 currentCreateTableSQLQuery.append(createCommentQuery(dataTableName, "data_lastmodified", "Last modification date")); 399 currentCreateTableSQLQuery.append(", "); 400 401 addSortColumn(currentCreateTableSQLQuery, dataTableName); 402 403 currentCreateTableSQLQuery.append(") "); 404 currentCreateTableSQLQuery.append(createEngineQuery()); 405 406 String comment = "Data table of all rich text"; 407 currentCreateTableSQLQuery.append(createCommentQuery(dataTableName, null, comment)); 408 409 tableInfo.addCreateQuery(currentCreateTableSQLQuery.toString()); 410 } 411 412 /** 413 * Create table for metadata content 414 * @throws ContextException if a context error occurred 415 */ 416 protected void createContentTable() throws ContextException 417 { 418 String dataTableName = _sqlPrefixConf + ExportManager.CONTENT_TABLE_NAME; 419 ExportTableInfo tableInfo = new ExportTableInfo(dataTableName); 420 tableInfo.incrementNbColumns(2); 421 422 String dataTableNameNormalized = _normalizeNameComponent.normalizedTableName(_sqlTablePrefix, "FULL", dataTableName, _connection); 423 _tablesInfos.put(dataTableName, tableInfo); 424 425 StringBuilder currentCreateTableSQLQuery = new StringBuilder(); 426 427 currentCreateTableSQLQuery.append("CREATE TABLE "); 428 currentCreateTableSQLQuery.append(dataTableNameNormalized); 429 currentCreateTableSQLQuery.append(" (id_content VARCHAR(80)"); 430 currentCreateTableSQLQuery.append(createCommentQuery(dataTableName, "id_content", "Content ID")); 431 currentCreateTableSQLQuery.append(", table_name VARCHAR(170)"); 432 currentCreateTableSQLQuery.append(createCommentQuery(dataTableName, "table_name", "Table name")); 433 currentCreateTableSQLQuery.append(", CONSTRAINT pk_content PRIMARY KEY (id_content, table_name) "); 434 currentCreateTableSQLQuery.append(") "); 435 currentCreateTableSQLQuery.append(createEngineQuery()); 436 437 String comment = "Link table of content with it's own table"; 438 currentCreateTableSQLQuery.append(createCommentQuery(dataTableName, null, comment)); 439 440 tableInfo.addCreateQuery(currentCreateTableSQLQuery.toString()); 441 } 442 443 /** 444 * Create the table for the enumerator (key, value) 445 * @param metadataDef the metadata definition model 446 * @param tableParentName the table parent name 447 * @param tableName the table name 448 * @param columnName the column name 449 * @param currentCreateTableSQLQuery the current SQL create table query 450 * @throws ContextException if a context error occurred 451 */ 452 protected void createTableForEnumerator(MetadataDefinition metadataDef, String tableParentName, String tableName, String columnName, StringBuilder currentCreateTableSQLQuery) throws ContextException 453 { 454 ExportTableInfo tableInfo = new ExportTableInfo(tableName); 455 tableInfo.incrementNbColumns(); 456 457 String tableNameNormalized = _normalizeNameComponent.normalizedTableName(_sqlTablePrefix, _mappingPolicy, tableName, _connection); 458 _tablesInfos.put(tableName, tableInfo); 459 460 StringBuilder sql = new StringBuilder(); 461 462 sql.append("CREATE TABLE "); 463 sql.append(tableNameNormalized); 464 sql.append(" (key_enum "); 465 sql.append(metadataDef.getType().equals(MetadataType.LONG) ? "INT " : "VARCHAR(250) "); 466 sql.append(createPrimaryKeyQuery()); 467 sql.append(createCommentQuery(tableName, "key_enum_" + metadataDef.getName(), "Enumerator key")); 468 469 sql.append(", "); 470 addColumnForStringMetadata(sql, "value_enum_" + metadataDef.getName(), tableName); 471 472 sql.append(") "); 473 sql.append(createEngineQuery()); 474 sql.append(createCommentQuery(tableName, null, "Enumerator table " + metadataDef.getName() + " linked to the table " + tableParentName)); 475 476 tableInfo.addCreateQuery(sql.toString()); 477 478// String fkName = _normaliseNameComponent.normalizedColumnName(_mappingPolicy, columnName, tableParentName, _connection); 479// String fkTableName = _normaliseNameComponent.normalizedTableName(_sqlTablePrefix, _mappingPolicy, tableName, _connection); 480// String fkColumnName = "key_enum"; 481// currentCreateTableSQLQuery.append(createForeignKeyQuery(fkName, fkTableName, fkColumnName)); 482 //TODO foreign key ?? 483 484 fillTableForEnumerator(metadataDef, tableName); 485 } 486 487 /** 488 * Fill values for the enumerator table 489 * @param metadataDef the metadata definition model 490 * @param tableName the table name 491 */ 492 protected void fillTableForEnumerator(MetadataDefinition metadataDef, String tableName) 493 { 494 try 495 { 496 for (Entry<Object, I18nizableText> entry : metadataDef.getEnumerator().getEntries().entrySet()) 497 { 498 String enumValue = _i18nTranslator.translate(entry.getValue(), DEFAULT_LANGUAGE_CODE_FOR_COMMENTS); 499 String enumKey = (String) entry.getKey(); 500 501 StringBuilder sql = new StringBuilder(); 502 sql.append("INSERT INTO "); 503 sql.append(_normalizeNameComponent.normalizedTableName(_sqlTablePrefix, _mappingPolicy, tableName, _connection)); 504 sql.append(" VALUES ( '"); 505 sql.append(_normalizeNameComponent.escapeValue(enumKey, _connection)); 506 sql.append("', '"); 507 sql.append(_normalizeNameComponent.escapeValue(enumValue, _connection)); 508 sql.append("')"); 509 510 _tablesInfos.get(tableName).addInsertQuery(sql.toString()); 511 } 512 } 513 catch (IllegalStateException e) 514 { 515 getLogger().warn(e.getMessage(), e); 516 } 517 catch (Exception e) 518 { 519 getLogger().warn(e.getMessage(), e); 520 } 521 } 522 523 /** 524 * Create the two table mapping (for table name and column name) 525 * @throws ContextException if a context error occurred 526 */ 527 protected void createMappingNameTableSql() throws ContextException 528 { 529 PreparedStatement stmt = null; 530 String mappingTableName = _sqlTablePrefix + ExportManager.MAPPING_TABLE_NAME; 531 String mappingColumnName = _sqlTablePrefix + ExportManager.MAPPING_COLUMN_NAME; 532 533 ExportTableInfo mappingTableInfo = new ExportTableInfo(mappingTableName); 534 mappingTableInfo.incrementNbColumns(3); 535 536 ExportTableInfo mappingColumnInfo = new ExportTableInfo(mappingColumnName); 537 mappingColumnInfo.incrementNbColumns(3); 538 539 String mappingTableNameNormalized = _normalizeNameComponent.normalizedTableName(_sqlTablePrefix, "FULL", mappingTableName, _connection); 540 String mappingColumnNameNormalized = _normalizeNameComponent.normalizedTableName(_sqlTablePrefix, "FULL", mappingColumnName, _connection); 541 542 _tablesInfos.put(mappingTableName, mappingTableInfo); 543 _tablesInfos.put(mappingColumnName, mappingColumnInfo); 544 545 StringBuilder createMappingTableSQLQuery = new StringBuilder(); 546 547 createMappingTableSQLQuery.append("CREATE TABLE "); 548 createMappingTableSQLQuery.append(mappingTableNameNormalized); 549 createMappingTableSQLQuery.append(" (id_table INT"); 550 createMappingTableSQLQuery.append(createPrimaryKeyQuery()); 551 createMappingTableSQLQuery.append(createCommentQuery(mappingTableName, "id_table", "Table name ID")); 552 createMappingTableSQLQuery.append(", real_name VARCHAR(512)"); 553 createMappingTableSQLQuery.append(createCommentQuery(mappingTableName, "real_name", "Real name")); 554 createMappingTableSQLQuery.append(", modified_name VARCHAR(512)"); 555 createMappingTableSQLQuery.append(createCommentQuery(mappingTableName, "modified_name", "Normalized name")); 556 557 createMappingTableSQLQuery.append(") "); 558 createMappingTableSQLQuery.append(createEngineQuery()); 559 560 String comment = "Mapping table between real name and normalized name."; 561 createMappingTableSQLQuery.append(createCommentQuery(mappingTableName, null, comment)); 562 563 try 564 { 565 _mappingTablesQueries.add(createMappingTableSQLQuery.toString()); 566 stmt = _connection.prepareStatement(createMappingTableSQLQuery.toString()); 567 stmt.execute(); 568 } 569 catch (SQLException e) 570 { 571 getLogger().error(_i18nTranslator.translate(new I18nizableText("plugin.contentio", "PLUGINS_CONTENTIO_CONTENT_EXPORT_LOG_ANALYZE_TABLE_CREATE_MAPPING_TABLE_ERROR")), e); 572 } 573 finally 574 { 575 ConnectionHelper.cleanup(stmt); 576 } 577 578 StringBuilder createMappingColumnSQLQuery = new StringBuilder(); 579 580 createMappingColumnSQLQuery.append("CREATE TABLE "); 581 createMappingColumnSQLQuery.append(mappingColumnNameNormalized); 582 createMappingColumnSQLQuery.append(" (id_table INT"); 583 createMappingColumnSQLQuery.append(createCommentQuery(mappingColumnName, "id_table", "Table name id")); 584 createMappingColumnSQLQuery.append(createForeignKeyQuery("id_table", _normalizeNameComponent.normalizedTableName(_sqlTablePrefix, _mappingPolicy, mappingTableName, _connection), "id_table")); 585 createMappingColumnSQLQuery.append(", real_name VARCHAR(512)"); 586 createMappingColumnSQLQuery.append(createCommentQuery(mappingColumnName, "real_name", "Real column name")); 587 createMappingColumnSQLQuery.append(", modified_name VARCHAR(512)"); 588 createMappingColumnSQLQuery.append(createCommentQuery(mappingColumnName, "modified_name", "Normalized column name")); 589 590 createMappingColumnSQLQuery.append(") "); 591 createMappingColumnSQLQuery.append(createEngineQuery()); 592 593 String commentColum = "Mapping table between real column name and normalized column name."; 594 createMappingColumnSQLQuery.append(createCommentQuery(mappingColumnName, null, commentColum)); 595 596 try 597 { 598 _mappingTablesQueries.add(createMappingColumnSQLQuery.toString()); 599 stmt = _connection.prepareStatement(createMappingColumnSQLQuery.toString()); 600 stmt.execute(); 601 } 602 catch (SQLException e) 603 { 604 getLogger().error(_i18nTranslator.translate(new I18nizableText("plugin.contentio", "PLUGINS_CONTENTIO_CONTENT_EXPORT_LOG_ANALYZE_TABLE_CREATE_MAPPING_COLUMN_ERROR")), e); 605 } 606 finally 607 { 608 ConnectionHelper.cleanup(stmt); 609 } 610 611 fillMappingTableSql(mappingTableName, mappingColumnName); 612 } 613 614 /** 615 * Fill the two mapping table (for table name and column name) 616 * @param mappingTableName the table mapping table name 617 * @param mappingColumnName the column mapping table name 618 * @throws ContextException if a context error occurred 619 */ 620 protected void fillMappingTableSql(String mappingTableName, String mappingColumnName) throws ContextException 621 { 622 HashMap<String, String> mappingTable = (HashMap<String, String>) _normalizeNameComponent.getMappingTableNameFromCache(); 623 HashMap<String, HashMap<String, String>> mappingColumn = (HashMap<String, HashMap<String, String>>) _normalizeNameComponent.getMappingTableColumnNameFromCache(); 624 625 PreparedStatement stmtTableName = null; 626 PreparedStatement stmtColumnName = null; 627 try 628 { 629 stmtTableName = getInsertPreparedStatementFromTableName(mappingTableName); 630 stmtColumnName = getInsertPreparedStatementFromTableName(mappingColumnName); 631 int i = 0; 632 for (Entry<String, String> entry : mappingTable.entrySet()) 633 { 634 String realName = entry.getKey(); 635 String modifiedName = entry.getValue(); 636 637 if (getLogger().isDebugEnabled()) 638 { 639 String tableName = _normalizeNameComponent.normalizedTableName(_sqlTablePrefix, _mappingPolicy, mappingTableName, _connection); 640 getLogger().debug("INSERT INTO {} VALUES ('{}', '{}', '{}')", tableName, i, realName, modifiedName); 641 } 642 643 stmtTableName.setInt(1, i); 644 stmtTableName.setString(2, realName); 645 stmtTableName.setString(3, modifiedName); 646 647 stmtTableName.addBatch(); 648 649 if (mappingColumn.containsKey(realName)) 650 { 651 for (Entry<String, String> entryCol : mappingColumn.get(realName).entrySet()) 652 { 653 String realNameCol = entryCol.getKey(); 654 String modifiedNameCol = entryCol.getValue(); 655 656 if (getLogger().isDebugEnabled()) 657 { 658 String tableName = _normalizeNameComponent.normalizedTableName(_sqlTablePrefix, _mappingPolicy, mappingTableName, _connection); 659 getLogger().debug("INSERT INTO {} VALUES ('{}', '{}', '{}')", tableName, i, realNameCol, modifiedNameCol); 660 } 661 662 stmtColumnName.setInt(1, i); 663 stmtColumnName.setString(2, realNameCol); 664 stmtColumnName.setString(3, modifiedNameCol); 665 666 stmtColumnName.addBatch(); 667 668 } 669 } 670 i++; 671 } 672 673 stmtTableName.executeBatch(); 674 stmtColumnName.executeBatch(); 675 } 676 catch (SQLException e) 677 { 678 getLogger().error(_i18nTranslator.translate(new I18nizableText("plugin.contentio", "PLUGINS_CONTENTIO_CONTENT_EXPORT_LOG_ANALYZE_TABLE_FILL_MAPPING_ERROR")), e); 679 } 680 finally 681 { 682 ConnectionHelper.cleanup(stmtTableName); 683 ConnectionHelper.cleanup(stmtColumnName); 684 } 685 } 686 687 /** 688 * Add all the column for each metadata in the composite 689 * @param metadataDef the metadata definition model 690 * @param currentCreateTableSQLQuery the current SQL create table query 691 * @param tableName the table name 692 * @param columnNamePrefix the column namePrefix 693 * @throws ContextException if a context error occurred 694 */ 695 protected void addColumnForCompositeMetadata(MetadataDefinitionHolder metadataDef, StringBuilder currentCreateTableSQLQuery, String tableName, String columnNamePrefix) throws ContextException 696 { 697 for (String metadataName : metadataDef.getMetadataNames()) 698 { 699 MetadataDefinition subMetadataDef = metadataDef.getMetadataDefinition(metadataName); 700 addColumnForMetadata(subMetadataDef, currentCreateTableSQLQuery, tableName, columnNamePrefix); 701 } 702 } 703 704 /** 705 * Add column for the metadata (multiple or single) 706 * @param metadataDef the metadata definition model 707 * @param currentCreateTableSQLQuery the current SQL create table query 708 * @param tableName the table name 709 * @param columnNamePrefix the column namePrefix 710 * @throws ContextException if a context error occurred 711 */ 712 protected void addColumnForMetadata(MetadataDefinition metadataDef, StringBuilder currentCreateTableSQLQuery, String tableName, String columnNamePrefix) throws ContextException 713 { 714 String columnName = columnNamePrefix + metadataDef.getName(); 715 716 if (metadataDef.isMultiple()) 717 { 718 if (_exportNoMultiValuedTable) 719 { 720 String comment = _i18nTranslator.translate(metadataDef.getLabel(), DEFAULT_LANGUAGE_CODE_FOR_COMMENTS) + ": " + _i18nTranslator.translate(metadataDef.getDescription(), DEFAULT_LANGUAGE_CODE_FOR_COMMENTS); 721 722 currentCreateTableSQLQuery.append(", "); 723 addColumnForStringMetadata(currentCreateTableSQLQuery, columnName, tableName); 724 currentCreateTableSQLQuery.append(createCommentQuery(tableName, columnName, comment)); 725 } 726 else 727 { 728 createSqlQueryForMultipleMetadata(metadataDef, tableName, tableName + "_" + columnName); 729 } 730 } 731 else 732 { 733 addColumnForSingleMetadata(metadataDef, currentCreateTableSQLQuery, tableName, columnName); 734 } 735 } 736 737 /** 738 * Add column for single metadata 739 * @param metadataDef the metadata definition model 740 * @param currentCreateTableSQLQuery the current SQL create table query 741 * @param tableName the table name 742 * @param columnName the column name 743 * @throws ContextException if a context error occurred 744 */ 745 protected void addColumnForSingleMetadata(MetadataDefinition metadataDef, StringBuilder currentCreateTableSQLQuery, String tableName, String columnName) throws ContextException 746 { 747 String comment = _i18nTranslator.translate(metadataDef.getLabel(), DEFAULT_LANGUAGE_CODE_FOR_COMMENTS) + ": " + _i18nTranslator.translate(metadataDef.getDescription(), DEFAULT_LANGUAGE_CODE_FOR_COMMENTS); 748 749 MetadataType metadataType = metadataDef.getType(); 750 switch (metadataType) 751 { 752 case USER: 753 currentCreateTableSQLQuery.append(", "); 754 addColumnForUserMetadata(currentCreateTableSQLQuery, columnName, tableName); 755 break; 756 case STRING: 757 currentCreateTableSQLQuery.append(", "); 758 if (metadataDef.getEnumerator() != null) 759 { 760 addColumnForEnumStringMetadata(currentCreateTableSQLQuery, columnName, tableName); 761 } 762 else 763 { 764 addColumnForStringMetadata(currentCreateTableSQLQuery, columnName, tableName); 765 } 766 currentCreateTableSQLQuery.append(createCommentQuery(tableName, columnName, comment)); 767 break; 768 case MULTILINGUAL_STRING: 769 currentCreateTableSQLQuery.append(", "); 770 addColumnsForMultilingualStringMetadata(currentCreateTableSQLQuery, columnName, tableName, comment); 771 break; 772 case LONG: 773 currentCreateTableSQLQuery.append(", "); 774 addColumnForLongMetadata(currentCreateTableSQLQuery, columnName, tableName); 775 currentCreateTableSQLQuery.append(createCommentQuery(tableName, columnName, comment)); 776 break; 777 case BOOLEAN: 778 currentCreateTableSQLQuery.append(", "); 779 addColumnForBooleanMetadata(currentCreateTableSQLQuery, columnName, tableName); 780 currentCreateTableSQLQuery.append(createCommentQuery(tableName, columnName, comment)); 781 break; 782 case DATE: 783 currentCreateTableSQLQuery.append(", "); 784 addColumnForDateMetadata(currentCreateTableSQLQuery, columnName, tableName); 785 currentCreateTableSQLQuery.append(createCommentQuery(tableName, columnName, comment)); 786 break; 787 case DATETIME: 788 currentCreateTableSQLQuery.append(", "); 789 addColumnForDateTimeMetadata(currentCreateTableSQLQuery, columnName, tableName); 790 currentCreateTableSQLQuery.append(createCommentQuery(tableName, columnName, comment)); 791 break; 792 case DOUBLE: 793 currentCreateTableSQLQuery.append(", "); 794 addColumnForDoubleMetadata(currentCreateTableSQLQuery, columnName, tableName); 795 currentCreateTableSQLQuery.append(createCommentQuery(tableName, columnName, comment)); 796 break; 797 case RICH_TEXT: 798 currentCreateTableSQLQuery.append(", "); 799 addColumnForRichTextMetadata(currentCreateTableSQLQuery, columnName, tableName); 800 currentCreateTableSQLQuery.append(createCommentQuery(tableName, columnName, comment)); 801 break; 802 case CONTENT: 803 currentCreateTableSQLQuery.append(", "); 804 addColumnForContentMetadata(currentCreateTableSQLQuery, columnName, tableName); 805 currentCreateTableSQLQuery.append(createCommentQuery(tableName, columnName, comment)); 806 break; 807 case FILE: 808 currentCreateTableSQLQuery.append(", "); 809 addColumnsForFileMetadata(currentCreateTableSQLQuery, columnName, tableName, comment); 810 break; 811 case BINARY: 812 currentCreateTableSQLQuery.append(", "); 813 addColumnsForBinaryMetadata(currentCreateTableSQLQuery, columnName, tableName, comment); 814 break; 815 case GEOCODE: 816 currentCreateTableSQLQuery.append(", "); 817 addColumnsForGeocodeMetadata(currentCreateTableSQLQuery, columnName, tableName, comment); 818 break; 819 case REFERENCE: 820 case COMPOSITE: 821 if (metadataDef instanceof RepeaterDefinition) 822 { 823 String commentTable = "Repeater " + _normalizeNameComponent.normalizedColumnName(_mappingPolicy, columnName, tableName, _reservedWords, _connection) + " linked to the table " + _normalizeNameComponent.normalizedTableName(_sqlTablePrefix, _mappingPolicy, tableName, _connection); 824 createSqlQueriesForTableCreation(metadataDef, tableName + "_" + columnName, tableName, commentTable, true); 825 } 826 else 827 { 828 addColumnForCompositeMetadata(metadataDef, currentCreateTableSQLQuery, tableName, columnName + "_"); 829 } 830 break; 831 default: 832 break; 833 } 834 835 if (metadataDef.getEnumerator() != null) 836 { 837 createTableForEnumerator(metadataDef, tableName, tableName + "_" + metadataDef.getName(), columnName, currentCreateTableSQLQuery); 838 } 839 } 840 841 /** 842 * Add a column to sort 843 * @param currentCreateTableSQLQuery the current SQL create table query 844 * @param tableName the table name 845 * @throws ContextException if a context error occurred 846 */ 847 protected void addSortColumn(StringBuilder currentCreateTableSQLQuery, String tableName) throws ContextException 848 { 849 currentCreateTableSQLQuery.append("position INT"); 850 currentCreateTableSQLQuery.append(createCommentQuery(tableName, "position", "Order of the row")); 851 852 ExportTableInfo tableInfo = _tablesInfos.get(tableName); 853 tableInfo.incrementNbColumns(); 854 } 855 856 /** 857 * Add an id column which refer to another table 858 * @param currentCreateTableSQLQuery the current SQL create table query 859 * @param tableParentName the table parent name 860 * @param tableName the table name 861 * @throws ContextException if a context error occurred 862 */ 863 protected void addColumnParentId(StringBuilder currentCreateTableSQLQuery, String tableParentName, String tableName) throws ContextException 864 { 865 currentCreateTableSQLQuery.append(_normalizeNameComponent.normalizedColumnName(_mappingPolicy, COLUMN_PARENT_TABLE_PREFIX + tableParentName, tableName, _reservedWords, _connection)); 866 currentCreateTableSQLQuery.append(" VARCHAR(250)"); //TODO NOT NULL 867 currentCreateTableSQLQuery.append(createCommentQuery(tableName, COLUMN_PARENT_TABLE_PREFIX + tableParentName, "Parent table ID " + tableParentName)); 868 869 String fkName = _normalizeNameComponent.normalizedColumnName(_mappingPolicy, COLUMN_PARENT_TABLE_PREFIX + tableParentName, tableName, _reservedWords, _connection); 870 String fkTableName = _normalizeNameComponent.normalizedTableName(_sqlTablePrefix, _mappingPolicy, tableParentName, _connection); 871 String fkColumnName = _normalizeNameComponent.normalizedColumnName(_mappingPolicy, "id_" + tableParentName, tableParentName, _reservedWords, _connection); 872 currentCreateTableSQLQuery.append(createForeignKeyQuery(fkName, fkTableName, fkColumnName)); 873 874 ExportTableInfo tableInfo = _tablesInfos.get(tableName); 875 tableInfo.incrementNbColumns(); 876 } 877 878 /** 879 * Add columns for geocode metadata 880 * @param currentCreateTableSQLQuery the current SQL create table query 881 * @param initialColumnName the initial column name 882 * @param tableName the table name 883 * @param comment the comment 884 * @throws ContextException if a context error occurred 885 */ 886 protected void addColumnsForGeocodeMetadata(StringBuilder currentCreateTableSQLQuery, String initialColumnName, String tableName, String comment) throws ContextException 887 { 888 String columnName = _normalizeNameComponent.normalizedColumnName(_mappingPolicy, initialColumnName, tableName, _reservedWords, _connection); 889 890 currentCreateTableSQLQuery.append(_normalizeNameComponent.normalizedColumnName(_mappingPolicy, columnName + "_longitude", tableName, _reservedWords, _connection)); 891 currentCreateTableSQLQuery.append(" "); 892 currentCreateTableSQLQuery.append(convertMetadataTypeToSql("double")); 893 currentCreateTableSQLQuery.append(createCommentQuery(tableName, initialColumnName, "Longitude of " + columnName)); 894 currentCreateTableSQLQuery.append(", "); 895 896 currentCreateTableSQLQuery.append(_normalizeNameComponent.normalizedColumnName(_mappingPolicy, columnName + "_latitude", tableName, _reservedWords, _connection)); 897 currentCreateTableSQLQuery.append(" "); 898 currentCreateTableSQLQuery.append(convertMetadataTypeToSql("double")); 899 currentCreateTableSQLQuery.append(createCommentQuery(tableName, initialColumnName, "Latitude type of " + columnName)); 900 901 ExportTableInfo tableInfo = _tablesInfos.get(tableName); 902 tableInfo.incrementNbColumns(2); 903 } 904 905 /** 906 * Add columns for binary metadata 907 * @param currentCreateTableSQLQuery the current SQL create table query 908 * @param initialColumnName the initial column name 909 * @param tableName the table name 910 * @param comment the comment 911 * @throws ContextException if a context error occurred 912 */ 913 protected void addColumnsForBinaryMetadata(StringBuilder currentCreateTableSQLQuery, String initialColumnName, String tableName, String comment) throws ContextException 914 { 915 String columnName = _normalizeNameComponent.normalizedColumnName(_mappingPolicy, initialColumnName, tableName, _reservedWords, _connection); 916 917 currentCreateTableSQLQuery.append(columnName); 918 currentCreateTableSQLQuery.append(" "); 919 currentCreateTableSQLQuery.append(convertMetadataTypeToSql("string")); 920 currentCreateTableSQLQuery.append(createCommentQuery(tableName, initialColumnName, comment)); 921 currentCreateTableSQLQuery.append(", "); 922 923 currentCreateTableSQLQuery.append(_normalizeNameComponent.normalizedColumnName(_mappingPolicy, columnName + "_data", tableName, _reservedWords, _connection)); 924 currentCreateTableSQLQuery.append(" "); 925 currentCreateTableSQLQuery.append(convertMetadataTypeToSql("binary")); 926 currentCreateTableSQLQuery.append(createCommentQuery(tableName, initialColumnName, "Data of " + columnName)); 927 currentCreateTableSQLQuery.append(", "); 928 929 currentCreateTableSQLQuery.append(_normalizeNameComponent.normalizedColumnName(_mappingPolicy, columnName + "_mimetype", tableName, _reservedWords, _connection)); 930 currentCreateTableSQLQuery.append(" VARCHAR(255)"); 931 currentCreateTableSQLQuery.append(createCommentQuery(tableName, initialColumnName, "Mime type of " + columnName)); 932 currentCreateTableSQLQuery.append(", "); 933 934 currentCreateTableSQLQuery.append(_normalizeNameComponent.normalizedColumnName(_mappingPolicy, columnName + "_size", tableName, _reservedWords, _connection)); 935 currentCreateTableSQLQuery.append(" INT"); 936 currentCreateTableSQLQuery.append(createCommentQuery(tableName, initialColumnName, "Size of " + columnName)); 937 currentCreateTableSQLQuery.append(", "); 938 939 currentCreateTableSQLQuery.append(_normalizeNameComponent.normalizedColumnName(_mappingPolicy, columnName + "_lastmodified", tableName, _reservedWords, _connection)); 940 currentCreateTableSQLQuery.append(" "); 941 currentCreateTableSQLQuery.append(convertMetadataTypeToSql("datetime")); 942 currentCreateTableSQLQuery.append(createCommentQuery(tableName, initialColumnName, "Last modification date of " + columnName)); 943 944 ExportTableInfo tableInfo = _tablesInfos.get(tableName); 945 tableInfo.incrementNbColumns(5); 946 } 947 948 /** 949 * Add columns for file metadata 950 * @param currentCreateTableSQLQuery the current SQL create table query 951 * @param initialColumnName the initial column name 952 * @param tableName the table name 953 * @param comment the comment 954 * @throws ContextException if a context error occurred 955 */ 956 protected void addColumnsForFileMetadata(StringBuilder currentCreateTableSQLQuery, String initialColumnName, String tableName, String comment) throws ContextException 957 { 958 String columnName = _normalizeNameComponent.normalizedColumnName(_mappingPolicy, initialColumnName, tableName, _reservedWords, _connection); 959 960 currentCreateTableSQLQuery.append(columnName); 961 currentCreateTableSQLQuery.append(" "); 962 currentCreateTableSQLQuery.append(convertMetadataTypeToSql("string")); 963 currentCreateTableSQLQuery.append(createCommentQuery(tableName, initialColumnName, comment)); 964 currentCreateTableSQLQuery.append(", "); 965 966 currentCreateTableSQLQuery.append(_normalizeNameComponent.normalizedColumnName(_mappingPolicy, columnName + "_data", tableName, _reservedWords, _connection)); 967 currentCreateTableSQLQuery.append(" "); 968 currentCreateTableSQLQuery.append(convertMetadataTypeToSql("file")); 969 currentCreateTableSQLQuery.append(createCommentQuery(tableName, initialColumnName, "Data of " + columnName)); 970 currentCreateTableSQLQuery.append(", "); 971 972 currentCreateTableSQLQuery.append(_normalizeNameComponent.normalizedColumnName(_mappingPolicy, columnName + "_mimetype", tableName, _reservedWords, _connection)); 973 currentCreateTableSQLQuery.append(" VARCHAR(255)"); 974 currentCreateTableSQLQuery.append(createCommentQuery(tableName, initialColumnName, "Mime type of " + columnName)); 975 currentCreateTableSQLQuery.append(", "); 976 977 currentCreateTableSQLQuery.append(_normalizeNameComponent.normalizedColumnName(_mappingPolicy, columnName + "_size", tableName, _reservedWords, _connection)); 978 currentCreateTableSQLQuery.append(" INT"); 979 currentCreateTableSQLQuery.append(createCommentQuery(tableName, initialColumnName, "Size of " + columnName)); 980 currentCreateTableSQLQuery.append(", "); 981 982 currentCreateTableSQLQuery.append(_normalizeNameComponent.normalizedColumnName(_mappingPolicy, columnName + "_lastmodified", tableName, _reservedWords, _connection)); 983 currentCreateTableSQLQuery.append(" "); 984 currentCreateTableSQLQuery.append(convertMetadataTypeToSql("datetime")); 985 currentCreateTableSQLQuery.append(createCommentQuery(tableName, initialColumnName, "Last modification date of " + columnName)); 986 987 ExportTableInfo tableInfo = _tablesInfos.get(tableName); 988 tableInfo.incrementNbColumns(5); 989 } 990 991 /** 992 * Add columns for multilangual string metadata (one for each language) 993 * @param currentCreateTableSQLQuery the current SQL create table query 994 * @param initialColumnName the initial column name 995 * @param tableName the table name 996 * @param comment the comment 997 * @throws ContextException if a context error occurred 998 */ 999 protected void addColumnsForMultilingualStringMetadata(StringBuilder currentCreateTableSQLQuery, String initialColumnName, String tableName, String comment) throws ContextException 1000 { 1001 String columnName = _normalizeNameComponent.normalizedColumnName(_mappingPolicy, initialColumnName, tableName, _reservedWords, _connection); 1002 1003 ExportTableInfo tableInfo = _tablesInfos.get(tableName); 1004 int position = 0; 1005 for (String lang : _languageManager.getAvailableLanguages().keySet()) 1006 { 1007 if (position != 0) 1008 { 1009 currentCreateTableSQLQuery.append(", "); 1010 } 1011 1012 currentCreateTableSQLQuery.append(_normalizeNameComponent.normalizedColumnName(_mappingPolicy, columnName + "_" + lang, tableName, _reservedWords, _connection)); 1013 currentCreateTableSQLQuery.append(" "); 1014 currentCreateTableSQLQuery.append(convertMetadataTypeToSql("string")); 1015 currentCreateTableSQLQuery.append(createCommentQuery(tableName, initialColumnName, "Value of " + columnName + " for lang " + lang)); 1016 1017 position++; 1018 tableInfo.incrementNbColumns(); 1019 } 1020 } 1021 1022 /** 1023 * Add column for rich Text 1024 * @param currentCreateTableSQLQuery the current SQL create table query 1025 * @param columnName the column name 1026 * @param tableName the table name 1027 * @throws ContextException if a context error occurred 1028 */ 1029 protected void addColumnForRichTextMetadata(StringBuilder currentCreateTableSQLQuery, String columnName, String tableName) throws ContextException 1030 { 1031 currentCreateTableSQLQuery.append(_normalizeNameComponent.normalizedColumnName(_mappingPolicy, columnName, tableName, _reservedWords, _connection)); 1032 currentCreateTableSQLQuery.append(" "); 1033 currentCreateTableSQLQuery.append(convertMetadataTypeToSql("richtext")); 1034 1035 ExportTableInfo tableInfo = _tablesInfos.get(tableName); 1036 tableInfo.incrementNbColumns(); 1037 } 1038 1039 /** 1040 * Add column for content metadata 1041 * @param currentCreateTableSQLQuery the current SQL create table query 1042 * @param columnName the column name 1043 * @param tableName the table name 1044 * @throws ContextException if a context error occurred 1045 */ 1046 private void addColumnForContentMetadata(StringBuilder currentCreateTableSQLQuery, String columnName, String tableName) throws ContextException 1047 { 1048 currentCreateTableSQLQuery.append(_normalizeNameComponent.normalizedColumnName(_mappingPolicy, columnName, tableName, _reservedWords, _connection)); 1049 currentCreateTableSQLQuery.append(" "); 1050 currentCreateTableSQLQuery.append(convertMetadataTypeToSql("content")); 1051 1052 ExportTableInfo tableInfo = _tablesInfos.get(tableName); 1053 tableInfo.incrementNbColumns(); 1054 } 1055 1056 /** 1057 * Add column for Double metadata 1058 * @param currentCreateTableSQLQuery the current SQL create table query 1059 * @param columnName the column name 1060 * @param tableName the table name 1061 * @throws ContextException if a context error occurred 1062 */ 1063 protected void addColumnForDoubleMetadata(StringBuilder currentCreateTableSQLQuery, String columnName, String tableName) throws ContextException 1064 { 1065 currentCreateTableSQLQuery.append(_normalizeNameComponent.normalizedColumnName(_mappingPolicy, columnName, tableName, _reservedWords, _connection)); 1066 currentCreateTableSQLQuery.append(" "); 1067 currentCreateTableSQLQuery.append(convertMetadataTypeToSql("double")); 1068 1069 ExportTableInfo tableInfo = _tablesInfos.get(tableName); 1070 tableInfo.incrementNbColumns(); 1071 } 1072 1073 /** 1074 * Add column for DateTime metadata 1075 * @param currentCreateTableSQLQuery the current SQL create table query 1076 * @param columnName the column name 1077 * @param tableName the table name 1078 * @throws ContextException if a context error occurred 1079 */ 1080 protected void addColumnForDateTimeMetadata(StringBuilder currentCreateTableSQLQuery, String columnName, String tableName) throws ContextException 1081 { 1082 currentCreateTableSQLQuery.append(_normalizeNameComponent.normalizedColumnName(_mappingPolicy, columnName, tableName, _reservedWords, _connection)); 1083 currentCreateTableSQLQuery.append(" "); 1084 currentCreateTableSQLQuery.append(convertMetadataTypeToSql("datetime")); 1085 1086 ExportTableInfo tableInfo = _tablesInfos.get(tableName); 1087 tableInfo.incrementNbColumns(); 1088 } 1089 1090 /** 1091 * Add column for Date metadata 1092 * @param currentCreateTableSQLQuery the current SQL create table query 1093 * @param columnName the column name 1094 * @param tableName the table name 1095 * @throws ContextException if a context error occurred 1096 */ 1097 protected void addColumnForDateMetadata(StringBuilder currentCreateTableSQLQuery, String columnName, String tableName) throws ContextException 1098 { 1099 currentCreateTableSQLQuery.append(_normalizeNameComponent.normalizedColumnName(_mappingPolicy, columnName, tableName, _reservedWords, _connection)); 1100 currentCreateTableSQLQuery.append(" "); 1101 currentCreateTableSQLQuery.append(convertMetadataTypeToSql("date")); 1102 1103 ExportTableInfo tableInfo = _tablesInfos.get(tableName); 1104 tableInfo.incrementNbColumns(); 1105 } 1106 1107 /** 1108 * Add column for String metadata 1109 * @param currentCreateTableSQLQuery the current SQL create table query 1110 * @param columnName the column name 1111 * @param tableName the table name 1112 * @throws ContextException if a context error occurred 1113 */ 1114 protected void addColumnForStringMetadata(StringBuilder currentCreateTableSQLQuery, String columnName, String tableName) throws ContextException 1115 { 1116 currentCreateTableSQLQuery.append(_normalizeNameComponent.normalizedColumnName(_mappingPolicy, columnName, tableName, _reservedWords, _connection)); 1117 currentCreateTableSQLQuery.append(" "); 1118 currentCreateTableSQLQuery.append(convertMetadataTypeToSql("string")); 1119 1120 ExportTableInfo tableInfo = _tablesInfos.get(tableName); 1121 tableInfo.incrementNbColumns(); 1122 } 1123 1124 /** 1125 * Add column for User metadata 1126 * @param currentCreateTableSQLQuery the current SQL create table query 1127 * @param columnName the column name 1128 * @param tableName the table name 1129 * @throws ContextException if a context error occurred 1130 */ 1131 protected void addColumnForUserMetadata(StringBuilder currentCreateTableSQLQuery, String columnName, String tableName) throws ContextException 1132 { 1133 addColumnForStringMetadata(currentCreateTableSQLQuery, columnName + "_login", tableName); 1134 currentCreateTableSQLQuery.append(createCommentQuery(tableName, columnName + "_login", "User login")); 1135 currentCreateTableSQLQuery.append(", "); 1136 addColumnForStringMetadata(currentCreateTableSQLQuery, columnName + "_population", tableName); 1137 currentCreateTableSQLQuery.append(createCommentQuery(tableName, columnName + "_population", "User population")); 1138 } 1139 1140 /** 1141 * Add column for enumerator metadata 1142 * @param currentCreateTableSQLQuery the current SQL create table query 1143 * @param columnName the column name 1144 * @param tableName the table name 1145 * @throws ContextException if a context error occurred 1146 */ 1147 protected void addColumnForEnumStringMetadata(StringBuilder currentCreateTableSQLQuery, String columnName, String tableName) throws ContextException 1148 { 1149 currentCreateTableSQLQuery.append(_normalizeNameComponent.normalizedColumnName(_mappingPolicy, columnName, tableName, _reservedWords, _connection)); 1150 currentCreateTableSQLQuery.append(" "); 1151 currentCreateTableSQLQuery.append(convertMetadataTypeToSql("string")); 1152 1153 ExportTableInfo tableInfo = _tablesInfos.get(tableName); 1154 tableInfo.incrementNbColumns(); 1155 } 1156 1157 /** 1158 * Add column for Boolean metadata 1159 * @param currentCreateTableSQLQuery the current SQL create table query 1160 * @param columnName the column name 1161 * @param tableName the table name 1162 * @throws ContextException if a context error occurred 1163 */ 1164 protected void addColumnForBooleanMetadata(StringBuilder currentCreateTableSQLQuery, String columnName, String tableName) throws ContextException 1165 { 1166 currentCreateTableSQLQuery.append(_normalizeNameComponent.normalizedColumnName(_mappingPolicy, columnName, tableName, _reservedWords, _connection)); 1167 currentCreateTableSQLQuery.append(" "); 1168 currentCreateTableSQLQuery.append(convertMetadataTypeToSql("boolean")); 1169 1170 ExportTableInfo tableInfo = _tablesInfos.get(tableName); 1171 tableInfo.incrementNbColumns(); 1172 } 1173 1174 /** 1175 * Add column for Long metadata 1176 * @param currentCreateTableSQLQuery the current SQL create table query 1177 * @param columnName the column name 1178 * @param tableName the table name 1179 * @throws ContextException if a context error occurred 1180 */ 1181 protected void addColumnForLongMetadata(StringBuilder currentCreateTableSQLQuery, String columnName, String tableName) throws ContextException 1182 { 1183 currentCreateTableSQLQuery.append(_normalizeNameComponent.normalizedColumnName(_mappingPolicy, columnName, tableName, _reservedWords, _connection)); 1184 currentCreateTableSQLQuery.append(" "); 1185 currentCreateTableSQLQuery.append(convertMetadataTypeToSql("long")); 1186 1187 ExportTableInfo tableInfo = _tablesInfos.get(tableName); 1188 tableInfo.incrementNbColumns(); 1189 } 1190 1191 /** 1192 * Add additionnal metadata for content (title, type, language, creator, creationDate, ....) 1193 * @param metadataDef the metadata definition model 1194 * @param currentCreateTableSQLQuery the current SQL create table query 1195 * @param tableName the table name 1196 * @throws ContextException if a context error occurred 1197 */ 1198 protected void addAdditionnalContentMetadata(MetadataDefinitionHolder metadataDef, StringBuilder currentCreateTableSQLQuery, String tableName) throws ContextException 1199 { 1200 if (metadataDef instanceof ContentType) 1201 { 1202 currentCreateTableSQLQuery.append(", "); 1203 addColumnForStringMetadata(currentCreateTableSQLQuery, "content_title", tableName); 1204 currentCreateTableSQLQuery.append(createCommentQuery(tableName, "content_title", "Content title")); 1205 currentCreateTableSQLQuery.append(", "); 1206 1207 addColumnForStringMetadata(currentCreateTableSQLQuery, "content_type", tableName); 1208 currentCreateTableSQLQuery.append(createCommentQuery(tableName, "content_type", "Content type")); 1209 currentCreateTableSQLQuery.append(", "); 1210 //TODO site for webContent 1211 addColumnForStringMetadata(currentCreateTableSQLQuery, "content_language", tableName); 1212 currentCreateTableSQLQuery.append(createCommentQuery(tableName, "content_language", "Content lang")); 1213 currentCreateTableSQLQuery.append(", "); 1214 1215 addColumnForStringMetadata(currentCreateTableSQLQuery, "content_creator", tableName); 1216 currentCreateTableSQLQuery.append(createCommentQuery(tableName, "content_creator", "Content author")); 1217 currentCreateTableSQLQuery.append(", "); 1218 1219 addColumnForDateTimeMetadata(currentCreateTableSQLQuery, "content_creationDate", tableName); 1220 currentCreateTableSQLQuery.append(createCommentQuery(tableName, "content_creationDate", "Content creation date")); 1221 currentCreateTableSQLQuery.append(", "); 1222 1223 addColumnForStringMetadata(currentCreateTableSQLQuery, "content_lastContributor", tableName); 1224 currentCreateTableSQLQuery.append(createCommentQuery(tableName, "content_lastContributor", "Content last contributor")); 1225 currentCreateTableSQLQuery.append(", "); 1226 1227 addColumnForDateTimeMetadata(currentCreateTableSQLQuery, "content_lastModificationDate", tableName); 1228 currentCreateTableSQLQuery.append(createCommentQuery(tableName, "content_lastModificationDate", "Content last modification date")); 1229 currentCreateTableSQLQuery.append(", "); 1230 1231 addColumnForDateTimeMetadata(currentCreateTableSQLQuery, "content_lastValidationDate", tableName); 1232 currentCreateTableSQLQuery.append(createCommentQuery(tableName, "content_lastValidationDate", "Content last validation date")); 1233 currentCreateTableSQLQuery.append(", "); 1234 1235 addColumnForDateTimeMetadata(currentCreateTableSQLQuery, "content_lastMajorValidationDate", tableName); 1236 currentCreateTableSQLQuery.append(createCommentQuery(tableName, "content_lastMajorValidationDate", "Content last major validation date")); 1237 } 1238 } 1239 1240 /** 1241 * Create the query to add comment to a table or a column 1242 * @param table the table name 1243 * @param column the column name 1244 * @param comments the comments 1245 * @return the query to add comment to a table or a column 1246 * @throws ContextException if a context error occurred 1247 */ 1248 protected String createCommentQuery(String table, String column, String comments) throws ContextException 1249 { 1250 String normalizedComment = _normalizeNameComponent.normalizedComment(comments, StringUtils.isEmpty(column) ? _commentTableMaxLength : _commentColumnMaxLength, _connection); 1251 1252 String commentSql = ""; 1253 if (_databaseType.equals(ConnectionHelper.DATABASE_MYSQL)) 1254 { 1255 commentSql = " COMMENT '" + normalizedComment + "'"; 1256 } 1257 else if (_databaseType.equals(ConnectionHelper.DATABASE_ORACLE)) //TODO 1258 { 1259 /*if (StringUtils.isNotEmpty(table)) 1260 { 1261 if (StringUtils.isEmpty(column)) 1262 { 1263// _tablesInfos.get(table).addCommentQuery("COMMENT ON TABLE " + _normaliseNameComponent.normalizedTableName(_sqlTablePrefix, _mappingPolicy, table, _connection) + " IS '" + normalizedComment + "'"); 1264 } 1265 else 1266 { 1267// _tablesInfos.get(table).addCommentQuery("COMMENT ON COLUMN " + _normaliseNameComponent.normalizedTableName(_sqlTablePrefix, _mappingPolicy, table, _connection) + "." + _normaliseNameComponent.normalizedColumnName(_mappingPolicy, column, table, _connection) + " IS '" + normalizedComment + "'"); 1268 } 1269 }*/ 1270 } 1271 1272 return commentSql; 1273 } 1274 1275 /** 1276 * Create the query to add foreign key 1277 * @param fkName the foreign key name 1278 * @param tableName the table name 1279 * @param columnName the column name 1280 * @return the query to add comment to a table or a column 1281 * @throws ContextException if a context error occurred 1282 */ 1283 protected String createForeignKeyQuery(String fkName, String tableName, String columnName) throws ContextException 1284 { 1285 StringBuilder foreignKeySQLQuery = new StringBuilder(); 1286 foreignKeySQLQuery.append(", CONSTRAINT fk_"); 1287 foreignKeySQLQuery.append(_fkIndice); 1288 _fkIndice++; 1289 1290 foreignKeySQLQuery.append(" FOREIGN KEY ("); 1291 foreignKeySQLQuery.append(fkName); 1292 foreignKeySQLQuery.append(")"); 1293 foreignKeySQLQuery.append(" REFERENCES "); 1294 foreignKeySQLQuery.append(tableName); 1295 foreignKeySQLQuery.append(" ("); 1296 foreignKeySQLQuery.append(columnName); 1297 foreignKeySQLQuery.append(")"); 1298 1299 return foreignKeySQLQuery.toString(); 1300 } 1301 1302 /** 1303 * Create the query to add engine 1304 * @return the query to add engine 1305 * @throws ContextException if a context error occurred 1306 */ 1307 protected String createEngineQuery() throws ContextException 1308 { 1309 if (_databaseType.equals(ConnectionHelper.DATABASE_MYSQL)) 1310 { 1311 return "ENGINE=" + MYSQL_CONTENT_EXPORT_ENGINE + " ROW_FORMAT=COMPRESSED DEFAULT CHARACTER SET " + MYSQL_CONTENT_EXPORT_CHARSET + " "; 1312 } 1313 else if (_databaseType.equals(ConnectionHelper.DATABASE_ORACLE)) 1314 { 1315 return "STORAGE (INITIAL 8K NEXT 8K)"; 1316 } 1317 1318 return ""; 1319 } 1320 1321 /** 1322 * Create the query to add primary key 1323 * @return the query to add primary key 1324 * @throws ContextException if a context error occurred 1325 */ 1326 protected String createPrimaryKeyQuery() throws ContextException 1327 { 1328 return " PRIMARY KEY NOT NULL"; 1329 } 1330 1331 /** 1332 * Return the sql type depends on the metadata and the database type 1333 * @param metadataType the metadata type 1334 * @return the sql type depends on the metadata and the database type 1335 */ 1336 protected String convertMetadataTypeToSql(String metadataType) 1337 { 1338 String sqlType = ""; 1339 1340 if (_databaseType.equals(ConnectionHelper.DATABASE_MYSQL)) 1341 { 1342 sqlType = _mappingSql.get("mysql").get(metadataType); 1343 } 1344 else if (_databaseType.equals(ConnectionHelper.DATABASE_ORACLE)) 1345 { 1346 sqlType = _mappingSql.get("oracle").get(metadataType); 1347 } 1348 1349 return sqlType; 1350 } 1351 1352 1353 /** 1354 * Execute SQL queries 1355 * @throws SQLException if a sql error occurred 1356 * @throws IOException if an IO error occurred 1357 */ 1358 protected void executeSqlQueries() throws SQLException, IOException 1359 { 1360 int nbTotalTable = _getNbTable(); 1361 1362 boolean isInfoEnabled = getLogger().isInfoEnabled(); 1363 if (isInfoEnabled) 1364 { 1365 List<String> i18nParams = new ArrayList<>(); 1366 i18nParams.add(String.valueOf(nbTotalTable)); 1367 getLogger().info(_i18nTranslator.translate(new I18nizableText("plugin.contentio", "PLUGINS_CONTENTIO_CONTENT_EXPORT_LOG_ANALYZE_TABLE_CREATE_BEGINNING", i18nParams))); 1368 } 1369 1370 int nbTableCreated = 0; 1371 int limitPourcentReport = 10; 1372 try 1373 { 1374 for (Entry<String, ExportTableInfo> entry : _tablesInfos.entrySet()) 1375 { 1376 ExportTableInfo tableInfo = entry.getValue(); 1377 1378 List<String> listQuery = tableInfo.getCreateQueries(); 1379 _executeQueryFromlistQuery(listQuery); 1380 nbTableCreated += listQuery.size(); 1381 1382 int pourcent = nbTableCreated * 100 / nbTotalTable; 1383 if (pourcent >= limitPourcentReport) 1384 { 1385 if (isInfoEnabled) 1386 { 1387 List<String> i18nParams = new ArrayList<>(); 1388 i18nParams.add(String.valueOf(limitPourcentReport)); 1389 getLogger().info(_i18nTranslator.translate(new I18nizableText("plugin.contentio", "PLUGINS_CONTENTIO_CONTENT_EXPORT_LOG_ANALYZE_TABLE_CREATE_ADVANCE", i18nParams))); 1390 } 1391 limitPourcentReport += 10; 1392 } 1393 1394 _executeQueryFromlistQuery(tableInfo.getCommentQueries()); 1395 _executeQueryFromlistQuery(tableInfo.getInsertQueries()); 1396 } 1397 } 1398 catch (IOException e) 1399 { 1400 getLogger().error(_i18nTranslator.translate(new I18nizableText("plugin.contentio", "PLUGINS_CONTENTIO_CONTENT_EXPORT_LOG_ANALYZE_TABLE_GET_FILE_ERROR")), e); 1401 } 1402 finally 1403 { 1404 if (isInfoEnabled) 1405 { 1406 List<String> i18nParams = new ArrayList<>(); 1407 i18nParams.add(String.valueOf(nbTableCreated)); 1408 getLogger().info(_i18nTranslator.translate(new I18nizableText("plugin.contentio", "PLUGINS_CONTENTIO_CONTENT_EXPORT_LOG_ANALYZE_TABLE_CREATE_FINISH", i18nParams))); 1409 } 1410 } 1411 } 1412 1413 private int _getNbTable() 1414 { 1415 int nbTable = 0; 1416 for (Entry<String, ExportTableInfo> entry : _tablesInfos.entrySet()) 1417 { 1418 ExportTableInfo tableInfo = entry.getValue(); 1419 1420 List<String> listQuery = tableInfo.getCreateQueries(); 1421 nbTable += listQuery.size(); 1422 } 1423 1424 return nbTable; 1425 } 1426 1427 /** 1428 * Execute query list 1429 * @param listQuery the list of query to execute 1430 * @throws SQLException if a sql error occurred 1431 * @throws IOException if an IO error occurred 1432 */ 1433 protected void _executeQueryFromlistQuery(List<String> listQuery) throws SQLException, IOException 1434 { 1435 for (String query : listQuery) 1436 { 1437 getLogger().debug(query); 1438 1439 PreparedStatement stmt = null; 1440 try 1441 { 1442 stmt = _connection.prepareStatement(query); 1443 stmt.execute(); 1444 } 1445 catch (SQLException e) 1446 { 1447 throw new SQLException("The SQL query failed : " + query, e); 1448 } 1449 finally 1450 { 1451 // Close the connection resources 1452 ConnectionHelper.cleanup(stmt); 1453 } 1454 } 1455 } 1456 1457 /** 1458 * Prepare INSERT statement 1459 * @param tableName the table name 1460 * @return the INSERT preparedStatement 1461 * @throws SQLException if a sql error occurred 1462 * @throws ContextException if a context error occurred 1463 */ 1464 protected PreparedStatement getInsertPreparedStatementFromTableName(String tableName) throws SQLException, ContextException 1465 { 1466 StringBuilder sql = new StringBuilder(); 1467 sql.append("INSERT INTO "); 1468 sql.append(_normalizeNameComponent.normalizedTableName(_sqlTablePrefix, _mappingPolicy, tableName, _connection)); 1469 sql.append(" VALUES ( ?"); 1470 1471 ExportTableInfo tableInfo = _tablesInfos.get(tableName); 1472 1473 for (int i = 1; i < tableInfo.getNbColumns(); i++) 1474 { 1475 sql.append(", ?"); 1476 } 1477 sql.append(")"); 1478 1479 PreparedStatement stmt = _connection.prepareStatement(sql.toString()); 1480 return stmt; 1481 } 1482}