blob: 874fb097d0a7a8f23d9a8b5c158fff833cbcda05 [file] [log] [blame]
/*
* Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
// 07/25/2008-1.0 Michael OBrien
// - 242120: Let the DB exception in alterOnDatabase() propagate so as not to
// cause an infinite loop when ddl generation updates fail on a JTA DS
// 09/14/2011-2.3.1 Guy Pelletier
// - 357533: Allow DDL queries to execute even when Multitenant entities are part of the PU
package org.eclipse.persistence.tools.schemaframework;
import java.io.*;
import org.eclipse.persistence.queries.SQLCall;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.sequencing.Sequence;
import org.eclipse.persistence.internal.sessions.AbstractSession;
/**
* <p>
* <b>Purpose</b>: Sequence definition Native Sequence object.
* </p>
*/
public class SequenceObjectDefinition extends SequenceDefinition {
/**
* INTERNAL:
* Should be a sequence defining sequence object in the db:
* either NativeSequence with shouldAcquireValueAfterInsert() returning false;
* or DefaultSequence (only if case platform.getDefaultSequence() is a
* NativeSequence with shouldAcquireValueAfterInsert() returning false).
*/
public SequenceObjectDefinition(Sequence sequence) {
super(sequence);
}
/**
* INTERNAL:
* Return the SQL required to create the Oracle sequence object.
*/
@Override
public Writer buildCreationWriter(AbstractSession session, Writer writer) {
try {
// startWith value calculated using the initial value and increment.
// The first time TopLink calls select nextval, the value equal to startWith is returned.
// The first sequence value EclipseLink may assign is startWith - getIncrement() + 1.
int startWith = sequence.getInitialValue() + sequence.getPreallocationSize() - 1;
session.getPlatform().buildSequenceObjectCreationWriter(writer, getFullName(), sequence.getPreallocationSize(), startWith);
} catch (IOException ioException) {
throw ValidationException.fileError(ioException);
}
return writer;
}
/**
* INTERNAL:
* Return the SQL required to drop the Oracle sequence object.
*/
@Override
public Writer buildDeletionWriter(AbstractSession session, Writer writer) {
try {
session.getPlatform().buildSequenceObjectDeletionWriter(writer, getFullName());
} catch (IOException ioException) {
throw ValidationException.fileError(ioException);
}
return writer;
}
/**
* INTERNAL:
* Return the SQL required to alter INCREMENT BY
*/
public Writer buildAlterIncrementWriter(AbstractSession session, Writer writer) {
try {
session.getPlatform().buildSequenceObjectAlterIncrementWriter(writer, getFullName(), sequence.getPreallocationSize());
} catch (IOException ioException) {
throw ValidationException.fileError(ioException);
}
return writer;
}
/**
* INTERNAL:
* Check if the sequence object already exists, in which case dont create it.
*/
@Override
public boolean checkIfExist(AbstractSession session) throws DatabaseException {
boolean isConnected = sequence.isConnected();
// temporary connect sequence if it's not connected.
if(!isConnected) {
sequence.onConnect(session.getPlatform());
}
try {
if(sequence.shouldUsePreallocation()) {
sequence.getGeneratedVector(null, session);
} else {
sequence.getGeneratedValue(null, session);
}
return true;
} catch (DatabaseException databaseException) {
return false;
} catch (ValidationException validationException) {
// This exception indicates that the current preallocationSize
// is greater than the returned value.
// It should be ignored because sequence actually exists in the db.
if(validationException.getErrorCode() == ValidationException.SEQUENCE_SETUP_INCORRECTLY) {
return true;
} else {
throw validationException;
}
} finally {
if(!isConnected) {
sequence.onDisconnect(session.getPlatform());
}
}
}
/**
* INTERNAL:
* Indicates whether alterIncrement is supported
*/
@Override
public boolean isAlterSupported(AbstractSession session) {
return session.getPlatform().isAlterSequenceObjectSupported();
}
/**
* INTERNAL:
* Execute the SQL required to alter sequence increment.
* Assume that the sequence exists.
*/
@Override
public void alterOnDatabase(AbstractSession session) throws EclipseLinkException {
// Bug# 242120: Let the DatabaseException propagate and do not call
// createOnDatabase(session) which would cause an infinite loop on a JTA connection
session.priviledgedExecuteNonSelectingCall(new SQLCall(buildAlterIncrementWriter(session, new StringWriter()).toString()));
}
/**
* INTERNAL:
* Execute the SQL required to alter sequence increment.
* Assume that the sequence exists.
*/
public void alterIncrement(AbstractSession session, Writer schemaWriter) throws ValidationException {
if (schemaWriter == null) {
this.alterOnDatabase(session);
} else {
this.buildAlterIncrementWriter(session, schemaWriter);
}
}
/**
* INTERNAL:
* Most major databases support a creator name scope.
* This means whenever the database object is referenced, it must be qualified.
*/
@Override
public String getFullName() {
return sequence.getQualified(getName());
}
}