mirror of
https://github.com/google/nomulus.git
synced 2025-05-19 18:59:35 +02:00
Add schema and DAO for cursors in cloudsql (#370)
* Add schema for Cursor * Add CursorDao and CursorDaoTest * Fix comment on getTld * Change tld column to scope * Fix cursorTime to be converted to DateTime internally and other small fixes * Add a CursorType enum and a createGlobal constructor for Cursor * Rename flyway file * Use cursorType from common/Cursor.java and add null checks
This commit is contained in:
parent
bba5aff4b6
commit
2478a4a93b
8 changed files with 370 additions and 0 deletions
116
core/src/main/java/google/registry/schema/cursor/Cursor.java
Normal file
116
core/src/main/java/google/registry/schema/cursor/Cursor.java
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
// Copyright 2019 The Nomulus Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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 google.registry.schema.cursor;
|
||||||
|
|
||||||
|
import static com.google.appengine.api.search.checkers.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import google.registry.model.ImmutableObject;
|
||||||
|
import google.registry.model.UpdateAutoTimestamp;
|
||||||
|
import google.registry.model.common.Cursor.CursorType;
|
||||||
|
import google.registry.schema.cursor.Cursor.CursorId;
|
||||||
|
import google.registry.util.DateTimeUtils;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.EnumType;
|
||||||
|
import javax.persistence.Enumerated;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.IdClass;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shared entity for date cursors. This uses a compound primary key as defined in {@link CursorId}.
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Table
|
||||||
|
@IdClass(CursorId.class)
|
||||||
|
public class Cursor {
|
||||||
|
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
@Column(nullable = false)
|
||||||
|
@Id
|
||||||
|
private CursorType type;
|
||||||
|
|
||||||
|
@Column @Id private String scope;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private ZonedDateTime cursorTime;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private UpdateAutoTimestamp lastUpdateTime = UpdateAutoTimestamp.create(null);
|
||||||
|
|
||||||
|
/** The scope of a global cursor. A global cursor is a cursor that is not specific to one tld. */
|
||||||
|
public static final String GLOBAL = "GLOBAL";
|
||||||
|
|
||||||
|
private Cursor(CursorType type, String scope, DateTime cursorTime) {
|
||||||
|
this.type = type;
|
||||||
|
this.scope = scope;
|
||||||
|
this.cursorTime = DateTimeUtils.toZonedDateTime(cursorTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hibernate requires a default constructor.
|
||||||
|
private Cursor() {}
|
||||||
|
|
||||||
|
/** Constructs a {@link Cursor} object. */
|
||||||
|
public static Cursor create(CursorType type, String scope, DateTime cursorTime) {
|
||||||
|
checkNotNull(
|
||||||
|
scope, "Scope cannot be null. To create a global cursor, use the createGlobal method");
|
||||||
|
return new Cursor(type, scope, cursorTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Constructs a {@link Cursor} object with a {@link GLOBAL} scope. */
|
||||||
|
public static Cursor createGlobal(CursorType type, DateTime cursorTime) {
|
||||||
|
return new Cursor(type, GLOBAL, cursorTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the type of the cursor. */
|
||||||
|
public CursorType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the scope of the cursor. The scope will typically be the tld the cursor is referring
|
||||||
|
* to. If the cursor is a global cursor, the scope will be {@link GLOBAL}.
|
||||||
|
*/
|
||||||
|
public String getScope() {
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the time the cursor is set to. */
|
||||||
|
public DateTime getCursorTime() {
|
||||||
|
return DateTimeUtils.toJodaDateTime(cursorTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the last time the cursor was updated. */
|
||||||
|
public DateTime getLastUpdateTime() {
|
||||||
|
return lastUpdateTime.getTimestamp();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class CursorId extends ImmutableObject implements Serializable {
|
||||||
|
|
||||||
|
public CursorType type;
|
||||||
|
|
||||||
|
public String scope;
|
||||||
|
|
||||||
|
private CursorId() {}
|
||||||
|
|
||||||
|
public CursorId(CursorType type, String scope) {
|
||||||
|
this.type = type;
|
||||||
|
this.scope = scope;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
// Copyright 2019 The Nomulus Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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 google.registry.schema.cursor;
|
||||||
|
|
||||||
|
import static com.google.appengine.api.search.checkers.Preconditions.checkNotNull;
|
||||||
|
import static google.registry.model.transaction.TransactionManagerFactory.jpaTm;
|
||||||
|
|
||||||
|
import google.registry.model.common.Cursor.CursorType;
|
||||||
|
import google.registry.schema.cursor.Cursor.CursorId;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/** Data access object class for {@link Cursor}. */
|
||||||
|
public class CursorDao {
|
||||||
|
|
||||||
|
public static void save(Cursor cursor) {
|
||||||
|
jpaTm()
|
||||||
|
.transact(
|
||||||
|
() -> {
|
||||||
|
jpaTm().getEntityManager().merge(cursor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Cursor load(CursorType type, String scope) {
|
||||||
|
checkNotNull(scope, "The scope of the cursor to load cannot be null");
|
||||||
|
checkNotNull(type, "The type of the cursor to load must be specified");
|
||||||
|
return jpaTm()
|
||||||
|
.transact(() -> jpaTm().getEntityManager().find(Cursor.class, new CursorId(type, scope)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** If no scope is given, use {@link Cursor.GLOBAL} as the scope. */
|
||||||
|
public static Cursor load(CursorType type) {
|
||||||
|
checkNotNull(type, "The type of the cursor to load must be specified");
|
||||||
|
return load(type, Cursor.GLOBAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Cursor> loadAll() {
|
||||||
|
return jpaTm()
|
||||||
|
.transact(
|
||||||
|
() ->
|
||||||
|
jpaTm()
|
||||||
|
.getEntityManager()
|
||||||
|
.createQuery("SELECT cursor FROM Cursor cursor", Cursor.class)
|
||||||
|
.getResultList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Cursor> loadByType(CursorType type) {
|
||||||
|
checkNotNull(type, "The type of the cursors to load must be specified");
|
||||||
|
return jpaTm()
|
||||||
|
.transact(
|
||||||
|
() ->
|
||||||
|
jpaTm()
|
||||||
|
.getEntityManager()
|
||||||
|
.createQuery(
|
||||||
|
"SELECT cursor FROM Cursor cursor WHERE cursor.type = :type", Cursor.class)
|
||||||
|
.setParameter("type", type)
|
||||||
|
.getResultList());
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,7 @@
|
||||||
<class>google.registry.model.domain.DomainBase</class>
|
<class>google.registry.model.domain.DomainBase</class>
|
||||||
<class>google.registry.schema.domain.RegistryLock</class>
|
<class>google.registry.schema.domain.RegistryLock</class>
|
||||||
<class>google.registry.schema.tmch.ClaimsList</class>
|
<class>google.registry.schema.tmch.ClaimsList</class>
|
||||||
|
<class>google.registry.schema.cursor.Cursor</class>
|
||||||
<class>google.registry.model.transfer.BaseTransferObject</class>
|
<class>google.registry.model.transfer.BaseTransferObject</class>
|
||||||
<class>google.registry.schema.tld.PremiumList</class>
|
<class>google.registry.schema.tld.PremiumList</class>
|
||||||
<class>google.registry.schema.tld.ReservedList</class>
|
<class>google.registry.schema.tld.ReservedList</class>
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
// Copyright 2019 The Nomulus Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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 google.registry.schema.cursor;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import google.registry.model.common.Cursor.CursorType;
|
||||||
|
import google.registry.model.transaction.JpaTransactionManagerRule;
|
||||||
|
import google.registry.testing.FakeClock;
|
||||||
|
import java.util.List;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.JUnit4;
|
||||||
|
|
||||||
|
/** Unit tests for {@link Cursor}. */
|
||||||
|
@RunWith(JUnit4.class)
|
||||||
|
public class CursorDaoTest {
|
||||||
|
|
||||||
|
private FakeClock fakeClock = new FakeClock();
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final JpaTransactionManagerRule jpaTmRule =
|
||||||
|
new JpaTransactionManagerRule.Builder().build();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void save_worksSuccessfullyOnNewCursor() {
|
||||||
|
Cursor cursor = Cursor.create(CursorType.BRDA, "tld", fakeClock.nowUtc());
|
||||||
|
CursorDao.save(cursor);
|
||||||
|
Cursor returnedCursor = CursorDao.load(CursorType.BRDA, "tld");
|
||||||
|
assertThat(returnedCursor.getCursorTime()).isEqualTo(cursor.getCursorTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void save_worksSuccessfullyOnExistingCursor() {
|
||||||
|
Cursor cursor = Cursor.create(CursorType.RDE_REPORT, "tld", fakeClock.nowUtc());
|
||||||
|
CursorDao.save(cursor);
|
||||||
|
Cursor cursor2 = Cursor.create(CursorType.RDE_REPORT, "tld", fakeClock.nowUtc().plusDays(3));
|
||||||
|
CursorDao.save(cursor2);
|
||||||
|
Cursor returnedCursor = CursorDao.load(CursorType.RDE_REPORT, "tld");
|
||||||
|
assertThat(returnedCursor.getCursorTime()).isEqualTo(cursor2.getCursorTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void save_worksSuccessfullyOnNewGlobalCursor() {
|
||||||
|
Cursor cursor = Cursor.createGlobal(CursorType.RECURRING_BILLING, fakeClock.nowUtc());
|
||||||
|
CursorDao.save(cursor);
|
||||||
|
Cursor returnedCursor = CursorDao.load(CursorType.RECURRING_BILLING);
|
||||||
|
assertThat(returnedCursor.getCursorTime()).isEqualTo(cursor.getCursorTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void save_worksSuccessfullyOnExistingGlobalCursor() {
|
||||||
|
Cursor cursor = Cursor.createGlobal(CursorType.RECURRING_BILLING, fakeClock.nowUtc());
|
||||||
|
CursorDao.save(cursor);
|
||||||
|
Cursor cursor2 =
|
||||||
|
Cursor.createGlobal(CursorType.RECURRING_BILLING, fakeClock.nowUtc().plusDays(3));
|
||||||
|
CursorDao.save(cursor2);
|
||||||
|
Cursor returnedCursor = CursorDao.load(CursorType.RECURRING_BILLING);
|
||||||
|
assertThat(returnedCursor.getCursorTime()).isEqualTo(cursor2.getCursorTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void load_worksSuccessfully() {
|
||||||
|
Cursor cursor = Cursor.createGlobal(CursorType.RECURRING_BILLING, fakeClock.nowUtc());
|
||||||
|
Cursor cursor2 = Cursor.create(CursorType.RDE_REPORT, "tld", fakeClock.nowUtc());
|
||||||
|
Cursor cursor3 = Cursor.create(CursorType.RDE_REPORT, "foo", fakeClock.nowUtc());
|
||||||
|
Cursor cursor4 = Cursor.create(CursorType.BRDA, "foo", fakeClock.nowUtc());
|
||||||
|
CursorDao.save(cursor);
|
||||||
|
CursorDao.save(cursor2);
|
||||||
|
CursorDao.save(cursor3);
|
||||||
|
CursorDao.save(cursor4);
|
||||||
|
Cursor returnedCursor = CursorDao.load(CursorType.RDE_REPORT, "tld");
|
||||||
|
assertThat(returnedCursor.getCursorTime()).isEqualTo(cursor2.getCursorTime());
|
||||||
|
returnedCursor = CursorDao.load(CursorType.BRDA, "foo");
|
||||||
|
assertThat(returnedCursor.getCursorTime()).isEqualTo(cursor4.getCursorTime());
|
||||||
|
returnedCursor = CursorDao.load(CursorType.RECURRING_BILLING);
|
||||||
|
assertThat(returnedCursor.getCursorTime()).isEqualTo(cursor.getCursorTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loadAll_worksSuccessfully() {
|
||||||
|
Cursor cursor = Cursor.createGlobal(CursorType.RECURRING_BILLING, fakeClock.nowUtc());
|
||||||
|
Cursor cursor2 = Cursor.create(CursorType.RDE_REPORT, "tld", fakeClock.nowUtc());
|
||||||
|
Cursor cursor3 = Cursor.create(CursorType.RDE_REPORT, "foo", fakeClock.nowUtc());
|
||||||
|
Cursor cursor4 = Cursor.create(CursorType.BRDA, "foo", fakeClock.nowUtc());
|
||||||
|
CursorDao.save(cursor);
|
||||||
|
CursorDao.save(cursor2);
|
||||||
|
CursorDao.save(cursor3);
|
||||||
|
CursorDao.save(cursor4);
|
||||||
|
List<Cursor> returnedCursors = CursorDao.loadAll();
|
||||||
|
assertThat(returnedCursors.size()).isEqualTo(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loadAll_worksSuccessfullyEmptyTable() {
|
||||||
|
List<Cursor> returnedCursors = CursorDao.loadAll();
|
||||||
|
assertThat(returnedCursors.size()).isEqualTo(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loadByType_worksSuccessfully() {
|
||||||
|
Cursor cursor = Cursor.createGlobal(CursorType.RECURRING_BILLING, fakeClock.nowUtc());
|
||||||
|
Cursor cursor2 = Cursor.create(CursorType.RDE_REPORT, "tld", fakeClock.nowUtc());
|
||||||
|
Cursor cursor3 = Cursor.create(CursorType.RDE_REPORT, "foo", fakeClock.nowUtc());
|
||||||
|
Cursor cursor4 = Cursor.create(CursorType.BRDA, "foo", fakeClock.nowUtc());
|
||||||
|
CursorDao.save(cursor);
|
||||||
|
CursorDao.save(cursor2);
|
||||||
|
CursorDao.save(cursor3);
|
||||||
|
CursorDao.save(cursor4);
|
||||||
|
List<Cursor> returnedCursors = CursorDao.loadByType(CursorType.RDE_REPORT);
|
||||||
|
assertThat(returnedCursors.size()).isEqualTo(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loadByType_worksSuccessfullyNoneOfType() {
|
||||||
|
List<Cursor> returnedCursors = CursorDao.loadByType(CursorType.RDE_REPORT);
|
||||||
|
assertThat(returnedCursors.size()).isEqualTo(0);
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ import google.registry.persistence.DateTimeConverterTest;
|
||||||
import google.registry.persistence.JodaMoneyConverterTest;
|
import google.registry.persistence.JodaMoneyConverterTest;
|
||||||
import google.registry.persistence.UpdateAutoTimestampConverterTest;
|
import google.registry.persistence.UpdateAutoTimestampConverterTest;
|
||||||
import google.registry.persistence.ZonedDateTimeConverterTest;
|
import google.registry.persistence.ZonedDateTimeConverterTest;
|
||||||
|
import google.registry.schema.cursor.CursorDaoTest;
|
||||||
import google.registry.schema.tld.PremiumListDaoTest;
|
import google.registry.schema.tld.PremiumListDaoTest;
|
||||||
import google.registry.ui.server.registrar.RegistryLockGetActionTest;
|
import google.registry.ui.server.registrar.RegistryLockGetActionTest;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
@ -47,6 +48,7 @@ import org.junit.runners.Suite.SuiteClasses;
|
||||||
ClaimsListDaoTest.class,
|
ClaimsListDaoTest.class,
|
||||||
CreateAutoTimestampConverterTest.class,
|
CreateAutoTimestampConverterTest.class,
|
||||||
CurrencyUnitConverterTest.class,
|
CurrencyUnitConverterTest.class,
|
||||||
|
CursorDaoTest.class,
|
||||||
DateTimeConverterTest.class,
|
DateTimeConverterTest.class,
|
||||||
JodaMoneyConverterTest.class,
|
JodaMoneyConverterTest.class,
|
||||||
JpaTransactionManagerImplTest.class,
|
JpaTransactionManagerImplTest.class,
|
||||||
|
|
21
db/src/main/resources/sql/flyway/V11__create_cursor.sql
Normal file
21
db/src/main/resources/sql/flyway/V11__create_cursor.sql
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
-- Copyright 2019 The Nomulus Authors. All Rights Reserved.
|
||||||
|
--
|
||||||
|
-- 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.
|
||||||
|
|
||||||
|
create table "Cursor" (
|
||||||
|
scope text not null,
|
||||||
|
type text not null,
|
||||||
|
cursor_time timestamptz not null,
|
||||||
|
last_update_time timestamptz not null,
|
||||||
|
primary key (scope, type)
|
||||||
|
);
|
|
@ -26,6 +26,14 @@
|
||||||
primary key (revision_id)
|
primary key (revision_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
create table "Cursor" (
|
||||||
|
scope text not null,
|
||||||
|
type text not null,
|
||||||
|
cursor_time timestamptz not null,
|
||||||
|
last_update_time timestamptz not null,
|
||||||
|
primary key (scope, type)
|
||||||
|
);
|
||||||
|
|
||||||
create table "DelegationSignerData" (
|
create table "DelegationSignerData" (
|
||||||
key_tag int4 not null,
|
key_tag int4 not null,
|
||||||
algorithm int4 not null,
|
algorithm int4 not null,
|
||||||
|
|
|
@ -61,6 +61,18 @@ CREATE SEQUENCE public."ClaimsList_revision_id_seq"
|
||||||
ALTER SEQUENCE public."ClaimsList_revision_id_seq" OWNED BY public."ClaimsList".revision_id;
|
ALTER SEQUENCE public."ClaimsList_revision_id_seq" OWNED BY public."ClaimsList".revision_id;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: Cursor; Type: TABLE; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE public."Cursor" (
|
||||||
|
scope text NOT NULL,
|
||||||
|
type text NOT NULL,
|
||||||
|
cursor_time timestamp with time zone NOT NULL,
|
||||||
|
last_update_time timestamp with time zone NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: PremiumEntry; Type: TABLE; Schema: public; Owner: -
|
-- Name: PremiumEntry; Type: TABLE; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
|
@ -228,6 +240,14 @@ ALTER TABLE ONLY public."ClaimsList"
|
||||||
ADD CONSTRAINT "ClaimsList_pkey" PRIMARY KEY (revision_id);
|
ADD CONSTRAINT "ClaimsList_pkey" PRIMARY KEY (revision_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: Cursor Cursor_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public."Cursor"
|
||||||
|
ADD CONSTRAINT "Cursor_pkey" PRIMARY KEY (scope, type);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: PremiumEntry PremiumEntry_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
-- Name: PremiumEntry PremiumEntry_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue