/*! ****************************************************************************** * * Pentaho Data Integration * * Copyright (C) 2002-2017 by Pentaho : http://www.pentaho.com * ******************************************************************************* * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ package org.pentaho.di.repository.kdr; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.zip.GZIPOutputStream; import org.apache.commons.codec.binary.Base64; import org.pentaho.di.cluster.ClusterSchema; import org.pentaho.di.cluster.SlaveServer; import org.pentaho.di.core.Condition; import org.pentaho.di.core.Const; import org.pentaho.di.core.util.Utils; import org.pentaho.di.i18n.BaseMessages; import org.pentaho.di.core.NotePadMeta; import org.pentaho.di.core.ProgressMonitorListener; import org.pentaho.di.core.RowMetaAndData; import org.pentaho.di.core.database.Database; import org.pentaho.di.core.database.DatabaseMeta; import org.pentaho.di.core.exception.KettleDatabaseException; import org.pentaho.di.core.exception.KettleDependencyException; import org.pentaho.di.core.exception.KettleException; import org.pentaho.di.core.extension.ExtensionPointHandler; import org.pentaho.di.core.extension.KettleExtensionPoint; import org.pentaho.di.core.logging.LogChannel; import org.pentaho.di.core.row.ValueMetaAndData; import org.pentaho.di.core.row.value.ValueMetaDate; import org.pentaho.di.core.row.value.ValueMetaInteger; import org.pentaho.di.core.row.value.ValueMetaString; import org.pentaho.di.job.JobMeta; import org.pentaho.di.job.entry.JobEntryBase; import org.pentaho.di.partition.PartitionSchema; import org.pentaho.di.repository.IRepositoryExporter; import org.pentaho.di.repository.IRepositoryImporter; import org.pentaho.di.repository.IRepositoryService; import org.pentaho.di.repository.IUser; import org.pentaho.di.repository.LongObjectId; import org.pentaho.di.repository.ObjectId; import org.pentaho.di.repository.RepositoryDirectory; import org.pentaho.di.repository.RepositoryDirectoryInterface; import org.pentaho.di.repository.RepositoryElementInterface; import org.pentaho.di.repository.RepositoryElementMetaInterface; import org.pentaho.di.repository.RepositoryExporter; import org.pentaho.di.repository.RepositoryImporter; import org.pentaho.di.repository.RepositoryMeta; import org.pentaho.di.repository.RepositoryObject; import org.pentaho.di.repository.RepositoryObjectType; import org.pentaho.di.repository.RepositoryOperation; import org.pentaho.di.repository.RepositorySecurityManager; import org.pentaho.di.repository.RepositorySecurityProvider; import org.pentaho.di.repository.UserInfo; import org.pentaho.di.repository.kdr.delegates.KettleDatabaseRepositoryClusterSchemaDelegate; import org.pentaho.di.repository.kdr.delegates.KettleDatabaseRepositoryConditionDelegate; import org.pentaho.di.repository.kdr.delegates.KettleDatabaseRepositoryConnectionDelegate; import org.pentaho.di.repository.kdr.delegates.KettleDatabaseRepositoryDatabaseDelegate; import org.pentaho.di.repository.kdr.delegates.KettleDatabaseRepositoryDirectoryDelegate; import org.pentaho.di.repository.kdr.delegates.KettleDatabaseRepositoryJobDelegate; import org.pentaho.di.repository.kdr.delegates.KettleDatabaseRepositoryJobEntryDelegate; import org.pentaho.di.repository.kdr.delegates.KettleDatabaseRepositoryMetaStoreDelegate; import org.pentaho.di.repository.kdr.delegates.KettleDatabaseRepositoryNotePadDelegate; import org.pentaho.di.repository.kdr.delegates.KettleDatabaseRepositoryPartitionSchemaDelegate; import org.pentaho.di.repository.kdr.delegates.KettleDatabaseRepositorySlaveServerDelegate; import org.pentaho.di.repository.kdr.delegates.KettleDatabaseRepositoryStepDelegate; import org.pentaho.di.repository.kdr.delegates.KettleDatabaseRepositoryTransDelegate; import org.pentaho.di.repository.kdr.delegates.KettleDatabaseRepositoryUserDelegate; import org.pentaho.di.repository.kdr.delegates.KettleDatabaseRepositoryValueDelegate; import org.pentaho.di.repository.kdr.delegates.metastore.KettleDatabaseRepositoryMetaStore; import org.pentaho.di.shared.SharedObjects; import org.pentaho.di.trans.TransMeta; /** * * This class handles interactions with a Kettle repository. * * @author Matt Created on 31-mrt-2004 * */ public class KettleDatabaseRepository extends KettleDatabaseRepositoryBase { // private static Class<?> PKG = Repository.class; // for i18n purposes, needed by Translator2!! public KettleDatabaseRepositoryTransDelegate transDelegate; public KettleDatabaseRepositoryJobDelegate jobDelegate; public KettleDatabaseRepositoryDatabaseDelegate databaseDelegate; public KettleDatabaseRepositorySlaveServerDelegate slaveServerDelegate; public KettleDatabaseRepositoryClusterSchemaDelegate clusterSchemaDelegate; public KettleDatabaseRepositoryPartitionSchemaDelegate partitionSchemaDelegate; public KettleDatabaseRepositoryDirectoryDelegate directoryDelegate; public KettleDatabaseRepositoryConnectionDelegate connectionDelegate; public KettleDatabaseRepositoryUserDelegate userDelegate; public KettleDatabaseRepositoryConditionDelegate conditionDelegate; public KettleDatabaseRepositoryValueDelegate valueDelegate; public KettleDatabaseRepositoryNotePadDelegate notePadDelegate; public KettleDatabaseRepositoryStepDelegate stepDelegate; public KettleDatabaseRepositoryJobEntryDelegate jobEntryDelegate; public KettleDatabaseRepositoryMetaStoreDelegate metaStoreDelegate; private KettleDatabaseRepositorySecurityProvider securityProvider; private Map<Class<? extends IRepositoryService>, IRepositoryService> serviceMap; private List<Class<? extends IRepositoryService>> serviceList; public KettleDatabaseRepositoryMetaStore metaStore; public KettleDatabaseRepository() { super(); metaStore = null; } /** * Initialize the repository with the repository metadata and user information. */ public void init( RepositoryMeta repositoryMeta ) { this.repositoryMeta = (KettleDatabaseRepositoryMeta) repositoryMeta; this.serviceList = new ArrayList<>(); this.serviceMap = new HashMap<>(); this.log = new LogChannel( this ); init(); } private void init() { // Create the delegates... // this.transDelegate = new KettleDatabaseRepositoryTransDelegate( this ); this.jobDelegate = new KettleDatabaseRepositoryJobDelegate( this ); this.databaseDelegate = new KettleDatabaseRepositoryDatabaseDelegate( this ); this.slaveServerDelegate = new KettleDatabaseRepositorySlaveServerDelegate( this ); this.clusterSchemaDelegate = new KettleDatabaseRepositoryClusterSchemaDelegate( this ); this.partitionSchemaDelegate = new KettleDatabaseRepositoryPartitionSchemaDelegate( this ); this.directoryDelegate = new KettleDatabaseRepositoryDirectoryDelegate( this ); this.connectionDelegate = new KettleDatabaseRepositoryConnectionDelegate( this, repositoryMeta.getConnection() ); this.userDelegate = new KettleDatabaseRepositoryUserDelegate( this ); this.conditionDelegate = new KettleDatabaseRepositoryConditionDelegate( this ); this.valueDelegate = new KettleDatabaseRepositoryValueDelegate( this ); this.notePadDelegate = new KettleDatabaseRepositoryNotePadDelegate( this ); this.stepDelegate = new KettleDatabaseRepositoryStepDelegate( this ); this.jobEntryDelegate = new KettleDatabaseRepositoryJobEntryDelegate( this ); this.metaStoreDelegate = new KettleDatabaseRepositoryMetaStoreDelegate( this ); this.creationHelper = new KettleDatabaseRepositoryCreationHelper( this ); } /** * @return A new repository meta object */ public RepositoryMeta createRepositoryMeta() { return new KettleDatabaseRepositoryMeta(); } /** * Connect to the repository. * * @throws KettleException * in case there is a general unexpected error or if we're already connected */ public void connect( String username, String password ) throws KettleException { connect( username, password, false ); } /** * Connect to the repository. * * @throws KettleException * in case there is a general unexpected error or if we're already connected */ public void connect( String username, String password, boolean upgrade ) throws KettleException { // first disconnect if already connected connectionDelegate.connect( upgrade, upgrade ); try { IUser userinfo = userDelegate.loadUserInfo( new UserInfo(), username, password ); securityProvider = new KettleDatabaseRepositorySecurityProvider( this, repositoryMeta, userinfo ); // We need to add services in the list in the order of dependencies registerRepositoryService( RepositorySecurityProvider.class, securityProvider ); registerRepositoryService( RepositorySecurityManager.class, securityProvider ); // Apparently, MySQL InnoDB opens a new transaction simply by doing a // lookup. // connectionDelegate.closeReadTransaction(); // Open the metaStore for business too... // metaStore = new KettleDatabaseRepositoryMetaStore( this ); } catch ( KettleDatabaseException e ) { // if we fail to log in, disconnect and then rethrow the exception connectionDelegate.disconnect(); throw e; } } @Override public boolean test() { try { getDatabase().connect(); } catch ( KettleDatabaseException kde ) { return false; } return true; } @Override public void create() { if ( repositoryMeta.getConnection() != null ) { if ( repositoryMeta.getConnection().getAccessType() == DatabaseMeta.TYPE_ACCESS_ODBC ) { // This will change in a future story log.logDebug( "ODBC type is not advised for repository use" ); } try { if ( !getDatabaseMeta().getDatabaseInterface().supportsRepository() ) { // show error about not being valid log.logError( "This database type does not support being a repository" ); } connectionDelegate.connect( true, true ); boolean upgrade = false; try { String userTableName = getDatabaseMeta().quoteField( KettleDatabaseRepository.TABLE_R_USER ); upgrade = getDatabase().checkTableExists( userTableName ); if ( upgrade ) { // This will change in future story log.logDebug( "Database upgrade will now take place" ); } } catch ( KettleDatabaseException dbe ) { // Roll back the connection: this is required for certain databases like PGSQL // Otherwise we can't execute any other DDL statement. // rollback(); // Don't show an error anymore, just go ahead and propose to create the repository! } if ( upgrade ) { // authenticate as admin before upgrade reconnectAsAdminForUpgrade(); } createRepositorySchema( null, upgrade, new ArrayList<String>(), false ); disconnect(); } catch ( KettleException ke ) { log.logError( "An error has occurred creating a repository" ); } } } /** * Reconnect to the repository as "admin" to perform upgrade. */ void reconnectAsAdminForUpgrade() { try { // disconnect before connecting, we connected above already disconnect(); connect( "admin", "admin", true ); } catch ( KettleException e ) { log.logError( BaseMessages.getString( KettleDatabaseRepository.class, "KettleDatabaseRepository.ERROR_CONNECT_TO_REPOSITORY" ), e ); } } /** * Add the repository service to the map and add the interface to the list * * @param clazz * @param repositoryService */ private void registerRepositoryService( Class<? extends IRepositoryService> clazz, IRepositoryService repositoryService ) { this.serviceMap.put( clazz, repositoryService ); this.serviceList.add( clazz ); } public synchronized void commit() throws KettleException { connectionDelegate.commit(); } public synchronized void rollback() { connectionDelegate.rollback(); } public IUser getUserInfo() { if ( securityProvider != null ) { return securityProvider.getUserInfo(); } else { return null; } } /** * Return the major repository version. * * @return the major repository version. */ public int getMajorVersion() { return connectionDelegate.getMajorVersion(); } /** * Return the minor repository version. * * @return the minor repository version. */ public int getMinorVersion() { return connectionDelegate.getMinorVersion(); } /** * Get the repository version. * * @return The repository version as major version + "." + minor version */ public String getVersion() { return connectionDelegate.getVersion(); } // TransMeta // public TransMeta loadTransformation( String transname, RepositoryDirectoryInterface repdir, ProgressMonitorListener monitor, boolean setInternalVariables, String versionName ) throws KettleException { try { securityProvider.validateAction( RepositoryOperation.READ_TRANSFORMATION ); TransMeta transMeta = new TransMeta(); transMeta = transDelegate.loadTransformation( transMeta, transname, repdir, monitor, setInternalVariables ); ExtensionPointHandler.callExtensionPoint( log, KettleExtensionPoint.TransformationMetaLoaded.id, transMeta ); return transMeta; } finally { connectionDelegate.closeReadTransaction(); } } public SharedObjects readTransSharedObjects( TransMeta transMeta ) throws KettleException { try { return transDelegate.readTransSharedObjects( transMeta ); } finally { connectionDelegate.closeReadTransaction(); } } public ObjectId renameTransformation( ObjectId id_transformation, RepositoryDirectoryInterface newDir, String newName ) throws KettleException { return renameTransformation( id_transformation, null, newDir, newName ); } public synchronized ObjectId renameTransformation( ObjectId id_transformation, String versionComment, RepositoryDirectoryInterface newDir, String newName ) throws KettleException { securityProvider.validateAction( RepositoryOperation.MODIFY_TRANSFORMATION ); transDelegate.renameTransformation( id_transformation, newDir, newName ); if ( !Utils.isEmpty( versionComment ) ) { insertLogEntry( versionComment ); } return id_transformation; // The same in our case. } // JobMeta /** * Load a job in a directory * * @param jobname * The name of the job * @param repdir * The directory in which the job resides. * @param the * monitor to use as feedback in a UI (or null if not used) * @throws KettleException */ public JobMeta loadJob( String jobname, RepositoryDirectoryInterface repdir, ProgressMonitorListener monitor, String versionName ) throws KettleException { try { securityProvider.validateAction( RepositoryOperation.READ_JOB ); JobMeta jobMeta = jobDelegate.loadJobMeta( jobname, repdir, monitor ); ExtensionPointHandler.callExtensionPoint( log, KettleExtensionPoint.JobMetaLoaded.id, jobMeta ); return jobMeta; } finally { connectionDelegate.closeReadTransaction(); } } public SharedObjects readJobMetaSharedObjects( JobMeta jobMeta ) throws KettleException { try { return jobDelegate.readSharedObjects( jobMeta ); } finally { connectionDelegate.closeReadTransaction(); } } public ObjectId renameJob( ObjectId id_job, RepositoryDirectoryInterface dir, String newname ) throws KettleException { return renameJob( id_job, null, dir, newname ); } public synchronized ObjectId renameJob( ObjectId id_job, String versionComment, RepositoryDirectoryInterface dir, String newname ) throws KettleException { securityProvider.validateAction( RepositoryOperation.MODIFY_TRANSFORMATION ); jobDelegate.renameJob( id_job, dir, newname ); if ( !Utils.isEmpty( versionComment ) ) { insertLogEntry( versionComment ); } return id_job; // Same in this case } // Common methods... // //////////////////////////// public boolean exists( String name, RepositoryDirectoryInterface repositoryDirectory, RepositoryObjectType objectType ) throws KettleException { try { switch ( objectType ) { case JOB: securityProvider.validateAction( RepositoryOperation.READ_JOB ); return jobDelegate.existsJobMeta( name, repositoryDirectory, objectType ); case TRANSFORMATION: securityProvider.validateAction( RepositoryOperation.READ_TRANSFORMATION ); return transDelegate.existsTransMeta( name, repositoryDirectory, objectType ); default: throw new KettleException( "We can't verify the existance of repository element type [" + objectType + "]" ); } } finally { connectionDelegate.closeReadTransaction(); } } public void save( RepositoryElementInterface repositoryElement, String versionComment ) throws KettleException { save( repositoryElement, versionComment, null ); } public void save( RepositoryElementInterface repositoryElement, String versionComment, ProgressMonitorListener monitor, boolean overwrite ) throws KettleException { save( repositoryElement, versionComment, monitor, null, false, overwrite ); } public void save( RepositoryElementInterface repositoryElement, String versionComment, ProgressMonitorListener monitor, ObjectId parentId, boolean used, boolean overwrite ) throws KettleException { try { lockRepository(); if ( !Utils.isEmpty( versionComment ) ) { insertLogEntry( versionComment ); } switch ( repositoryElement.getRepositoryElementType() ) { case JOB: securityProvider.validateAction( RepositoryOperation.MODIFY_JOB ); jobDelegate.saveJob( (JobMeta) repositoryElement, versionComment, monitor, overwrite ); break; case TRANSFORMATION: securityProvider.validateAction( RepositoryOperation.MODIFY_TRANSFORMATION ); transDelegate.saveTransformation( (TransMeta) repositoryElement, versionComment, monitor, overwrite ); break; case DATABASE: securityProvider.validateAction( RepositoryOperation.MODIFY_DATABASE ); databaseDelegate.saveDatabaseMeta( (DatabaseMeta) repositoryElement ); break; case SLAVE_SERVER: securityProvider.validateAction( RepositoryOperation.MODIFY_SLAVE_SERVER ); slaveServerDelegate.saveSlaveServer( (SlaveServer) repositoryElement, parentId, used, overwrite ); break; case CLUSTER_SCHEMA: securityProvider.validateAction( RepositoryOperation.MODIFY_CLUSTER_SCHEMA ); clusterSchemaDelegate.saveClusterSchema( (ClusterSchema) repositoryElement, versionComment, parentId, used, overwrite ); break; case PARTITION_SCHEMA: securityProvider.validateAction( RepositoryOperation.MODIFY_PARTITION_SCHEMA ); partitionSchemaDelegate.savePartitionSchema( (PartitionSchema) repositoryElement, parentId, used, overwrite ); break; default: throw new KettleException( "We can't save the element with type [" + repositoryElement.getRepositoryElementType() + "] in the repository" ); } // Automatically commit changes to these elements. // commit(); } finally { unlockRepository(); } } @Override public void save( RepositoryElementInterface repositoryElement, String versionComment, Calendar versionDate, ProgressMonitorListener monitor, boolean overwrite ) throws KettleException { save( repositoryElement, versionComment, monitor, null, false, overwrite ); } // Condition /** * * Read a condition from the repository. * * @param id_condition * The condition id * @throws KettleException * if something goes wrong. */ public Condition loadCondition( ObjectId id_condition ) throws KettleException { return conditionDelegate.loadCondition( id_condition ); } public ObjectId saveCondition( Condition condition ) throws KettleException { return saveCondition( condition, null ); } public ObjectId saveCondition( Condition condition, ObjectId id_condition_parent ) throws KettleException { return conditionDelegate.saveCondition( condition, id_condition_parent ); } // DatabaseMeta /** * Load the Database connection Metadata from the repository * * @param id_database * the id of the database connection to load * @throws KettleException * in case something goes wrong with database, connection, etc. */ public DatabaseMeta loadDatabaseMeta( ObjectId id_database, String versionName ) throws KettleException { return databaseDelegate.loadDatabaseMeta( id_database ); } /** * Remove a database connection from the repository * * @param databaseName * The name of the connection to remove * @throws KettleException * In case something went wrong: database error, insufficient permissions, depending objects, etc. */ public void deleteDatabaseMeta( String databaseName ) throws KettleException { securityProvider.validateAction( RepositoryOperation.DELETE_DATABASE ); databaseDelegate.deleteDatabaseMeta( databaseName ); commit(); } // ClusterSchema public ClusterSchema loadClusterSchema( ObjectId idClusterSchema, List<SlaveServer> slaveServers, String versionLabel ) throws KettleException { return clusterSchemaDelegate.loadClusterSchema( idClusterSchema, slaveServers ); } // SlaveServer public SlaveServer loadSlaveServer( ObjectId id_slave_server, String versionName ) throws KettleException { return slaveServerDelegate.loadSlaveServer( id_slave_server ); } // PartitionSchema public PartitionSchema loadPartitionSchema( ObjectId id_partition_schema, String versionName ) throws KettleException { return partitionSchemaDelegate.loadPartitionSchema( id_partition_schema ); } // ValueMetaAndData public ValueMetaAndData loadValueMetaAndData( ObjectId id_value ) throws KettleException { return valueDelegate.loadValueMetaAndData( id_value ); } // NotePadMeta public NotePadMeta loadNotePadMeta( ObjectId id_note ) throws KettleException { return notePadDelegate.loadNotePadMeta( id_note ); } public void saveNotePadMeta( NotePadMeta note, ObjectId id_transformation ) throws KettleException { notePadDelegate.saveNotePadMeta( note, id_transformation ); } // Directory stuff public RepositoryDirectoryInterface loadRepositoryDirectoryTree() throws KettleException { RepositoryDirectory root = new RepositoryDirectory(); root.setObjectId( new LongObjectId( 0L ) ); return directoryDelegate.loadRepositoryDirectoryTree( root ); } public RepositoryDirectoryInterface loadRepositoryDirectoryTree( RepositoryDirectoryInterface root ) throws KettleException { try { return directoryDelegate.loadRepositoryDirectoryTree( root ); } finally { connectionDelegate.closeReadTransaction(); } } public RepositoryDirectoryInterface findDirectory( String directory ) throws KettleException { return loadRepositoryDirectoryTree().findDirectory( directory ); } public RepositoryDirectoryInterface findDirectory( ObjectId directory ) throws KettleException { return loadRepositoryDirectoryTree().findDirectory( directory ); } public void saveRepositoryDirectory( RepositoryDirectoryInterface dir ) throws KettleException { securityProvider.validateAction( RepositoryOperation.CREATE_DIRECTORY ); directoryDelegate.saveRepositoryDirectory( dir ); } public void deleteRepositoryDirectory( RepositoryDirectoryInterface dir ) throws KettleException { securityProvider.validateAction( RepositoryOperation.DELETE_DIRECTORY ); directoryDelegate.delRepositoryDirectory( dir, true ); commit(); } public ObjectId renameRepositoryDirectory( ObjectId id, RepositoryDirectoryInterface newParentDir, String newName ) throws KettleException { ObjectId result = null; securityProvider.validateAction( RepositoryOperation.RENAME_DIRECTORY ); result = directoryDelegate.renameRepositoryDirectory( id, newParentDir, newName ); commit(); return result; } /** * Create a new directory, possibly by creating several sub-directies of / at the same time. * * @param parentDirectory * the parent directory * @param directoryPath * The path to the new Repository Directory, to be created. * @return The created sub-directory * @throws KettleException * In case something goes wrong */ public RepositoryDirectoryInterface createRepositoryDirectory( RepositoryDirectoryInterface parentDirectory, String directoryPath ) throws KettleException { securityProvider.validateAction( RepositoryOperation.CREATE_DIRECTORY ); return directoryDelegate.createRepositoryDirectory( parentDirectory, directoryPath ); } // /////////////////////////////////////////////////////////////////////////////////// // LOOKUP ID TODO: get rid of these as well! Move to a delegate // /////////////////////////////////////////////////////////////////////////////////// public synchronized ObjectId getRootDirectoryID() throws KettleException { RowMetaAndData result = connectionDelegate.getOneRow( "SELECT " + quote( KettleDatabaseRepository.FIELD_DIRECTORY_ID_DIRECTORY ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_DIRECTORY ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_DIRECTORY_ID_DIRECTORY_PARENT ) + " = 0" ); if ( result != null && result.isNumeric( 0 ) ) { return new LongObjectId( result.getInteger( 0, -1 ) ); } return null; } public synchronized int getNrSubDirectories( ObjectId id_directory ) throws KettleException { return directoryDelegate.getNrSubDirectories( id_directory ); } public synchronized ObjectId[] getSubDirectoryIDs( ObjectId id_directory ) throws KettleException { return directoryDelegate.getSubDirectoryIDs( id_directory ); } // /////////////////////////////////////////////////////////////////////////////////// // INSERT VALUES // /////////////////////////////////////////////////////////////////////////////////// public synchronized ObjectId insertLogEntry( String description ) throws KettleException { ObjectId id = connectionDelegate.getNextLogID(); RowMetaAndData table = new RowMetaAndData(); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_REPOSITORY_LOG_ID_REPOSITORY_LOG ), id ); table.addValue( new ValueMetaString( KettleDatabaseRepository.FIELD_REPOSITORY_LOG_REP_VERSION ), getVersion() ); table.addValue( new ValueMetaDate( KettleDatabaseRepository.FIELD_REPOSITORY_LOG_LOG_DATE ), new Date() ); table.addValue( new ValueMetaString( KettleDatabaseRepository.FIELD_REPOSITORY_LOG_LOG_USER ), getUserInfo() != null ? getUserInfo().getLogin() : "admin" ); table.addValue( new ValueMetaString( KettleDatabaseRepository.FIELD_REPOSITORY_LOG_OPERATION_DESC ), description ); connectionDelegate.insertTableRow( KettleDatabaseRepository.TABLE_R_REPOSITORY_LOG, table ); return id; } public synchronized void insertTransNote( ObjectId id_transformation, ObjectId id_note ) throws KettleException { RowMetaAndData table = new RowMetaAndData(); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_TRANS_NOTE_ID_TRANSFORMATION ), id_transformation ); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_TRANS_NOTE_ID_NOTE ), id_note ); connectionDelegate.insertTableRow( KettleDatabaseRepository.TABLE_R_TRANS_NOTE, table ); } public synchronized void insertJobNote( ObjectId id_job, ObjectId id_note ) throws KettleException { RowMetaAndData table = new RowMetaAndData(); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_JOB_NOTE_ID_JOB ), id_job ); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_JOB_NOTE_ID_NOTE ), id_note ); connectionDelegate.insertTableRow( KettleDatabaseRepository.TABLE_R_JOB_NOTE, table ); } public synchronized void insertStepDatabase( ObjectId id_transformation, ObjectId id_step, ObjectId id_database ) throws KettleException { // First check if the relationship is already there. // There is no need to store it twice! RowMetaAndData check = getStepDatabase( id_step ); if ( check.getInteger( 0 ) == null ) { RowMetaAndData table = new RowMetaAndData(); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_STEP_DATABASE_ID_TRANSFORMATION ), id_transformation ); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_STEP_DATABASE_ID_STEP ), id_step ); table .addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_STEP_DATABASE_ID_DATABASE ), id_database ); connectionDelegate.insertTableRow( KettleDatabaseRepository.TABLE_R_STEP_DATABASE, table ); } } public synchronized void insertJobEntryDatabase( ObjectId id_job, ObjectId id_jobentry, ObjectId id_database ) throws KettleException { // First check if the relationship is already there. // There is no need to store it twice! RowMetaAndData check = getJobEntryDatabase( id_jobentry ); if ( check.getInteger( 0 ) == null ) { RowMetaAndData table = new RowMetaAndData(); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_JOBENTRY_DATABASE_ID_JOB ), id_job ); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_JOBENTRY_DATABASE_ID_JOBENTRY ), id_jobentry ); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_JOBENTRY_DATABASE_ID_DATABASE ), id_database ); connectionDelegate.insertTableRow( KettleDatabaseRepository.TABLE_R_JOBENTRY_DATABASE, table ); } } public synchronized ObjectId insertTransformationPartitionSchema( ObjectId id_transformation, ObjectId id_partition_schema ) throws KettleException { ObjectId id = connectionDelegate.getNextTransformationPartitionSchemaID(); RowMetaAndData table = new RowMetaAndData(); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_TRANS_PARTITION_SCHEMA_ID_TRANS_PARTITION_SCHEMA ), id ); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_TRANS_PARTITION_SCHEMA_ID_TRANSFORMATION ), id_transformation ); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_TRANS_PARTITION_SCHEMA_ID_PARTITION_SCHEMA ), id_partition_schema ); connectionDelegate.insertTableRow( KettleDatabaseRepository.TABLE_R_TRANS_PARTITION_SCHEMA, table ); return id; } public synchronized ObjectId insertClusterSlave( ClusterSchema clusterSchema, SlaveServer slaveServer ) throws KettleException { ObjectId id = connectionDelegate.getNextClusterSlaveID(); RowMetaAndData table = new RowMetaAndData(); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_CLUSTER_SLAVE_ID_CLUSTER_SLAVE ), id ); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_CLUSTER_SLAVE_ID_CLUSTER ), clusterSchema .getObjectId() ); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_CLUSTER_SLAVE_ID_SLAVE ), slaveServer .getObjectId() ); connectionDelegate.insertTableRow( KettleDatabaseRepository.TABLE_R_CLUSTER_SLAVE, table ); return id; } public synchronized ObjectId insertTransformationCluster( ObjectId id_transformation, ObjectId id_cluster ) throws KettleException { ObjectId id = connectionDelegate.getNextTransformationClusterID(); RowMetaAndData table = new RowMetaAndData(); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_TRANS_CLUSTER_ID_TRANS_CLUSTER ), id ); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_TRANS_CLUSTER_ID_TRANSFORMATION ), id_transformation ); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_TRANS_CLUSTER_ID_CLUSTER ), id_cluster ); connectionDelegate.insertTableRow( KettleDatabaseRepository.TABLE_R_TRANS_CLUSTER, table ); return id; } public synchronized ObjectId insertTransformationSlave( ObjectId id_transformation, ObjectId id_slave ) throws KettleException { ObjectId id = connectionDelegate.getNextTransformationSlaveID(); RowMetaAndData table = new RowMetaAndData(); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_TRANS_SLAVE_ID_TRANS_SLAVE ), id ); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_TRANS_SLAVE_ID_TRANSFORMATION ), id_transformation ); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_TRANS_SLAVE_ID_SLAVE ), id_slave ); connectionDelegate.insertTableRow( KettleDatabaseRepository.TABLE_R_TRANS_SLAVE, table ); return id; } public synchronized void insertTransStepCondition( ObjectId id_transformation, ObjectId id_step, ObjectId id_condition ) throws KettleException { String tablename = KettleDatabaseRepository.TABLE_R_TRANS_STEP_CONDITION; RowMetaAndData table = new RowMetaAndData(); table .addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_TRANS_STEP_CONDITION_ID_TRANSFORMATION ), id_transformation ); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_TRANS_STEP_CONDITION_ID_STEP ), id_step ); table.addValue( new ValueMetaInteger( KettleDatabaseRepository.FIELD_TRANS_STEP_CONDITION_ID_CONDITION ), id_condition ); connectionDelegate.insertTableRow( tablename, table ); } // //////////////////////////////////////////////////////////////////////////////////////// // READ DATA FROM REPOSITORY // //////////////////////////////////////////////////////////////////////////////////////// public synchronized String[] getTransformationNames( ObjectId id_directory, boolean includeDeleted ) throws KettleException { return connectionDelegate.getStrings( "SELECT " + quote( KettleDatabaseRepository.FIELD_TRANSFORMATION_NAME ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_TRANSFORMATION ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_TRANSFORMATION_ID_DIRECTORY ) + " = ? ORDER BY " + quote( KettleDatabaseRepository.FIELD_TRANSFORMATION_NAME ), id_directory ); } public List<RepositoryElementMetaInterface> getJobObjects( ObjectId id_directory, boolean includeDeleted ) throws KettleException { return getRepositoryObjects( quoteTable( KettleDatabaseRepository.TABLE_R_JOB ), RepositoryObjectType.JOB, id_directory ); } public List<RepositoryElementMetaInterface> getTransformationObjects( ObjectId id_directory, boolean includeDeleted ) throws KettleException { List<RepositoryElementMetaInterface> objects = getRepositoryObjects( quoteTable( KettleDatabaseRepository.TABLE_R_TRANSFORMATION ), RepositoryObjectType.TRANSFORMATION, id_directory ); if ( ( log != null ) && log.isDebug() && objects.size() > 0 ) { log.logDebug( objects.get( 0 ).getRepositoryDirectory().getPath() ); } return objects; } /** * @param id_directory * @return A list of RepositoryObjects * * @throws KettleException */ private synchronized List<RepositoryElementMetaInterface> getRepositoryObjects( String tableName, RepositoryObjectType objectType, ObjectId id_directory ) throws KettleException { return connectionDelegate.getRepositoryObjects( tableName, objectType, id_directory ); } public synchronized String[] getJobNames( ObjectId id_directory, boolean includeDeleted ) throws KettleException { return connectionDelegate.getStrings( "SELECT " + quote( KettleDatabaseRepository.FIELD_JOB_NAME ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_JOB ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_JOB_ID_DIRECTORY ) + " = ? ORDER BY " + quote( KettleDatabaseRepository.FIELD_JOB_NAME ), id_directory ); } public synchronized String[] getDirectoryNames( ObjectId id_directory ) throws KettleException { return connectionDelegate.getStrings( "SELECT " + quote( KettleDatabaseRepository.FIELD_DIRECTORY_DIRECTORY_NAME ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_DIRECTORY ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_DIRECTORY_ID_DIRECTORY_PARENT ) + " = ? ORDER BY " + quote( KettleDatabaseRepository.FIELD_DIRECTORY_DIRECTORY_NAME ), id_directory ); } public synchronized String[] getJobNames() throws KettleException { return connectionDelegate.getStrings( "SELECT " + quote( KettleDatabaseRepository.FIELD_JOB_NAME ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_JOB ) + " ORDER BY " + quote( KettleDatabaseRepository.FIELD_JOB_NAME ) ); } public ObjectId[] getSubConditionIDs( ObjectId id_condition ) throws KettleException { return connectionDelegate.getIDs( "SELECT " + quote( KettleDatabaseRepository.FIELD_CONDITION_ID_CONDITION ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_CONDITION ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_CONDITION_ID_CONDITION_PARENT ) + " = ? ORDER BY " + quote( KettleDatabaseRepository.FIELD_CONDITION_ID_CONDITION ), id_condition ); } public ObjectId[] getTransNoteIDs( ObjectId id_transformation ) throws KettleException { return connectionDelegate.getIDs( "SELECT " + quote( KettleDatabaseRepository.FIELD_TRANS_NOTE_ID_NOTE ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_TRANS_NOTE ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_TRANS_NOTE_ID_TRANSFORMATION ) + " = ?", id_transformation ); } public ObjectId[] getTransformationConditionIDs( ObjectId id_transformation ) throws KettleException { return connectionDelegate.getIDs( "SELECT " + quote( KettleDatabaseRepository.FIELD_TRANS_STEP_CONDITION_ID_CONDITION ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_TRANS_STEP_CONDITION ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_TRANS_STEP_CONDITION_ID_TRANSFORMATION ) + " = ? ", id_transformation ); } public ObjectId[] getTransformationDatabaseIDs( ObjectId id_transformation ) throws KettleException { return connectionDelegate.getIDs( "SELECT " + quote( KettleDatabaseRepository.FIELD_STEP_DATABASE_ID_DATABASE ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_STEP_DATABASE ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_STEP_DATABASE_ID_TRANSFORMATION ) + " = ?", id_transformation ); } public ObjectId[] getJobNoteIDs( ObjectId id_job ) throws KettleException { return connectionDelegate.getIDs( "SELECT " + quote( KettleDatabaseRepository.FIELD_JOB_NOTE_ID_NOTE ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_JOB_NOTE ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_JOB_NOTE_ID_JOB ) + " = ?", id_job ); } public ObjectId[] getDatabaseIDs( boolean includeDeleted ) throws KettleException { return connectionDelegate.getIDs( "SELECT " + quote( KettleDatabaseRepository.FIELD_DATABASE_ID_DATABASE ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_DATABASE ) + " ORDER BY " + quote( KettleDatabaseRepository.FIELD_DATABASE_ID_DATABASE ) ); } public ObjectId[] getDatabaseAttributeIDs( ObjectId id_database ) throws KettleException { return connectionDelegate.getIDs( "SELECT " + quote( KettleDatabaseRepository.FIELD_DATABASE_ATTRIBUTE_ID_DATABASE_ATTRIBUTE ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_DATABASE_ATTRIBUTE ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_DATABASE_ATTRIBUTE_ID_DATABASE ) + " = ? ", id_database ); } public ObjectId[] getPartitionSchemaIDs( boolean includeDeleted ) throws KettleException { return connectionDelegate.getIDs( "SELECT " + quote( KettleDatabaseRepository.FIELD_PARTITION_SCHEMA_ID_PARTITION_SCHEMA ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_PARTITION_SCHEMA ) + " ORDER BY " + quote( KettleDatabaseRepository.FIELD_PARTITION_SCHEMA_NAME ) ); } public ObjectId[] getPartitionIDs( ObjectId id_partition_schema ) throws KettleException { return connectionDelegate.getIDs( "SELECT " + quote( KettleDatabaseRepository.FIELD_PARTITION_ID_PARTITION ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_PARTITION ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_PARTITION_ID_PARTITION_SCHEMA ) + " = ? ", id_partition_schema ); } public ObjectId[] getTransformationPartitionSchemaIDs( ObjectId id_transformation ) throws KettleException { return connectionDelegate.getIDs( "SELECT " + quote( KettleDatabaseRepository.FIELD_TRANS_PARTITION_SCHEMA_ID_TRANS_PARTITION_SCHEMA ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_TRANS_PARTITION_SCHEMA ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_TRANS_PARTITION_SCHEMA_ID_TRANSFORMATION ) + " = ? ", id_transformation ); } public ObjectId[] getTransformationClusterSchemaIDs( ObjectId id_transformation ) throws KettleException { return connectionDelegate.getIDs( "SELECT ID_TRANS_CLUSTER FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_TRANS_CLUSTER ) + " WHERE ID_TRANSFORMATION = ? ", id_transformation ); } public ObjectId[] getClusterIDs( boolean includeDeleted ) throws KettleException { return connectionDelegate.getIDs( "SELECT " + quote( KettleDatabaseRepository.FIELD_CLUSTER_ID_CLUSTER ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_CLUSTER ) + " ORDER BY " + quote( KettleDatabaseRepository.FIELD_CLUSTER_NAME ) ); } public ObjectId[] getSlaveIDs( boolean includeDeleted ) throws KettleException { return connectionDelegate.getIDs( "SELECT " + quote( KettleDatabaseRepository.FIELD_SLAVE_ID_SLAVE ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_SLAVE ) ); } public ObjectId[] getClusterSlaveIDs( ObjectId id_cluster_schema ) throws KettleException { return connectionDelegate.getIDs( "SELECT " + quote( KettleDatabaseRepository.FIELD_CLUSTER_SLAVE_ID_SLAVE ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_CLUSTER_SLAVE ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_CLUSTER_SLAVE_ID_CLUSTER ) + " = ? ", id_cluster_schema ); } public synchronized String[] getDatabaseNames( boolean includeDeleted ) throws KettleException { String nameField = quote( KettleDatabaseRepository.FIELD_DATABASE_NAME ); return connectionDelegate.getStrings( "SELECT " + nameField + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_DATABASE ) + " ORDER BY " + nameField ); } public synchronized String[] getPartitionSchemaNames( boolean includeDeleted ) throws KettleException { String nameField = quote( KettleDatabaseRepository.FIELD_PARTITION_SCHEMA_NAME ); return connectionDelegate.getStrings( "SELECT " + nameField + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_PARTITION_SCHEMA ) + " ORDER BY " + nameField ); } public synchronized String[] getSlaveNames( boolean includeDeleted ) throws KettleException { String nameField = quote( KettleDatabaseRepository.FIELD_SLAVE_NAME ); return connectionDelegate.getStrings( "SELECT " + nameField + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_SLAVE ) + " ORDER BY " + nameField ); } public synchronized String[] getClusterNames( boolean includeDeleted ) throws KettleException { String nameField = quote( KettleDatabaseRepository.FIELD_CLUSTER_NAME ); return connectionDelegate .getStrings( "SELECT " + nameField + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_CLUSTER ) + " ORDER BY " + nameField ); } public ObjectId[] getStepIDs( ObjectId id_transformation ) throws KettleException { return connectionDelegate.getIDs( "SELECT " + quote( KettleDatabaseRepository.FIELD_STEP_ID_STEP ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_STEP ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_STEP_ID_TRANSFORMATION ) + " = ?", id_transformation ); } public synchronized String[] getTransformationsUsingDatabase( ObjectId id_database ) throws KettleException { ObjectId[] transIds = connectionDelegate.getIDs( "SELECT DISTINCT " + quote( FIELD_STEP_DATABASE_ID_TRANSFORMATION ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_STEP_DATABASE ) + " WHERE " + quote( FIELD_STEP_DATABASE_ID_DATABASE ) + " = ?", id_database ); return transDelegate.getTransformationsWithIDList( transIds ); } public synchronized String[] getJobsUsingDatabase( ObjectId id_database ) throws KettleException { ObjectId[] jobIds = connectionDelegate.getIDs( "SELECT DISTINCT " + quote( KettleDatabaseRepository.FIELD_JOBENTRY_DATABASE_ID_JOB ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_JOBENTRY_DATABASE ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_JOBENTRY_DATABASE_ID_DATABASE ) + " = ? ", id_database ); return jobDelegate.getJobsWithIDList( jobIds ); } public synchronized String[] getClustersUsingSlave( ObjectId id_slave ) throws KettleException { return connectionDelegate.getStrings( "SELECT DISTINCT " + quote( FIELD_CLUSTER_SLAVE_ID_CLUSTER ) + " FROM " + quoteTable( TABLE_R_CLUSTER_SLAVE ) + " WHERE " + quote( FIELD_CLUSTER_SLAVE_ID_SLAVE ) + " = ?", id_slave ); } public synchronized String[] getTransformationsUsingSlave( ObjectId id_slave ) throws KettleException { ObjectId[] transIds = connectionDelegate.getIDs( "SELECT DISTINCT " + quote( FIELD_TRANS_SLAVE_ID_TRANSFORMATION ) + " FROM " + quoteTable( TABLE_R_TRANS_SLAVE ) + " WHERE " + quote( FIELD_TRANS_SLAVE_ID_SLAVE ) + " = ?", id_slave ); return transDelegate.getTransformationsWithIDList( transIds ); } public synchronized String[] getTransformationsUsingPartitionSchema( ObjectId id_partition_schema ) throws KettleException { ObjectId[] transIds = connectionDelegate.getIDs( "SELECT DISTINCT " + quote( FIELD_TRANS_PARTITION_SCHEMA_ID_TRANSFORMATION ) + " FROM " + quoteTable( TABLE_R_TRANS_PARTITION_SCHEMA ) + " WHERE " + quote( FIELD_TRANS_PARTITION_SCHEMA_ID_PARTITION_SCHEMA ) + " = ?", id_partition_schema ); return transDelegate.getTransformationsWithIDList( transIds ); } public synchronized String[] getTransformationsUsingCluster( ObjectId id_cluster ) throws KettleException { ObjectId[] transIds = connectionDelegate.getIDs( "SELECT DISTINCT " + quote( FIELD_TRANS_CLUSTER_ID_TRANSFORMATION ) + " FROM " + quoteTable( TABLE_R_TRANS_CLUSTER ) + " WHERE " + quote( FIELD_TRANS_CLUSTER_ID_CLUSTER ) + " = ?", id_cluster ); return transDelegate.getTransformationsWithIDList( transIds ); } public ObjectId[] getJobHopIDs( ObjectId id_job ) throws KettleException { return connectionDelegate.getIDs( "SELECT " + quote( KettleDatabaseRepository.FIELD_JOB_HOP_ID_JOB_HOP ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_JOB_HOP ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_JOB_HOP_ID_JOB ) + " = ?", id_job ); } public ObjectId[] getTransDependencyIDs( ObjectId id_transformation ) throws KettleException { return connectionDelegate.getIDs( "SELECT " + quote( KettleDatabaseRepository.FIELD_DEPENDENCY_ID_DEPENDENCY ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_DEPENDENCY ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_DEPENDENCY_ID_TRANSFORMATION ) + " = ?", id_transformation ); } public ObjectId[] getJobEntryIDs( ObjectId id_job ) throws KettleException { return connectionDelegate.getIDs( "SELECT " + quote( KettleDatabaseRepository.FIELD_JOBENTRY_ID_JOBENTRY ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_JOBENTRY ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_JOBENTRY_ID_JOB ) + " = ?", id_job ); } public ObjectId[] getJobEntryCopyIDs( ObjectId id_job ) throws KettleException { return connectionDelegate.getIDs( "SELECT " + quote( KettleDatabaseRepository.FIELD_JOBENTRY_COPY_ID_JOBENTRY_COPY ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_JOBENTRY_COPY ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_JOBENTRY_COPY_ID_JOB ) + " = ?", id_job ); } public ObjectId[] getJobEntryCopyIDs( ObjectId id_job, ObjectId id_jobentry ) throws KettleException { return connectionDelegate.getIDs( "SELECT " + quote( KettleDatabaseRepository.FIELD_JOBENTRY_COPY_ID_JOBENTRY_COPY ) + " FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_JOBENTRY_COPY ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_JOBENTRY_COPY_ID_JOB ) + " = ? AND " + quote( KettleDatabaseRepository.FIELD_JOBENTRY_COPY_ID_JOBENTRY ) + " = ? ", id_job, id_jobentry ); } private RowMetaAndData getStepDatabase( ObjectId id_step ) throws KettleException { return connectionDelegate.getOneRow( quoteTable( KettleDatabaseRepository.TABLE_R_STEP_DATABASE ), quote( KettleDatabaseRepository.FIELD_STEP_DATABASE_ID_STEP ), id_step ); } private RowMetaAndData getJobEntryDatabase( ObjectId id_jobentry ) throws KettleException { return connectionDelegate.getOneRow( quoteTable( KettleDatabaseRepository.TABLE_R_JOBENTRY_DATABASE ), quote( KettleDatabaseRepository.FIELD_JOBENTRY_DATABASE_ID_JOBENTRY ), id_jobentry ); } // STEP ATTRIBUTES: SAVE /** * GZips and then base64 encodes an array of bytes to a String * * @param val * the array of bytes to convert to a string * @return the base64 encoded string * @throws IOException * in the case there is a Base64 or GZip encoding problem */ public static final String byteArrayToString( byte[] val ) throws IOException { String string; if ( val == null ) { string = null; } else { ByteArrayOutputStream baos = new ByteArrayOutputStream(); GZIPOutputStream gzos = new GZIPOutputStream( baos ); BufferedOutputStream bos = new BufferedOutputStream( gzos ); bos.write( val ); bos.flush(); bos.close(); string = new String( Base64.encodeBase64( baos.toByteArray() ) ); } return string; } // STEP ATTRIBUTES: GET // //////////////////////////////////////////////////////////////////////////////////////// // DELETE DATA IN REPOSITORY // //////////////////////////////////////////////////////////////////////////////////////// public synchronized void delSteps( ObjectId id_transformation ) throws KettleException { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_STEP ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_STEP_ID_TRANSFORMATION ) + " = ? ", id_transformation ); } public synchronized void deleteCondition( ObjectId id_condition ) throws KettleException { boolean ok = true; ObjectId[] ids = getSubConditionIDs( id_condition ); if ( ids.length > 0 ) { // Delete the sub-conditions... for ( int i = 0; i < ids.length && ok; i++ ) { deleteCondition( ids[i] ); } // Then delete the main condition deleteCondition( id_condition ); } else { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_CONDITION ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_CONDITION_ID_CONDITION ) + " = ? ", id_condition ); } } public synchronized void delStepConditions( ObjectId id_transformation ) throws KettleException { ObjectId[] ids = getTransformationConditionIDs( id_transformation ); for ( int i = 0; i < ids.length; i++ ) { deleteCondition( ids[i] ); } connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_TRANS_STEP_CONDITION ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_TRANS_STEP_CONDITION_ID_TRANSFORMATION ) + " = ? ", id_transformation ); } /** * Delete the relationships between the transformation/steps and the databases. * * @param id_transformation * the transformation for which we want to delete the databases. * @throws KettleException * in case something unexpected happens. */ public synchronized void delStepDatabases( ObjectId id_transformation ) throws KettleException { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_STEP_DATABASE ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_STEP_DATABASE_ID_TRANSFORMATION ) + " = ? ", id_transformation ); } /** * Delete the relationships between the job/job entries and the databases. * * @param id_job * the job for which we want to delete the databases. * @throws KettleDatabaseException * in case something unexpected happens. */ public synchronized void delJobEntryDatabases( ObjectId id_job ) throws KettleException { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_JOBENTRY_DATABASE ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_JOBENTRY_DATABASE_ID_JOB ) + " = ? ", id_job ); } public synchronized void delJobEntries( ObjectId id_job ) throws KettleException { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_JOBENTRY ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_JOBENTRY_ID_JOB ) + " = ? ", id_job ); } public synchronized void delJobEntryCopies( ObjectId id_job ) throws KettleException { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_JOBENTRY_COPY ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_JOBENTRY_COPY_ID_JOB ) + " = ? ", id_job ); } public synchronized void delDependencies( ObjectId id_transformation ) throws KettleException { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_DEPENDENCY ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_DEPENDENCY_ID_TRANSFORMATION ) + " = ? ", id_transformation ); } public synchronized void delStepAttributes( ObjectId id_transformation ) throws KettleException { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_STEP_ATTRIBUTE ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_STEP_ATTRIBUTE_ID_TRANSFORMATION ) + " = ? ", id_transformation ); } public synchronized void delTransAttributes( ObjectId id_transformation ) throws KettleException { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_TRANS_ATTRIBUTE ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_TRANS_ATTRIBUTE_ID_TRANSFORMATION ) + " = ? ", id_transformation ); } public synchronized void delJobAttributes( ObjectId id_job ) throws KettleException { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_JOB_ATTRIBUTE ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_JOB_ATTRIBUTE_ID_JOB ) + " = ? ", id_job ); } public synchronized void delPartitionSchemas( ObjectId id_transformation ) throws KettleException { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_TRANS_PARTITION_SCHEMA ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_TRANS_PARTITION_SCHEMA_ID_TRANSFORMATION ) + " = ? ", id_transformation ); } public synchronized void delPartitions( ObjectId id_partition_schema ) throws KettleException { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_PARTITION ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_PARTITION_ID_PARTITION_SCHEMA ) + " = ? ", id_partition_schema ); } public synchronized void delClusterSlaves( ObjectId id_cluster ) throws KettleException { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_CLUSTER_SLAVE ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_CLUSTER_SLAVE_ID_CLUSTER ) + " = ? ", id_cluster ); } public synchronized void delTransformationClusters( ObjectId id_transformation ) throws KettleException { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_TRANS_CLUSTER ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_TRANS_CLUSTER_ID_TRANSFORMATION ) + " = ? ", id_transformation ); } public synchronized void delTransformationSlaves( ObjectId id_transformation ) throws KettleException { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_TRANS_SLAVE ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_TRANS_SLAVE_ID_TRANSFORMATION ) + " = ? ", id_transformation ); } public synchronized void delJobEntryAttributes( ObjectId id_job ) throws KettleException { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_JOBENTRY_ATTRIBUTE ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_JOBENTRY_ATTRIBUTE_ID_JOB ) + " = ? ", id_job ); } public synchronized void delTransHops( ObjectId id_transformation ) throws KettleException { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_TRANS_HOP ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_TRANS_HOP_ID_TRANSFORMATION ) + " = ? ", id_transformation ); } public synchronized void delJobHops( ObjectId id_job ) throws KettleException { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_JOB_HOP ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_JOB_HOP_ID_JOB ) + " = ? ", id_job ); } public synchronized void delTransNotes( ObjectId id_transformation ) throws KettleException { ObjectId[] ids = getTransNoteIDs( id_transformation ); for ( int i = 0; i < ids.length; i++ ) { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_NOTE ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_NOTE_ID_NOTE ) + " = ? ", ids[i] ); } connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_TRANS_NOTE ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_TRANS_NOTE_ID_TRANSFORMATION ) + " = ? ", id_transformation ); } public synchronized void delJobNotes( ObjectId id_job ) throws KettleException { ObjectId[] ids = getJobNoteIDs( id_job ); for ( int i = 0; i < ids.length; i++ ) { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_NOTE ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_NOTE_ID_NOTE ) + " = ? ", ids[i] ); } connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_JOB_NOTE ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_JOB_NOTE_ID_JOB ) + " = ? ", id_job ); } public synchronized void delTrans( ObjectId id_transformation ) throws KettleException { securityProvider.validateAction( RepositoryOperation.DELETE_TRANSFORMATION ); connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_TRANSFORMATION ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_TRANSFORMATION_ID_TRANSFORMATION ) + " = ? ", id_transformation ); } public synchronized void delJob( ObjectId id_job ) throws KettleException { securityProvider.validateAction( RepositoryOperation.DELETE_TRANSFORMATION ); connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_JOB ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_JOB_ID_JOB ) + " = ? ", id_job ); } public synchronized void delTransStepCondition( ObjectId id_transformation ) throws KettleException { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_TRANS_STEP_CONDITION ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_TRANS_STEP_CONDITION_ID_TRANSFORMATION ) + " = ? ", id_transformation ); } public synchronized void delValue( ObjectId id_value ) throws KettleException { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_VALUE ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_VALUE_ID_VALUE ) + " = ? ", id_value ); } public synchronized void deleteSlave( ObjectId id_slave ) throws KettleException { securityProvider.validateAction( RepositoryOperation.DELETE_SLAVE_SERVER ); // First, see if the slave is still used by other objects... // If so, generate an error!! // We look in table R_TRANS_SLAVE to see if there are any transformations // using this slave. // We obviously also look in table R_CLUSTER_SLAVE to see if there are any // clusters that use this slave. // String[] transList = getTransformationsUsingSlave( id_slave ); String[] clustList = getClustersUsingSlave( id_slave ); if ( transList.length == 0 && clustList.length == 0 ) { connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_SLAVE ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_SLAVE_ID_SLAVE ) + " = ? ", id_slave ); connectionDelegate.performDelete( "DELETE FROM " + quoteTable( KettleDatabaseRepository.TABLE_R_TRANS_SLAVE ) + " WHERE " + quote( KettleDatabaseRepository.FIELD_TRANS_SLAVE_ID_SLAVE ) + " = ? ", id_slave ); commit(); } else { StringBuilder message = new StringBuilder( 100 ); if ( transList.length > 0 ) { message.append( "Slave used by the following transformations:" ).append( Const.CR ); for ( int i = 0; i < transList.length; i++ ) { message.append( " " ).append( transList[i] ).append( Const.CR ); } message.append( Const.CR ); } if ( clustList.length > 0 ) { message.append( "Slave used by the following cluster schemas:" ).append( Const.CR ); for ( int i = 0; i < clustList.length; i++ ) { message.append( " " ).append( clustList[i] ).append( Const.CR ); } } KettleDependencyException e = new KettleDependencyException( message.toString() ); throw new KettleDependencyException( "This slave server is still in use by one or more transformations (" + transList.length + ") or cluster schemas (" + clustList.length + ") :", e ); } } public synchronized void deletePartitionSchema( ObjectId id_partition_schema ) throws KettleException { partitionSchemaDelegate.delPartitionSchema( id_partition_schema ); commit(); } public synchronized void deleteClusterSchema( ObjectId id_cluster ) throws KettleException { clusterSchemaDelegate.delClusterSchema( id_cluster ); commit(); } public synchronized void deleteTransformation( ObjectId id_transformation ) throws KettleException { delTransNotes( id_transformation ); delStepAttributes( id_transformation ); delSteps( id_transformation ); delStepConditions( id_transformation ); delStepDatabases( id_transformation ); delTransHops( id_transformation ); delDependencies( id_transformation ); delTransAttributes( id_transformation ); delPartitionSchemas( id_transformation ); delTransformationClusters( id_transformation ); delTransformationSlaves( id_transformation ); delTrans( id_transformation ); commit(); } public synchronized void deleteJob( ObjectId id_job ) throws KettleException { // logBasic("Deleting info in repository on ID_JOB: "+id_job); delJobNotes( id_job ); delJobAttributes( id_job ); delJobEntryAttributes( id_job ); delJobEntryDatabases( id_job ); delJobEntries( id_job ); delJobEntryCopies( id_job ); delJobHops( id_job ); delJob( id_job ); commit(); // logBasic("All deleted on job with ID_JOB: "+id_job); } public boolean dropRepositorySchema() throws KettleException { // Make sure we close shop before dropping everything. // Some DB's can't handle the drop otherwise. // connectionDelegate.closeStepAttributeInsertPreparedStatement(); connectionDelegate.closeLookupJobEntryAttribute(); for ( int i = 0; i < repositoryTableNames.length; i++ ) { try { execStatement( "DROP TABLE " + quoteTable( repositoryTableNames[i] ) ); if ( log.isDetailed() ) { log.logDetailed( "dropped table " + repositoryTableNames[i] ); } } catch ( KettleException dbe ) { if ( log.isDetailed() ) { log.logDetailed( "Unable to drop table: " + repositoryTableNames[i] ); } } } log.logBasic( "Dropped all " + repositoryTableNames.length + " repository tables." ); // perform commit, for some DB's drop is not auto commit. commit(); return true; } /** * Update the list in R_STEP_TYPE using the StepLoader StepPlugin entries * * @return the SQL statements executed * @throws KettleException * if the update didn't go as planned. */ public void updateStepTypes() throws KettleException { creationHelper.updateStepTypes( new ArrayList<String>(), false, false ); } /** * Update the list in R_DATABASE_TYPE using the plugin registry * * @return the SQL statements executed * @throws KettleException * if the update didn't go as planned. */ public void updateDatabaseTypes() throws KettleException { creationHelper.updateDatabaseTypes( new ArrayList<String>(), false, false ); } /** * Update the list in R_JOBENTRY_TYPE * * @exception KettleException * if something went wrong during the update. */ public void updateJobEntryTypes() throws KettleException { creationHelper.updateJobEntryTypes( new ArrayList<String>(), false, false ); } public synchronized String toString() { if ( repositoryMeta == null ) { return getClass().getName(); } return repositoryMeta.getName(); } /** * Clear the shared object cache, if applicable. */ public void clearSharedObjectCache() { // no op } /** * @return Returns the database. */ public Database getDatabase() { return connectionDelegate.getDatabase(); } /** * @param database * The database to set. */ public void setDatabase( Database database ) { connectionDelegate.setDatabase( database ); connectionDelegate.setDatabaseMeta( database.getDatabaseMeta() ); } public synchronized void lockRepository() throws KettleException { connectionDelegate.lockRepository(); } public synchronized void unlockRepository() throws KettleException { connectionDelegate.unlockRepository(); } /** * @return a list of all the databases in the repository. * @throws KettleException */ public List<DatabaseMeta> getDatabases() throws KettleException { List<DatabaseMeta> list = new ArrayList<>(); ObjectId[] databaseIDs = getDatabaseIDs( false ); for ( int i = 0; i < databaseIDs.length; i++ ) { DatabaseMeta databaseMeta = loadDatabaseMeta( databaseIDs[i], null ); // reads // last // version list.add( databaseMeta ); } return list; } /** * @return a list of all the slave servers in the repository. * @throws KettleException */ public List<SlaveServer> getSlaveServers() throws KettleException { List<SlaveServer> list = new ArrayList<>(); ObjectId[] slaveIDs = getSlaveIDs( false ); for ( int i = 0; i < slaveIDs.length; i++ ) { SlaveServer slaveServer = loadSlaveServer( slaveIDs[i], null ); // Load last // version list.add( slaveServer ); } return list; } /** * @return the databaseMeta */ public DatabaseMeta getDatabaseMeta() { return connectionDelegate.getDatabaseMeta(); } /** * Read all the databases defined in the repository * * @return a list of all the databases defined in the repository * @throws KettleException */ public List<DatabaseMeta> readDatabases() throws KettleException { List<DatabaseMeta> databases = new ArrayList<>(); ObjectId[] ids = getDatabaseIDs( false ); for ( int i = 0; i < ids.length; i++ ) { DatabaseMeta databaseMeta = loadDatabaseMeta( ids[i], null ); // reads last // versions databases.add( databaseMeta ); } return databases; } /** * @return the useBatchProcessing */ public boolean isUseBatchProcessing() { return connectionDelegate.isUseBatchProcessing(); } /** * Set this directory during import to signal that job entries like Trans and Job need to point to job entries * relative to this directory. * * @param importBaseDirectory * the base import directory, selected by the user */ public void setImportBaseDirectory( RepositoryDirectory importBaseDirectory ) { this.importBaseDirectory = importBaseDirectory; } /** * The directory set during import to signal that job entries like Trans and Job need to point to job entries relative * to this directory * * @return the base import directory, selected by the user */ public RepositoryDirectory getImportBaseDirectory() { return importBaseDirectory; } /** * Create or upgrade repository tables & fields, populate lookup tables, ... * * @param monitor * The progress monitor to use, or null if no monitor is present. * @param upgrade * True if you want to upgrade the repository, false if you want to create it. * @param statements * the list of statements to populate * @param dryrun * true if we don't actually execute the statements * * @throws KettleException * in case something goes wrong! */ public void createRepositorySchema( ProgressMonitorListener monitor, boolean upgrade, List<String> statements, boolean dryRun ) throws KettleException { creationHelper.createRepositorySchema( monitor, upgrade, statements, dryRun ); } // REQUIRED INTERFACE METHODS... // public synchronized int countNrStepAttributes( ObjectId id_step, String code ) throws KettleException { return connectionDelegate.countNrStepAttributes( id_step, code ); } public synchronized int countNrJobEntryAttributes( ObjectId id_jobentry, String code ) throws KettleException { return connectionDelegate.countNrJobEntryAttributes( id_jobentry, code ); } public synchronized void disconnect() { metaStore = null; connectionDelegate.disconnect(); } // Job Entry attributes... // get public long getJobEntryAttributeInteger( ObjectId id_jobentry, int nr, String code ) throws KettleException { return connectionDelegate.getJobEntryAttributeInteger( id_jobentry, nr, code ); } public String getJobEntryAttributeString( ObjectId id_jobentry, int nr, String code ) throws KettleException { return connectionDelegate.getJobEntryAttributeString( id_jobentry, nr, code ); } @Override public boolean getJobEntryAttributeBoolean( ObjectId id_jobentry, int nr, String code, boolean def ) throws KettleException { return connectionDelegate.getJobEntryAttributeBoolean( id_jobentry, nr, code, def ); } // put public void saveJobEntryAttribute( ObjectId id_job, ObjectId id_jobentry, int nr, String code, String value ) throws KettleException { connectionDelegate.saveJobEntryAttribute( id_job, id_jobentry, nr, code, value ); } public void saveJobEntryAttribute( ObjectId id_job, ObjectId id_jobentry, int nr, String code, boolean value ) throws KettleException { connectionDelegate.saveJobEntryAttribute( id_job, id_jobentry, nr, code, value ); } public void saveJobEntryAttribute( ObjectId id_job, ObjectId id_jobentry, int nr, String code, long value ) throws KettleException { connectionDelegate.saveJobEntryAttribute( id_job, id_jobentry, nr, code, value ); } // Step attributes // get public boolean getStepAttributeBoolean( ObjectId id_step, int nr, String code, boolean def ) throws KettleException { return connectionDelegate.getStepAttributeBoolean( id_step, nr, code, def ); } public long getStepAttributeInteger( ObjectId id_step, int nr, String code ) throws KettleException { return connectionDelegate.getStepAttributeInteger( id_step, nr, code ); } public String getStepAttributeString( ObjectId id_step, int nr, String code ) throws KettleException { return connectionDelegate.getStepAttributeString( id_step, nr, code ); } // put public void saveStepAttribute( ObjectId id_transformation, ObjectId id_step, int nr, String code, String value ) throws KettleException { connectionDelegate.saveStepAttribute( id_transformation, id_step, nr, code, value ); } public void saveStepAttribute( ObjectId id_transformation, ObjectId id_step, int nr, String code, boolean value ) throws KettleException { connectionDelegate.saveStepAttribute( id_transformation, id_step, nr, code, value ); } public void saveStepAttribute( ObjectId id_transformation, ObjectId id_step, int nr, String code, long value ) throws KettleException { connectionDelegate.saveStepAttribute( id_transformation, id_step, nr, code, value ); } public void saveStepAttribute( ObjectId id_transformation, ObjectId id_step, int nr, String code, double value ) throws KettleException { connectionDelegate.saveStepAttribute( id_transformation, id_step, nr, code, value ); } /** * This method is only used to check backward compatibility with the 2.x series. * * @param id_step * @param nr * @param code * @return * @throws KettleException */ public ObjectId findStepAttributeID( ObjectId id_step, int nr, String code ) throws KettleException { return connectionDelegate.findStepAttributeID( id_step, nr, code ); } public void execStatement( String sql ) throws KettleException { connectionDelegate.getDatabase().execStatement( sql ); } public void loadJobEntry( JobEntryBase jobEntryBase, ObjectId id_jobentry, List<DatabaseMeta> databases, List<SlaveServer> slaveServers ) throws KettleException { jobEntryDelegate.loadJobEntryBase( jobEntryBase, id_jobentry, databases, slaveServers ); } public ObjectId getClusterID( String name ) throws KettleException { return clusterSchemaDelegate.getClusterID( name ); } public ObjectId getDatabaseID( String name ) throws KettleException { ObjectId exactMatch = databaseDelegate.getDatabaseID( name ); if ( exactMatch == null ) { // look for a database DatabaseMeta database = DatabaseMeta.findDatabase( getDatabases(), name ); return ( database == null ) ? null : database.getObjectId(); } else { return exactMatch; } } public ObjectId getJobId( String name, RepositoryDirectoryInterface repositoryDirectory ) throws KettleException { return jobDelegate.getJobID( name, repositoryDirectory.getObjectId() ); } public ObjectId getPartitionSchemaID( String name ) throws KettleException { return partitionSchemaDelegate.getPartitionSchemaID( name ); } public ObjectId getSlaveID( String name ) throws KettleException { return slaveServerDelegate.getSlaveID( name ); } public ObjectId getTransformationID( String name, RepositoryDirectoryInterface repositoryDirectory ) throws KettleException { return transDelegate.getTransformationID( name, repositoryDirectory.getObjectId() ); } public ObjectId insertJobEntry( ObjectId id_job, JobEntryBase jobEntryBase ) throws KettleException { return jobEntryDelegate.insertJobEntry( id_job, jobEntryBase ); } public DatabaseMeta loadDatabaseMetaFromStepAttribute( ObjectId idStep, String code, List<DatabaseMeta> databases ) throws KettleException { long id_database = getStepAttributeInteger( idStep, code ); if ( id_database <= 0 ) { return null; } return DatabaseMeta.findDatabase( databases, new LongObjectId( id_database ) ); } /** * This method saves the object ID of the database object (if not null) in the step attributes * * @param id_transformation * @param id_step * @param string * @param database */ public void saveDatabaseMetaStepAttribute( ObjectId id_transformation, ObjectId id_step, String code, DatabaseMeta database ) throws KettleException { ObjectId id = null; if ( database != null ) { id = database.getObjectId(); Long id_database = id == null ? Long.valueOf( -1L ) : new LongObjectId( id ).longValue(); saveStepAttribute( id_transformation, id_step, code, id_database ); } } public DatabaseMeta loadDatabaseMetaFromJobEntryAttribute( ObjectId id_jobentry, String nameCode, int nr, String idCode, List<DatabaseMeta> databases ) throws KettleException { long id_database = getJobEntryAttributeInteger( id_jobentry, nr, idCode ); if ( id_database <= 0 ) { String name = getJobEntryAttributeString( id_jobentry, nr, nameCode ); if ( name == null ) { return null; } return DatabaseMeta.findDatabase( databases, name ); } return DatabaseMeta.findDatabase( databases, new LongObjectId( id_database ) ); } /** * This method saves the object ID of the database object (if not null) in the step attributes * * @param id_job * @param nr * @param id_jobentry * @param nameCode * @param nameCode * @param idCode * @param database */ public void saveDatabaseMetaJobEntryAttribute( ObjectId id_job, ObjectId id_jobentry, int nr, String nameCode, String idCode, DatabaseMeta database ) throws KettleException { ObjectId id = null; if ( database != null ) { id = database.getObjectId(); Long id_database = id == null ? Long.valueOf( -1L ) : new LongObjectId( id ).longValue(); // Save both the ID and the name of the database connection... // saveJobEntryAttribute( id_job, id_jobentry, nr, idCode, id_database ); saveJobEntryAttribute( id_job, id_jobentry, nr, nameCode, id_database ); insertJobEntryDatabase( id_job, id_jobentry, id ); } } /** * Load a condition from the repository with the Object ID stored in a step attribute. * * @param id_step * @param code * @return * @throws KettleException */ public Condition loadConditionFromStepAttribute( ObjectId id_step, String code ) throws KettleException { long id_condition = getStepAttributeInteger( id_step, code ); if ( id_condition > 0 ) { return loadCondition( new LongObjectId( id_condition ) ); // this repository // uses longs } else { return null; } } /** * This method saves the object ID of the condition object (if not null) in the step attributes * * @param id_step * @param code * @param condition */ public void saveConditionStepAttribute( ObjectId id_transformation, ObjectId id_step, String code, Condition condition ) throws KettleException { ObjectId id = null; if ( condition != null ) { id = saveCondition( condition ); Long id_condition = id == null ? Long.valueOf( -1L ) : new LongObjectId( id ).longValue(); saveStepAttribute( id_transformation, id_step, code, id_condition ); insertTransStepCondition( id_transformation, id_step, condition.getObjectId() ); } } /** * @return the securityProvider */ public KettleDatabaseRepositorySecurityProvider getSecurityProvider() { return securityProvider; } public KettleDatabaseRepositorySecurityProvider getSecurityManager() { return securityProvider; } public void undeleteObject( RepositoryElementMetaInterface element ) throws KettleException { throw new UnsupportedOperationException(); } public List<RepositoryElementMetaInterface> getJobAndTransformationObjects( ObjectId id_directory, boolean includeDeleted ) throws KettleException { // TODO not the most efficient impl; also, no sorting is done List<RepositoryElementMetaInterface> objs = new ArrayList<>(); objs.addAll( getJobObjects( id_directory, includeDeleted ) ); objs.addAll( getTransformationObjects( id_directory, includeDeleted ) ); return objs; } public IRepositoryService getService( Class<? extends IRepositoryService> clazz ) throws KettleException { return serviceMap.get( clazz ); } public List<Class<? extends IRepositoryService>> getServiceInterfaces() throws KettleException { return serviceList; } public boolean hasService( Class<? extends IRepositoryService> clazz ) throws KettleException { return serviceMap.containsKey( clazz ); } public RepositoryDirectory getDefaultSaveDirectory( RepositoryElementInterface repositoryElement ) throws KettleException { return getUserHomeDirectory(); } public RepositoryDirectory getUserHomeDirectory() throws KettleException { RepositoryDirectory root = new RepositoryDirectory(); root.setObjectId( new LongObjectId( 0L ) ); directoryDelegate.loadRepositoryDirectory( root, root.getObjectId() ); return root; } public RepositoryObject getObjectInformation( ObjectId objectId, RepositoryObjectType objectType ) throws KettleException { try { String name, description, modifiedUser; Date modifiedDate; RepositoryDirectoryInterface directory; long dirId; switch ( objectType ) { case TRANSFORMATION: { RowMetaAndData row = transDelegate.getTransformation( objectId ); name = row.getString( KettleDatabaseRepository.FIELD_TRANSFORMATION_NAME, null ); description = row.getString( KettleDatabaseRepository.FIELD_TRANSFORMATION_DESCRIPTION, null ); modifiedUser = row.getString( KettleDatabaseRepository.FIELD_TRANSFORMATION_MODIFIED_USER, "-" ); modifiedDate = row.getDate( KettleDatabaseRepository.FIELD_TRANSFORMATION_MODIFIED_DATE, null ); dirId = row.getInteger( KettleDatabaseRepository.FIELD_TRANSFORMATION_ID_DIRECTORY, 0 ); break; } case JOB: { RowMetaAndData row = jobDelegate.getJob( objectId ); name = row.getString( KettleDatabaseRepository.FIELD_JOB_NAME, null ); description = row.getString( KettleDatabaseRepository.FIELD_JOB_DESCRIPTION, null ); modifiedUser = row.getString( KettleDatabaseRepository.FIELD_JOB_MODIFIED_USER, "-" ); modifiedDate = row.getDate( KettleDatabaseRepository.FIELD_JOB_MODIFIED_DATE, null ); dirId = row.getInteger( KettleDatabaseRepository.FIELD_JOB_ID_DIRECTORY, 0 ); break; } //PDI-15871 Return available information for DATABASE case DATABASE: { RowMetaAndData row = databaseDelegate.getDatabase( objectId ); name = row.getString( KettleDatabaseRepository.FIELD_DATABASE_NAME, null ); return new RepositoryObject( objectId, name, null, null, null, objectType, null, false ); } default: throw new KettleException( "Object type " + objectType.getTypeDescription() + " was specified. Only information from transformations, jobs and databases can be retrieved at this time." ); // Nothing matches, return null } boolean isDeleted = ( name == null ); directory = loadRepositoryDirectoryTree().findDirectory( new LongObjectId( dirId ) ); return new RepositoryObject( objectId, name, directory, modifiedUser, modifiedDate, objectType, description, isDeleted ); } catch ( Exception e ) { throw new KettleException( "Unable to get object information for object with id=" + objectId, e ); } } public JobMeta loadJob( ObjectId idJob, String versionLabel ) throws KettleException { RepositoryObject jobInfo = getObjectInformation( idJob, RepositoryObjectType.JOB ); return loadJob( jobInfo.getName(), jobInfo.getRepositoryDirectory(), null, versionLabel ); } public TransMeta loadTransformation( ObjectId idTransformation, String versionLabel ) throws KettleException { RepositoryObject jobInfo = getObjectInformation( idTransformation, RepositoryObjectType.TRANSFORMATION ); return loadTransformation( jobInfo.getName(), jobInfo.getRepositoryDirectory(), null, true, versionLabel ); } public String getConnectMessage() { return null; } public IRepositoryExporter getExporter() { return new RepositoryExporter( this ); } public IRepositoryImporter getImporter() { return new RepositoryImporter( this ); } public KettleDatabaseRepositoryMetaStore getMetaStore() { return metaStore; } }