view src/main/java/org/monetdb/jdbc/MonetSavepoint.java @ 931:df18aa5c8a61

Add test for MonetDriver.getPropertyInfo(url, props). The implementation is moved to Parameter.java which contains the list of connection parameters. It currently only returns the mandatory connection parameters.
author Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
date Thu, 24 Oct 2024 19:10:06 +0200 (6 months ago)
parents e890195256ac
children d416e9b6b3d0
line wrap: on
line source
/*
 * SPDX-License-Identifier: MPL-2.0
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0.  If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Copyright 2024 MonetDB Foundation;
 * Copyright August 2008 - 2023 MonetDB B.V.;
 * Copyright 1997 - July 2008 CWI.
 */

package org.monetdb.jdbc;

import java.sql.Savepoint;
import java.sql.SQLException;
import java.util.concurrent.atomic.AtomicInteger;

/**
 *<pre>
 * A {@link Savepoint} suitable for the MonetDB database.
 *
 * The representation of a savepoint, which is a point within the current
 * transaction that can be referenced from the Connection.rollback() method.
 * When a transaction is rolled back to a savepoint all changes made after
 * that savepoint are undone.
 * Savepoints can be either named or unnamed. Unnamed savepoints are
 * identified by an ID generated by the underlying data source.
 *
 * This little class is nothing more than a container for a name and/or
 * an id. Each instance of this class always has an id, which is used for
 * internal representation of the save point.
 *
 * Because the IDs which get generated are a logical sequence, application
 * wide, two concurrent transactions are guaranteed to not have the same
 * save point identifiers. In this implementation the validity of save points
 * is determined by the server, which makes this a light implementation.
 *</pre>
 *
 * @author Fabian Groffen
 * @version 1.1
 */
public final class MonetSavepoint implements Savepoint {
	/** The id of the last created Savepoint */
	private static final AtomicInteger highestId = new AtomicInteger(0);

	/** The name of this Savepoint */
	private final String name;
	/** The id of this Savepoint */
	private final int id;

	/**
	 * Creates a named MonetSavepoint object
	 *
	 * @param name of savepoint
	 * @throws IllegalArgumentException if no or empty name is given
	 */
	public MonetSavepoint(final String name) throws IllegalArgumentException {
		if (name == null || name.isEmpty())
			throw new IllegalArgumentException("Missing savepoint name");

		this.id = getNextId();
		this.name = name;
	}

	/**
	 * Creates an unnamed MonetSavepoint object
	 */
	public MonetSavepoint() {
		this.id = getNextId();
		this.name = null;
	}


	/**
	 * Retrieves the generated ID for the savepoint that this Savepoint object
	 * represents.
	 *
	 * @return the numeric ID of this savepoint
	 * @throws SQLException if this is a named savepoint
	 */
	@Override
	public int getSavepointId() throws SQLException {
		if (name != null)
			throw new SQLException("Cannot get ID of named savepoint", "3B000");

		return id;
	}

	/**
	 * Retrieves the name of the savepoint that this Savepoint object
	 * represents.
	 *
	 * @return the name of this savepoint
	 * @throws SQLException if this is an un-named savepoint
	 */
	@Override
	public String getSavepointName() throws SQLException {
		if (name == null)
			throw new SQLException("Cannot get name of un-named savepoint", "3B000");

		return name;
	}

	//== end of methods from Savepoint interface

	/**
	 * Retrieves the savepoint id, like the getSavepointId method with the only
	 * difference that this method will always return the id, regardless of
	 * whether it is named or not.
	 *
	 * @return the numeric ID of this savepoint
	 */
	final int getId() {
		return id;
	}

	/**
	 * Returns the constructed internal name to use when referencing this save point to the
	 * MonetDB database. The returned value is guaranteed to be unique and consists of
	 * a prefix string and a sequence number.
	 *
	 * @return the unique savepoint name
	 */
	final String getName() {
		return "JDBCSP" + id;
	}


	/**
	 * Returns the next id, which is larger than the last returned id. This
	 * method is synchronized to prevent race conditions. Since this is static
	 * code, this method is shared by requests from multiple Connection objects.
	 * Therefore two successive calls to this method need not to have a
	 * difference of 1.
	 *
	 * @return the next int which is guaranteed to be higher than the one
	 *         at the last call to this method.
	 */
	private static final int getNextId() {
		return highestId.incrementAndGet();
	}

	/**
	 * Returns the highest id returned by getNextId(). This method is also
	 * synchronized to prevent race conditions and thus guaranteed to be
	 * thread-safe.
	 *
	 * @return the highest id returned by a call to getNextId()
	 */
//	private static int getHighestId() {
//		return highestId.get();
//	}
}