Migrate Registry objects to a TLD table in Cloud SQL (#803)

* Add TLD table

* Change reservedLists to array

* Change ReservedLists back to a set

* Rename reservedListKeyConverter to ReservedListKeySetConverter

* Add a postload method
This commit is contained in:
sarahcaseybot 2020-09-17 12:47:50 -04:00 committed by GitHub
parent b6ed1982c3
commit 5b78844a94
10 changed files with 335 additions and 105 deletions

View file

@ -70,6 +70,13 @@ import java.util.concurrent.ExecutionException;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.PostLoad;
import javax.persistence.Transient;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.joda.time.DateTime;
@ -78,21 +85,31 @@ import org.joda.time.Duration;
/** Persisted per-TLD configuration data. */
@ReportedOn
@Entity
@javax.persistence.Entity(name = "Tld")
public class Registry extends ImmutableObject implements Buildable {
@Parent Key<EntityGroupRoot> parent = getCrossTldKey();
@Parent @Transient Key<EntityGroupRoot> parent = getCrossTldKey();
/**
* The canonical string representation of the TLD associated with this {@link Registry}, which is
* the standard ASCII for regular TLDs and punycoded ASCII for IDN TLDs.
*/
@Id String tldStrId;
@Id
@javax.persistence.Id
@Column(name = "tld_name", nullable = false)
String tldStrId;
/**
* A duplicate of {@link #tldStrId}, to simplify BigQuery reporting since the id field becomes
* {@code __key__.name} rather than being exported as a named field.
*/
String tldStr;
@Transient String tldStr;
/** Sets the Datastore specific field, tldStr, when the entity is loaded from Cloud SQL */
@PostLoad
void postLoad() {
tldStr = tldStrId;
}
/** The suffix that identifies roids as belonging to this specific tld, e.g. -HOW for .how. */
String roidSuffix;
@ -289,6 +306,7 @@ public class Registry extends ImmutableObject implements Buildable {
* <p>All entries of this list must be valid keys for the map of {@code DnsWriter}s injected by
* <code>@Inject Map<String, DnsWriter></code>
*/
@Column(nullable = false)
Set<String> dnsWriters;
/**
@ -312,6 +330,7 @@ public class Registry extends ImmutableObject implements Buildable {
* <p>Failure to do so can result in parallel writes to the {@link
* google.registry.dns.writer.DnsWriter}, which may be dangerous depending on your implementation.
*/
@Column(nullable = false)
int numDnsPublishLocks;
/** Updates an unset numDnsPublishLocks (0) to the standard default of 1. */
@ -327,6 +346,7 @@ public class Registry extends ImmutableObject implements Buildable {
* <p>This will be equal to {@link #tldStr} for ASCII TLDs, but will be non-ASCII for IDN TLDs. We
* store this in a field so that it will be retained upon import into BigQuery.
*/
@Column(nullable = false)
String tldUnicode;
/**
@ -334,9 +354,11 @@ public class Registry extends ImmutableObject implements Buildable {
*
* <p>This is optional; if not configured, then information won't be exported for this TLD.
*/
String driveFolderId;
@Nullable String driveFolderId;
/** The type of the TLD, whether it's real or for testing. */
@Column(nullable = false)
@Enumerated(EnumType.STRING)
TldType tldType = TldType.REAL;
/**
@ -345,20 +367,24 @@ public class Registry extends ImmutableObject implements Buildable {
* <p>Note that this boolean is the sole determiner on whether invoices should be generated for a
* TLD. This applies to {@link TldType#TEST} TLDs as well.
*/
@Column(nullable = false)
boolean invoicingEnabled = false;
/**
* A property that transitions to different TldStates at different times. Stored as a list of
* TldStateTransition embedded objects using the @Mapify annotation.
*/
@Column(nullable = false)
@Mapify(TimedTransitionProperty.TimeMapper.class)
TimedTransitionProperty<TldState, TldStateTransition> tldStateTransitions =
TimedTransitionProperty.forMapify(DEFAULT_TLD_STATE, TldStateTransition.class);
/** An automatically managed creation timestamp. */
@Column(nullable = false)
CreateAutoTimestamp creationTime = CreateAutoTimestamp.create(null);
/** The set of reserved lists that are applicable to this registry. */
@Column(name = "reserved_list_names", nullable = false)
Set<Key<ReservedList>> reservedLists;
/** Retrieves an ImmutableSet of all ReservedLists associated with this tld. */
@ -367,12 +393,15 @@ public class Registry extends ImmutableObject implements Buildable {
}
/** The static {@link PremiumList} for this TLD, if there is one. */
@Column(name = "premium_list_name", nullable = true)
Key<PremiumList> premiumList;
/** Should RDE upload a nightly escrow deposit for this TLD? */
@Column(nullable = false)
boolean escrowEnabled = DEFAULT_ESCROW_ENABLED;
/** Whether the pull queue that writes to authoritative DNS is paused for this TLD. */
@Column(nullable = false)
boolean dnsPaused = DEFAULT_DNS_PAUSED;
/**
@ -381,39 +410,72 @@ public class Registry extends ImmutableObject implements Buildable {
* <p>Domain deletes are free and effective immediately so long as they take place within this
* amount of time following creation.
*/
@Column(nullable = false)
Duration addGracePeriodLength = DEFAULT_ADD_GRACE_PERIOD;
/** The length of the anchor tenant add grace period for this TLD. */
@Column(nullable = false)
Duration anchorTenantAddGracePeriodLength = DEFAULT_ANCHOR_TENANT_ADD_GRACE_PERIOD;
/** The length of the auto renew grace period for this TLD. */
@Column(nullable = false)
Duration autoRenewGracePeriodLength = DEFAULT_AUTO_RENEW_GRACE_PERIOD;
/** The length of the redemption grace period for this TLD. */
@Column(nullable = false)
Duration redemptionGracePeriodLength = DEFAULT_REDEMPTION_GRACE_PERIOD;
/** The length of the renew grace period for this TLD. */
@Column(nullable = false)
Duration renewGracePeriodLength = DEFAULT_RENEW_GRACE_PERIOD;
/** The length of the transfer grace period for this TLD. */
@Column(nullable = false)
Duration transferGracePeriodLength = DEFAULT_TRANSFER_GRACE_PERIOD;
/** The length of time before a transfer is automatically approved for this TLD. */
@Column(nullable = false)
Duration automaticTransferLength = DEFAULT_AUTOMATIC_TRANSFER_LENGTH;
/** The length of time a domain spends in the non-redeemable pending delete phase for this TLD. */
@Column(nullable = false)
Duration pendingDeleteLength = DEFAULT_PENDING_DELETE_LENGTH;
/** The currency unit for all costs associated with this TLD. */
@Column(nullable = false)
CurrencyUnit currency = DEFAULT_CURRENCY;
/** The per-year billing cost for registering a new domain name. */
@AttributeOverrides({
@AttributeOverride(
name = "money.amount",
column = @Column(name = "create_billing_cost_amount")),
@AttributeOverride(
name = "money.currency",
column = @Column(name = "create_billing_cost_currency"))
})
Money createBillingCost = DEFAULT_CREATE_BILLING_COST;
/** The one-time billing cost for restoring a domain name from the redemption grace period. */
@AttributeOverrides({
@AttributeOverride(
name = "money.amount",
column = @Column(name = "restore_billing_cost_amount")),
@AttributeOverride(
name = "money.currency",
column = @Column(name = "restore_billing_cost_currency"))
})
Money restoreBillingCost = DEFAULT_RESTORE_BILLING_COST;
/** The one-time billing cost for changing the server status (i.e. lock). */
@AttributeOverrides({
@AttributeOverride(
name = "money.amount",
column = @Column(name = "server_status_change_billing_cost_amount")),
@AttributeOverride(
name = "money.currency",
column = @Column(name = "server_status_change_billing_cost_currency"))
})
Money serverStatusChangeBillingCost = DEFAULT_SERVER_STATUS_CHANGE_BILLING_COST;
/**
@ -424,11 +486,13 @@ public class Registry extends ImmutableObject implements Buildable {
* name. This cost is also used to compute costs for transfers, since each transfer includes a
* renewal to ensure transfers have a cost.
*/
@Column(nullable = false)
@Mapify(TimedTransitionProperty.TimeMapper.class)
TimedTransitionProperty<Money, BillingCostTransition> renewBillingCostTransitions =
TimedTransitionProperty.forMapify(DEFAULT_RENEW_BILLING_COST, BillingCostTransition.class);
/** A property that tracks the EAP fee schedule (if any) for the TLD. */
@Column(nullable = false)
@Mapify(TimedTransitionProperty.TimeMapper.class)
TimedTransitionProperty<Money, BillingCostTransition> eapFeeSchedule =
TimedTransitionProperty.forMapify(DEFAULT_EAP_BILLING_COST, BillingCostTransition.class);
@ -437,13 +501,14 @@ public class Registry extends ImmutableObject implements Buildable {
String lordnUsername;
/** The end of the claims period (at or after this time, claims no longer applies). */
@Column(nullable = false)
DateTime claimsPeriodEnd = END_OF_TIME;
/** An allow list of clients allowed to be used on domains on this TLD (ignored if empty). */
Set<String> allowedRegistrantContactIds;
@Nullable Set<String> allowedRegistrantContactIds;
/** An allow list of hosts allowed to be used on domains on this TLD (ignored if empty). */
Set<String> allowedFullyQualifiedHostNames;
@Nullable Set<String> allowedFullyQualifiedHostNames;
public String getTldStr() {
return tldStr;

View file

@ -18,20 +18,19 @@ import static google.registry.model.common.EntityGroupRoot.getCrossTldKey;
import com.googlecode.objectify.Key;
import google.registry.model.registry.label.ReservedList;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
/** JPA converter for a {@link Key} containing a {@link ReservedList} */
/** JPA converter for a set of {@link Key} containing a {@link ReservedList} */
@Converter(autoApply = true)
public class ReservedListKeyConverter implements AttributeConverter<Key<ReservedList>, String> {
public class ReservedListKeySetConverter extends StringSetConverterBase<Key<ReservedList>> {
@Override
public String convertToDatabaseColumn(Key<ReservedList> attribute) {
return (attribute == null) ? null : attribute.getName();
String toString(Key<ReservedList> key) {
return key.getName();
}
@Override
public Key<ReservedList> convertToEntityAttribute(String dbData) {
return (dbData == null) ? null : Key.create(getCrossTldKey(), ReservedList.class, dbData);
Key<ReservedList> fromString(String value) {
return Key.create(getCrossTldKey(), ReservedList.class, value);
}
}

View file

@ -51,6 +51,7 @@
<class>google.registry.model.registrar.Registrar</class>
<class>google.registry.model.registrar.RegistrarContact</class>
<class>google.registry.model.registry.label.PremiumList</class>
<class>google.registry.model.registry.Registry</class>
<class>google.registry.model.reporting.Spec11ThreatMatch</class>
<class>google.registry.persistence.transaction.TransactionEntity</class>
<class>google.registry.model.tmch.ClaimsListShard</class>
@ -81,7 +82,7 @@
<class>google.registry.persistence.converter.PostalInfoChoiceListConverter</class>
<class>google.registry.persistence.converter.PremiumListKeyConverter</class>
<class>google.registry.persistence.converter.RegistrarPocSetConverter</class>
<class>google.registry.persistence.converter.ReservedListKeyConverter</class>
<class>google.registry.persistence.converter.ReservedListKeySetConverter</class>
<class>google.registry.persistence.converter.Spec11ThreatMatchThreatTypeSetConverter</class>
<class>google.registry.persistence.converter.StatusValueSetConverter</class>
<class>google.registry.persistence.converter.StringListConverter</class>

View file

@ -23,6 +23,7 @@ import static google.registry.model.registry.Registry.TldState.GENERAL_AVAILABIL
import static google.registry.model.registry.Registry.TldState.PREDELEGATION;
import static google.registry.model.registry.Registry.TldState.QUIET_PERIOD;
import static google.registry.model.registry.Registry.TldState.START_DATE_SUNRISE;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import static google.registry.testing.DatastoreHelper.createTld;
import static google.registry.testing.DatastoreHelper.newRegistry;
import static google.registry.testing.DatastoreHelper.persistPremiumList;
@ -43,20 +44,40 @@ import google.registry.model.registry.Registry.RegistryNotFoundException;
import google.registry.model.registry.Registry.TldState;
import google.registry.model.registry.label.PremiumList;
import google.registry.model.registry.label.ReservedList;
import google.registry.persistence.VKey;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageExtension;
import java.math.BigDecimal;
import org.joda.money.Money;
import org.joda.time.DateTime;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link Registry}. */
class RegistryTest extends EntityTestCase {
public class RegistryTest extends EntityTestCase {
@BeforeEach
void beforeEach() {
createTld("tld");
}
@RegisterExtension
JpaIntegrationWithCoverageExtension jpa =
new JpaTestRules.Builder().withClock(fakeClock).buildIntegrationWithCoverageExtension();
@Test
public void testCloudSqlPersistence() {
ReservedList rl15 = persistReservedList("tld-reserved15", "potato,FULLY_BLOCKED");
PremiumList pl = persistPremiumList("tld2", "lol,USD 50", "cat,USD 700");
Registry registry =
Registry.get("tld").asBuilder().setReservedLists(rl15).setPremiumList(pl).build();
jpaTm().transact(() -> jpaTm().saveNew(registry));
Registry persisted =
jpaTm().transact(() -> jpaTm().load(VKey.createSql(Registry.class, registry.tldStrId)));
assertThat(persisted).isEqualTo(registry);
}
@Test
void testPersistence() {
assertWithMessage("Registry not found").that(Registry.get("tld")).isNotNull();

View file

@ -1,90 +0,0 @@
// Copyright 2020 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.persistence.converter;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.common.EntityGroupRoot.getCrossTldKey;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import com.googlecode.objectify.Key;
import google.registry.model.ImmutableObject;
import google.registry.model.registry.label.ReservedList;
import google.registry.testing.AppEngineExtension;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link ReservedListKeyConverter}. */
class ReservedListKeyConverterTest {
@RegisterExtension
final AppEngineExtension appEngine =
AppEngineExtension.builder()
.withDatastoreAndCloudSql()
.withJpaUnitTestEntities(ReservedListEntity.class)
.build();
private final ReservedListKeyConverter converter = new ReservedListKeyConverter();
@Test
void convertToDatabaseColumn_returnsNullIfInputIsNull() {
assertThat(converter.convertToDatabaseColumn(null)).isNull();
}
@Test
void convertToDatabaseColumn_convertsCorrectly() {
assertThat(
converter.convertToDatabaseColumn(
Key.create(getCrossTldKey(), ReservedList.class, "testList")))
.isEqualTo("testList");
}
@Test
void convertToEntityAttribute_returnsNullIfInputIsNull() {
assertThat(converter.convertToEntityAttribute(null)).isNull();
}
@Test
void convertToEntityAttribute_convertsCorrectly() {
assertThat(converter.convertToEntityAttribute("testList"))
.isEqualTo(Key.create(getCrossTldKey(), ReservedList.class, "testList"));
}
@Test
void testRoundTrip() {
Key<ReservedList> key = Key.create(getCrossTldKey(), ReservedList.class, "test");
ReservedListEntity testEntity = new ReservedListEntity(key);
jpaTm().transact(() -> jpaTm().getEntityManager().persist(testEntity));
ReservedListEntity persisted =
jpaTm().transact(() -> jpaTm().getEntityManager().find(ReservedListEntity.class, "test"));
assertThat(persisted.reservedList).isEqualTo(key);
}
@Entity(name = "ReservedListEntity")
private static class ReservedListEntity extends ImmutableObject {
@Id String name;
Key<ReservedList> reservedList;
public ReservedListEntity() {}
ReservedListEntity(Key<ReservedList> reservedList) {
this.name = reservedList.getName();
this.reservedList = reservedList;
}
}
}

View file

@ -0,0 +1,87 @@
// Copyright 2020 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.persistence.converter;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.common.EntityGroupRoot.getCrossTldKey;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import com.googlecode.objectify.Key;
import google.registry.model.ImmutableObject;
import google.registry.model.registry.label.ReservedList;
import google.registry.testing.AppEngineExtension;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.testcontainers.shaded.com.google.common.collect.ImmutableSet;
/** Unit tests for {@link ReservedListKeySetConverter}. */
class ReservedListKeySetConverterTest {
@RegisterExtension
final AppEngineExtension appEngine =
AppEngineExtension.builder()
.withDatastoreAndCloudSql()
.withJpaUnitTestEntities(ReservedListSetEntity.class)
.build();
@Test
void roundTripConversion_returnsSameSet() {
Key<ReservedList> key1 = Key.create(getCrossTldKey(), ReservedList.class, "test1");
Key<ReservedList> key2 = Key.create(getCrossTldKey(), ReservedList.class, "test2");
Key<ReservedList> key3 = Key.create(getCrossTldKey(), ReservedList.class, "test3");
Set<Key<ReservedList>> reservedLists = ImmutableSet.of(key1, key2, key3);
ReservedListSetEntity testEntity = new ReservedListSetEntity(reservedLists);
jpaTm().transact(() -> jpaTm().getEntityManager().persist(testEntity));
ReservedListSetEntity persisted =
jpaTm().transact(() -> jpaTm().getEntityManager().find(ReservedListSetEntity.class, "id"));
assertThat(persisted.reservedList).containsExactly(key1, key2, key3);
}
@Test
void testNullValue_writesAndReadsNullSuccessfully() {
ReservedListSetEntity testEntity = new ReservedListSetEntity(null);
jpaTm().transact(() -> jpaTm().getEntityManager().persist(testEntity));
ReservedListSetEntity persisted =
jpaTm().transact(() -> jpaTm().getEntityManager().find(ReservedListSetEntity.class, "id"));
assertThat(persisted.reservedList).isNull();
}
@Test
void testEmptyCollection_writesAndReadsEmptyCollectionSuccessfully() {
ReservedListSetEntity testEntity = new ReservedListSetEntity(ImmutableSet.of());
jpaTm().transact(() -> jpaTm().getEntityManager().persist(testEntity));
ReservedListSetEntity persisted =
jpaTm().transact(() -> jpaTm().getEntityManager().find(ReservedListSetEntity.class, "id"));
assertThat(persisted.reservedList).isEmpty();
}
@Entity(name = "ReservedListSetEntity")
private static class ReservedListSetEntity extends ImmutableObject {
@Id String name = "id";
Set<Key<ReservedList>> reservedList;
public ReservedListSetEntity() {}
ReservedListSetEntity(Set<Key<ReservedList>> reservedList) {
this.reservedList = reservedList;
}
}
}

View file

@ -25,6 +25,7 @@ import google.registry.model.history.DomainHistoryTest;
import google.registry.model.history.HostHistoryTest;
import google.registry.model.poll.PollMessageTest;
import google.registry.model.registry.RegistryLockDaoTest;
import google.registry.model.registry.RegistryTest;
import google.registry.model.registry.label.ReservedListSqlDaoTest;
import google.registry.model.reporting.Spec11ThreatMatchTest;
import google.registry.model.tmch.ClaimsListDaoTest;
@ -86,6 +87,7 @@ import org.junit.runner.RunWith;
PollMessageTest.class,
PremiumListDaoTest.class,
RegistrarDaoTest.class,
RegistryTest.class,
ReservedListSqlDaoTest.class,
RegistryLockDaoTest.class,
Spec11ThreatMatchTest.class,

View file

@ -0,0 +1,53 @@
-- Copyright 2020 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 "Tld" (
tld_name text not null,
add_grace_period_length interval not null,
allowed_fully_qualified_host_names text[],
allowed_registrant_contact_ids text[],
anchor_tenant_add_grace_period_length interval not null,
auto_renew_grace_period_length interval not null,
automatic_transfer_length interval not null,
claims_period_end timestamptz not null,
create_billing_cost_amount numeric(19, 2),
create_billing_cost_currency text,
creation_time timestamptz not null,
currency text not null,
dns_paused boolean not null,
dns_writers text[] not null,
drive_folder_id text,
eap_fee_schedule hstore not null,
escrow_enabled boolean not null,
invoicing_enabled boolean not null,
lordn_username text,
num_dns_publish_locks int4 not null,
pending_delete_length interval not null,
premium_list_name text,
pricing_engine_class_name text,
redemption_grace_period_length interval not null,
renew_billing_cost_transitions hstore not null,
renew_grace_period_length interval not null,
reserved_list_names text[] not null,
restore_billing_cost_amount numeric(19, 2),
restore_billing_cost_currency text,
roid_suffix text,
server_status_change_billing_cost_amount numeric(19, 2),
server_status_change_billing_cost_currency text,
tld_state_transitions hstore not null,
tld_type text not null,
tld_unicode text not null,
transfer_grace_period_length interval not null,
primary key (tld_name)
);

View file

@ -580,6 +580,46 @@ create sequence temp_history_id_sequence start 1 increment 50;
primary key (id)
);
create table "Tld" (
tld_name text not null,
add_grace_period_length interval not null,
allowed_fully_qualified_host_names text[],
allowed_registrant_contact_ids text[],
anchor_tenant_add_grace_period_length interval not null,
auto_renew_grace_period_length interval not null,
automatic_transfer_length interval not null,
claims_period_end timestamptz not null,
create_billing_cost_amount numeric(19, 2),
create_billing_cost_currency text,
creation_time timestamptz not null,
currency text not null,
dns_paused boolean not null,
dns_writers text[] not null,
drive_folder_id text,
eap_fee_schedule hstore not null,
escrow_enabled boolean not null,
invoicing_enabled boolean not null,
lordn_username text,
num_dns_publish_locks int4 not null,
pending_delete_length interval not null,
premium_list_name text,
pricing_engine_class_name text,
redemption_grace_period_length interval not null,
renew_billing_cost_transitions hstore not null,
renew_grace_period_length interval not null,
reserved_list_names text[] not null,
restore_billing_cost_amount numeric(19, 2),
restore_billing_cost_currency text,
roid_suffix text,
server_status_change_billing_cost_amount numeric(19, 2),
server_status_change_billing_cost_currency text,
tld_state_transitions hstore not null,
tld_type text not null,
tld_unicode text not null,
transfer_grace_period_length interval not null,
primary key (tld_name)
);
create table "Transaction" (
id bigserial not null,
contents bytea,

View file

@ -889,6 +889,50 @@ CREATE SEQUENCE public."SafeBrowsingThreat_id_seq"
ALTER SEQUENCE public."SafeBrowsingThreat_id_seq" OWNED BY public."Spec11ThreatMatch".id;
--
-- Name: Tld; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public."Tld" (
tld_name text NOT NULL,
add_grace_period_length interval NOT NULL,
allowed_fully_qualified_host_names text[],
allowed_registrant_contact_ids text[],
anchor_tenant_add_grace_period_length interval NOT NULL,
auto_renew_grace_period_length interval NOT NULL,
automatic_transfer_length interval NOT NULL,
claims_period_end timestamp with time zone NOT NULL,
create_billing_cost_amount numeric(19,2),
create_billing_cost_currency text,
creation_time timestamp with time zone NOT NULL,
currency text NOT NULL,
dns_paused boolean NOT NULL,
dns_writers text[] NOT NULL,
drive_folder_id text,
eap_fee_schedule public.hstore NOT NULL,
escrow_enabled boolean NOT NULL,
invoicing_enabled boolean NOT NULL,
lordn_username text,
num_dns_publish_locks integer NOT NULL,
pending_delete_length interval NOT NULL,
premium_list_name text,
pricing_engine_class_name text,
redemption_grace_period_length interval NOT NULL,
renew_billing_cost_transitions public.hstore NOT NULL,
renew_grace_period_length interval NOT NULL,
reserved_list_names text[] NOT NULL,
restore_billing_cost_amount numeric(19,2),
restore_billing_cost_currency text,
roid_suffix text,
server_status_change_billing_cost_amount numeric(19,2),
server_status_change_billing_cost_currency text,
tld_state_transitions public.hstore NOT NULL,
tld_type text NOT NULL,
tld_unicode text NOT NULL,
transfer_grace_period_length interval NOT NULL
);
--
-- Name: Transaction; Type: TABLE; Schema: public; Owner: -
--
@ -1211,6 +1255,14 @@ ALTER TABLE ONLY public."Spec11ThreatMatch"
ADD CONSTRAINT "SafeBrowsingThreat_pkey" PRIMARY KEY (id);
--
-- Name: Tld Tld_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."Tld"
ADD CONSTRAINT "Tld_pkey" PRIMARY KEY (tld_name);
--
-- Name: Transaction Transaction_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--