Add 'created on' field to groups
Contrary to accounts, groups currently have no indication on when they were created. From now on, the instant a group is added will be remembered. For existing groups, only a best guess is possible by deriving the creation time from the first time this group was recorded in the audit. As that is not possible for groups which were created before the audit was introduced, those groups get the moment the audit was available as creation time. Change-Id: Ic5b3cb8ec6373ad804535b73cbbf85675ab3ec6f
This commit is contained in:
		@@ -17,6 +17,7 @@ package com.google.gerrit.reviewdb.client;
 | 
			
		||||
import com.google.gwtorm.client.Column;
 | 
			
		||||
import com.google.gwtorm.client.IntKey;
 | 
			
		||||
import com.google.gwtorm.client.StringKey;
 | 
			
		||||
import java.sql.Timestamp;
 | 
			
		||||
 | 
			
		||||
/** Named group of one or more accounts, typically used for access controls. */
 | 
			
		||||
public final class AccountGroup {
 | 
			
		||||
@@ -145,17 +146,22 @@ public final class AccountGroup {
 | 
			
		||||
  @Column(id = 10)
 | 
			
		||||
  protected UUID ownerGroupUUID;
 | 
			
		||||
 | 
			
		||||
  @Column(id = 11)
 | 
			
		||||
  protected Timestamp createdOn;
 | 
			
		||||
 | 
			
		||||
  protected AccountGroup() {}
 | 
			
		||||
 | 
			
		||||
  public AccountGroup(
 | 
			
		||||
      final AccountGroup.NameKey newName,
 | 
			
		||||
      final AccountGroup.Id newId,
 | 
			
		||||
      final AccountGroup.UUID uuid) {
 | 
			
		||||
      AccountGroup.NameKey newName,
 | 
			
		||||
      AccountGroup.Id newId,
 | 
			
		||||
      AccountGroup.UUID uuid,
 | 
			
		||||
      Timestamp createdOn) {
 | 
			
		||||
    name = newName;
 | 
			
		||||
    groupId = newId;
 | 
			
		||||
    visibleToAll = false;
 | 
			
		||||
    groupUUID = uuid;
 | 
			
		||||
    ownerGroupUUID = groupUUID;
 | 
			
		||||
    this.createdOn = createdOn;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public AccountGroup.Id getId() {
 | 
			
		||||
@@ -205,4 +211,12 @@ public final class AccountGroup {
 | 
			
		||||
  public void setGroupUUID(AccountGroup.UUID uuid) {
 | 
			
		||||
    groupUUID = uuid;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public Timestamp getCreatedOn() {
 | 
			
		||||
    return createdOn;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void setCreatedOn(Timestamp createdOn) {
 | 
			
		||||
    this.createdOn = createdOn;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@ package com.google.gerrit.server.account;
 | 
			
		||||
import com.google.common.cache.CacheLoader;
 | 
			
		||||
import com.google.common.cache.LoadingCache;
 | 
			
		||||
import com.google.common.collect.ImmutableList;
 | 
			
		||||
import com.google.gerrit.common.TimeUtil;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.AccountGroup;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.AccountGroupName;
 | 
			
		||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
			
		||||
@@ -167,7 +168,7 @@ public class GroupCacheImpl implements GroupCache {
 | 
			
		||||
 | 
			
		||||
  private static AccountGroup missing(AccountGroup.Id key) {
 | 
			
		||||
    AccountGroup.NameKey name = new AccountGroup.NameKey("Deleted Group" + key);
 | 
			
		||||
    return new AccountGroup(name, key, null);
 | 
			
		||||
    return new AccountGroup(name, key, null, TimeUtil.nowTs());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static class ByIdLoader extends CacheLoader<AccountGroup.Id, Optional<AccountGroup>> {
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@ package com.google.gerrit.server.group;
 | 
			
		||||
 | 
			
		||||
import com.google.common.base.MoreObjects;
 | 
			
		||||
import com.google.common.base.Strings;
 | 
			
		||||
import com.google.gerrit.common.TimeUtil;
 | 
			
		||||
import com.google.gerrit.common.data.GlobalCapability;
 | 
			
		||||
import com.google.gerrit.common.data.GroupDescription;
 | 
			
		||||
import com.google.gerrit.common.data.GroupDescriptions;
 | 
			
		||||
@@ -188,7 +189,8 @@ public class CreateGroup implements RestModifyView<TopLevelResource, GroupInput>
 | 
			
		||||
        GroupUUID.make(
 | 
			
		||||
            createGroupArgs.getGroupName(),
 | 
			
		||||
            self.get().newCommitterIdent(serverIdent.getWhen(), serverIdent.getTimeZone()));
 | 
			
		||||
    AccountGroup group = new AccountGroup(createGroupArgs.getGroup(), groupId, uuid);
 | 
			
		||||
    AccountGroup group =
 | 
			
		||||
        new AccountGroup(createGroupArgs.getGroup(), groupId, uuid, TimeUtil.nowTs());
 | 
			
		||||
    group.setVisibleToAll(createGroupArgs.visibleToAll);
 | 
			
		||||
    if (createGroupArgs.ownerGroupId != null) {
 | 
			
		||||
      AccountGroup ownerGroup = groupCache.get(createGroupArgs.ownerGroupId);
 | 
			
		||||
 
 | 
			
		||||
@@ -18,10 +18,12 @@ import static com.google.gerrit.server.index.FieldDef.exact;
 | 
			
		||||
import static com.google.gerrit.server.index.FieldDef.fullText;
 | 
			
		||||
import static com.google.gerrit.server.index.FieldDef.integer;
 | 
			
		||||
import static com.google.gerrit.server.index.FieldDef.prefix;
 | 
			
		||||
import static com.google.gerrit.server.index.FieldDef.timestamp;
 | 
			
		||||
 | 
			
		||||
import com.google.gerrit.reviewdb.client.AccountGroup;
 | 
			
		||||
import com.google.gerrit.server.index.FieldDef;
 | 
			
		||||
import com.google.gerrit.server.index.SchemaUtil;
 | 
			
		||||
import java.sql.Timestamp;
 | 
			
		||||
 | 
			
		||||
/** Secondary index schemas for groups. */
 | 
			
		||||
public class GroupField {
 | 
			
		||||
@@ -37,6 +39,10 @@ public class GroupField {
 | 
			
		||||
  public static final FieldDef<AccountGroup, String> OWNER_UUID =
 | 
			
		||||
      exact("owner_uuid").build(g -> g.getOwnerGroupUUID().get());
 | 
			
		||||
 | 
			
		||||
  /** Timestamp indicating when this group was created. */
 | 
			
		||||
  public static final FieldDef<AccountGroup, Timestamp> CREATED_ON =
 | 
			
		||||
      timestamp("created_on").build(AccountGroup::getCreatedOn);
 | 
			
		||||
 | 
			
		||||
  /** Group name. */
 | 
			
		||||
  public static final FieldDef<AccountGroup, String> NAME =
 | 
			
		||||
      exact("name").build(AccountGroup::getName);
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,9 @@ public class GroupSchemaDefinitions extends SchemaDefinitions<AccountGroup> {
 | 
			
		||||
          GroupField.DESCRIPTION,
 | 
			
		||||
          GroupField.IS_VISIBLE_TO_ALL);
 | 
			
		||||
 | 
			
		||||
  static final Schema<AccountGroup> V2 = schema(V1);
 | 
			
		||||
  @Deprecated static final Schema<AccountGroup> V2 = schema(V1);
 | 
			
		||||
 | 
			
		||||
  static final Schema<AccountGroup> V3 = schema(V2, GroupField.CREATED_ON);
 | 
			
		||||
 | 
			
		||||
  public static final GroupSchemaDefinitions INSTANCE = new GroupSchemaDefinitions();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,7 @@
 | 
			
		||||
 | 
			
		||||
package com.google.gerrit.server.schema;
 | 
			
		||||
 | 
			
		||||
import com.google.gerrit.common.TimeUtil;
 | 
			
		||||
import com.google.gerrit.common.data.GroupReference;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.AccountGroup;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.AccountGroupName;
 | 
			
		||||
@@ -124,7 +125,8 @@ public class SchemaCreator {
 | 
			
		||||
    return new AccountGroup( //
 | 
			
		||||
        new AccountGroup.NameKey(name), //
 | 
			
		||||
        new AccountGroup.Id(c.nextAccountGroupId()), //
 | 
			
		||||
        uuid);
 | 
			
		||||
        uuid,
 | 
			
		||||
        TimeUtil.nowTs());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private SystemConfig initSystemConfig(ReviewDb db) throws OrmException {
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,7 @@ import java.util.concurrent.TimeUnit;
 | 
			
		||||
/** A version of the database schema. */
 | 
			
		||||
public abstract class SchemaVersion {
 | 
			
		||||
  /** The current schema version. */
 | 
			
		||||
  public static final Class<Schema_150> C = Schema_150.class;
 | 
			
		||||
  public static final Class<Schema_151> C = Schema_151.class;
 | 
			
		||||
 | 
			
		||||
  public static int getBinaryVersion() {
 | 
			
		||||
    return guessVersion(C);
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,65 @@
 | 
			
		||||
// Copyright (C) 2017 The Android Open Source Project
 | 
			
		||||
//
 | 
			
		||||
// 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 com.google.gerrit.server.schema;
 | 
			
		||||
 | 
			
		||||
import com.google.common.annotations.VisibleForTesting;
 | 
			
		||||
import com.google.common.collect.Streams;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.AccountGroup;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit.Key;
 | 
			
		||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
			
		||||
import com.google.gwtorm.server.OrmException;
 | 
			
		||||
import com.google.gwtorm.server.ResultSet;
 | 
			
		||||
import com.google.inject.Inject;
 | 
			
		||||
import com.google.inject.Provider;
 | 
			
		||||
import java.sql.Timestamp;
 | 
			
		||||
import java.time.Instant;
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
import java.time.Month;
 | 
			
		||||
import java.time.ZoneOffset;
 | 
			
		||||
import java.util.Comparator;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
 | 
			
		||||
/** A schema which adds the 'created on' field to groups. */
 | 
			
		||||
public class Schema_151 extends SchemaVersion {
 | 
			
		||||
  @VisibleForTesting
 | 
			
		||||
  static final Instant AUDIT_CREATION_INSTANT =
 | 
			
		||||
      LocalDateTime.of(2009, Month.JUNE, 8, 19, 31).toInstant(ZoneOffset.UTC);
 | 
			
		||||
 | 
			
		||||
  @Inject
 | 
			
		||||
  protected Schema_151(Provider<Schema_150> prior) {
 | 
			
		||||
    super(prior);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException {
 | 
			
		||||
    List<AccountGroup> accountGroups = db.accountGroups().all().toList();
 | 
			
		||||
    for (AccountGroup accountGroup : accountGroups) {
 | 
			
		||||
      ResultSet<AccountGroupMemberAudit> groupMemberAudits =
 | 
			
		||||
          db.accountGroupMembersAudit().byGroup(accountGroup.getId());
 | 
			
		||||
      Optional<Timestamp> firstTimeMentioned =
 | 
			
		||||
          Streams.stream(groupMemberAudits)
 | 
			
		||||
              .map(AccountGroupMemberAudit::getKey)
 | 
			
		||||
              .map(Key::getAddedOn)
 | 
			
		||||
              .min(Comparator.naturalOrder());
 | 
			
		||||
      Timestamp createdOn =
 | 
			
		||||
          firstTimeMentioned.orElseGet(() -> Timestamp.from(AUDIT_CREATION_INSTANT));
 | 
			
		||||
 | 
			
		||||
      accountGroup.setCreatedOn(createdOn);
 | 
			
		||||
    }
 | 
			
		||||
    db.accountGroups().update(accountGroups);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,177 @@
 | 
			
		||||
// Copyright (C) 2017 The Android Open Source Project
 | 
			
		||||
//
 | 
			
		||||
// 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 com.google.gerrit.server.schema;
 | 
			
		||||
 | 
			
		||||
import static com.google.common.truth.Truth.assertThat;
 | 
			
		||||
 | 
			
		||||
import com.google.common.collect.ImmutableList;
 | 
			
		||||
import com.google.gerrit.common.TimeUtil;
 | 
			
		||||
import com.google.gerrit.extensions.api.groups.GroupInput;
 | 
			
		||||
import com.google.gerrit.extensions.common.GroupInfo;
 | 
			
		||||
import com.google.gerrit.extensions.restapi.TopLevelResource;
 | 
			
		||||
import com.google.gerrit.lifecycle.LifecycleManager;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Account;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.AccountGroup;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.AccountGroup.Id;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
 | 
			
		||||
import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
			
		||||
import com.google.gerrit.server.CurrentUser;
 | 
			
		||||
import com.google.gerrit.server.IdentifiedUser;
 | 
			
		||||
import com.google.gerrit.server.account.AccountManager;
 | 
			
		||||
import com.google.gerrit.server.account.AuthRequest;
 | 
			
		||||
import com.google.gerrit.server.group.CreateGroup;
 | 
			
		||||
import com.google.gerrit.server.util.RequestContext;
 | 
			
		||||
import com.google.gerrit.server.util.ThreadLocalRequestContext;
 | 
			
		||||
import com.google.gerrit.testutil.InMemoryDatabase;
 | 
			
		||||
import com.google.gerrit.testutil.InMemoryModule;
 | 
			
		||||
import com.google.gwtorm.server.OrmException;
 | 
			
		||||
import com.google.gwtorm.server.ResultSet;
 | 
			
		||||
import com.google.gwtorm.server.SchemaFactory;
 | 
			
		||||
import com.google.gwtorm.server.StatementExecutor;
 | 
			
		||||
import com.google.inject.Guice;
 | 
			
		||||
import com.google.inject.Inject;
 | 
			
		||||
import com.google.inject.Injector;
 | 
			
		||||
import com.google.inject.Provider;
 | 
			
		||||
import com.google.inject.util.Providers;
 | 
			
		||||
import java.sql.Timestamp;
 | 
			
		||||
import java.time.Instant;
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
import java.time.Month;
 | 
			
		||||
import java.time.ZoneOffset;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import org.junit.After;
 | 
			
		||||
import org.junit.Before;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
 | 
			
		||||
public class Schema_150_to_151_Test {
 | 
			
		||||
  @Inject private AccountManager accountManager;
 | 
			
		||||
  @Inject private IdentifiedUser.GenericFactory userFactory;
 | 
			
		||||
  @Inject private SchemaFactory<ReviewDb> schemaFactory;
 | 
			
		||||
  @Inject private SchemaCreator schemaCreator;
 | 
			
		||||
  @Inject private ThreadLocalRequestContext requestContext;
 | 
			
		||||
  @Inject private Schema_151 schema151;
 | 
			
		||||
  @Inject private CreateGroup.Factory createGroupFactory;
 | 
			
		||||
 | 
			
		||||
  // Only for use in setting up/tearing down injector.
 | 
			
		||||
  @Inject private InMemoryDatabase inMemoryDatabase;
 | 
			
		||||
 | 
			
		||||
  private LifecycleManager lifecycle;
 | 
			
		||||
  private ReviewDb db;
 | 
			
		||||
 | 
			
		||||
  @Before
 | 
			
		||||
  public void setUp() throws Exception {
 | 
			
		||||
    Injector injector = Guice.createInjector(new InMemoryModule());
 | 
			
		||||
    injector.injectMembers(this);
 | 
			
		||||
    lifecycle = new LifecycleManager();
 | 
			
		||||
    lifecycle.add(injector);
 | 
			
		||||
    lifecycle.start();
 | 
			
		||||
 | 
			
		||||
    try (ReviewDb underlyingDb = inMemoryDatabase.getDatabase().open()) {
 | 
			
		||||
      schemaCreator.create(underlyingDb);
 | 
			
		||||
    }
 | 
			
		||||
    db = schemaFactory.open();
 | 
			
		||||
    Account.Id userId = accountManager.authenticate(AuthRequest.forUser("user")).getAccountId();
 | 
			
		||||
    IdentifiedUser user = userFactory.create(userId);
 | 
			
		||||
 | 
			
		||||
    requestContext.setContext(
 | 
			
		||||
        new RequestContext() {
 | 
			
		||||
          @Override
 | 
			
		||||
          public CurrentUser getUser() {
 | 
			
		||||
            return user;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          @Override
 | 
			
		||||
          public Provider<ReviewDb> getReviewDbProvider() {
 | 
			
		||||
            return Providers.of(db);
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @After
 | 
			
		||||
  public void tearDown() {
 | 
			
		||||
    if (lifecycle != null) {
 | 
			
		||||
      lifecycle.stop();
 | 
			
		||||
    }
 | 
			
		||||
    requestContext.setContext(null);
 | 
			
		||||
    if (db != null) {
 | 
			
		||||
      db.close();
 | 
			
		||||
    }
 | 
			
		||||
    InMemoryDatabase.drop(inMemoryDatabase);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Test
 | 
			
		||||
  public void createdOnIsPopulatedForGroupsCreatedAfterAudit() throws Exception {
 | 
			
		||||
    Timestamp testStartTime = TimeUtil.nowTs();
 | 
			
		||||
    AccountGroup.Id groupId = createGroup("Group for schema migration");
 | 
			
		||||
    setCreatedOnToVeryOldTimestamp(groupId);
 | 
			
		||||
 | 
			
		||||
    schema151.migrateData(db, new TestUpdateUI());
 | 
			
		||||
 | 
			
		||||
    AccountGroup group = db.accountGroups().get(groupId);
 | 
			
		||||
    assertThat(group.getCreatedOn()).isAtLeast(testStartTime);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Test
 | 
			
		||||
  public void createdOnIsPopulatedForGroupsCreatedBeforeAudit() throws Exception {
 | 
			
		||||
    AccountGroup.Id groupId = createGroup("Ancient group for schema migration");
 | 
			
		||||
    setCreatedOnToVeryOldTimestamp(groupId);
 | 
			
		||||
    removeAuditEntriesFor(groupId);
 | 
			
		||||
 | 
			
		||||
    schema151.migrateData(db, new TestUpdateUI());
 | 
			
		||||
 | 
			
		||||
    AccountGroup group = db.accountGroups().get(groupId);
 | 
			
		||||
    assertThat(group.getCreatedOn()).isEqualTo(Timestamp.from(Schema_151.AUDIT_CREATION_INSTANT));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private AccountGroup.Id createGroup(String name) throws Exception {
 | 
			
		||||
    GroupInput groupInput = new GroupInput();
 | 
			
		||||
    groupInput.name = name;
 | 
			
		||||
    GroupInfo groupInfo =
 | 
			
		||||
        createGroupFactory.create(name).apply(TopLevelResource.INSTANCE, groupInput);
 | 
			
		||||
    return new Id(groupInfo.groupId);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private void setCreatedOnToVeryOldTimestamp(Id groupId) throws OrmException {
 | 
			
		||||
    AccountGroup group = db.accountGroups().get(groupId);
 | 
			
		||||
    Instant instant = LocalDateTime.of(1800, Month.JANUARY, 1, 0, 0).toInstant(ZoneOffset.UTC);
 | 
			
		||||
    group.setCreatedOn(Timestamp.from(instant));
 | 
			
		||||
    db.accountGroups().update(ImmutableList.of(group));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private void removeAuditEntriesFor(AccountGroup.Id groupId) throws Exception {
 | 
			
		||||
    ResultSet<AccountGroupMemberAudit> groupMemberAudits =
 | 
			
		||||
        db.accountGroupMembersAudit().byGroup(groupId);
 | 
			
		||||
    db.accountGroupMembersAudit().delete(groupMemberAudits);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static class TestUpdateUI implements UpdateUI {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void message(String msg) {}
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean yesno(boolean def, String msg) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean isBatch() {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void pruneSchema(StatementExecutor e, List<String> pruneList) throws OrmException {}
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user