| /* |
| * Copyright (c) 1998, 2021 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 |
| package org.eclipse.persistence.testing.tests.returning; |
| |
| import java.util.*; |
| |
| import org.eclipse.persistence.descriptors.ClassDescriptor; |
| import org.eclipse.persistence.tools.schemaframework.SchemaManager; |
| import org.eclipse.persistence.sessions.*; |
| import org.eclipse.persistence.sessions.Project; |
| import org.eclipse.persistence.platform.database.DatabasePlatform; |
| import org.eclipse.persistence.internal.sequencing.Sequencing; |
| import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl; |
| import org.eclipse.persistence.testing.framework.*; |
| |
| /** |
| * This adapter is meant to generate INSERT and UPDATE |
| * procedures that return values, but currently only generates |
| * procedures that just perform the INSERT/UPDATE, so is not currently used. |
| * It will hopefully be finished at some point... |
| */ |
| public class InsertUpdateStoredProcedureAdapter implements ProjectAndDatabaseAdapter { |
| |
| StoredProcedureGeneratorForAdapter generator; |
| |
| @Override |
| public boolean isOriginalSetupRequired() { |
| return true; |
| } |
| |
| @Override |
| public void updateProject(Project project, Session session) { |
| verifySession(session); |
| if (generator == null) { |
| generator = new StoredProcedureGeneratorForAdapter(new SchemaManager((DatabaseSession)session)); |
| generator.setUseTableNames(true); |
| } |
| removeOptimisticLocking(project); |
| ((DatabaseSession)session).addDescriptors(project); |
| generator.generateStoredProceduresDefinitionsForProject(project); |
| generator.amendDescriptors(); |
| } |
| |
| @Override |
| public void updateDatabase(Session session) { |
| try { |
| generator.writeStoredProcedures(); |
| } finally { |
| clear(); |
| } |
| } |
| |
| protected void clear() { |
| generator = null; |
| } |
| |
| // StoredProcedureGenerator currently can't handle optimistic locking |
| |
| protected int removeOptimisticLocking(Project project) { |
| int removed = 0; |
| Iterator<ClassDescriptor> descriptors = project.getDescriptors().values().iterator(); |
| while (descriptors.hasNext()) { |
| ClassDescriptor desc = descriptors.next(); |
| if (desc.getOptimisticLockingPolicy() != null) { |
| desc.setOptimisticLockingPolicy(null); |
| removed++; |
| } |
| } |
| return removed; |
| } |
| |
| protected void verifySession(Session session) { |
| DatabasePlatform platform = session.getPlatform(); |
| if (((DatabaseSessionImpl)session).getSequencing() != null) { |
| if (((DatabaseSessionImpl)session).getSequencing().whenShouldAcquireValueForAll() != Sequencing.BEFORE_INSERT) { |
| // On Sybase, Infomix, SQLServer native sequencing is provided by calling @@IDENTITY after insert |
| // Apparently if INSERT has occurred inside stored procedure, SELECT @@IDENTITY returns 0. |
| throw new TestWarningException("InsertUpdateStoredProcedureAdapter can't handle native sequencing on this platform. Use table sequencing instead"); |
| } |
| } |
| if ((platform.isSybase() || platform.isSQLAnywhere()) && platform.supportsAutoCommit()) { |
| // stored procedures won't work unless |
| // the flag set to false (at least with JConnect). |
| // see DatabaseLogin.handleTransactionsManuallyForSybaseJConnect() |
| throw new TestWarningException("Sybase requires supportAutoCommit()==false"); |
| } |
| } |
| |
| } |