Пример #1
0
  public EvolveStats evolve(EvolveConfig config) throws DatabaseException {

    checkOpen();
    List<Format> toEvolve = new ArrayList<Format>();
    Set<String> configToEvolve = config.getClassesToEvolve();
    if (configToEvolve.isEmpty()) {
      catalog.getEntityFormats(toEvolve);
    } else {
      for (String name : configToEvolve) {
        Format format = catalog.getFormat(name);
        if (format == null) {
          throw new IllegalArgumentException("Class to evolve is not persistent: " + name);
        }
        if (!format.isEntity()) {
          throw new IllegalArgumentException("Class to evolve is not an entity class: " + name);
        }
        toEvolve.add(format);
      }
    }

    EvolveEvent event = EvolveInternal.newEvent();
    for (Format format : toEvolve) {
      if (format.getEvolveNeeded()) {
        evolveIndex(format, event, config.getEvolveListener());
        format.setEvolveNeeded(false);
        catalog.flush();
      }
    }

    return event.getStats();
  }
 /** See Store.refresh. */
 void refresh(final PersistCatalog newCatalog) {
   catalog = newCatalog;
   entityFormat = newCatalog.getFormat(entityFormat.getClassName());
   if (keyAssigner != null) {
     keyAssigner.refresh(newCatalog);
   }
 }
  /**
   * Returns the format for the given entity and validates it, throwing an exception if it is
   * invalid for this binding.
   */
  private Format getValidFormat(Object entity) throws RefreshException {

    /* A null entity is not allowed. */
    if (entity == null) {
      throw new IllegalArgumentException("An entity may not be null");
    }

    /*
     * Get the format.  getFormat throws IllegalArgumentException if the
     * class is not persistent.
     */
    Format format;
    if (rawAccess) {
      if (!(entity instanceof RawObject)) {
        throw new IllegalArgumentException("Entity must be a RawObject");
      }
      format = (Format) ((RawObject) entity).getType();
    } else {
      format = catalog.getFormat(entity.getClass(), true /*checkEntitySubclassIndexes*/);
    }

    /* Check that the entity class/subclass is valid for this binding. */
    if (format.getEntityFormat() != entityFormat) {
      throw new IllegalArgumentException(
          "The entity class ("
              + format.getClassName()
              + ") must be this entity class or a subclass of it: "
              + entityFormat.getClassName());
    }

    return format;
  }
Пример #4
0
 @Override
 public Set<String> getKnownClasses() {
   if (knownClasses == null) {
     knownClasses = catalog.getModelClasses();
   }
   return knownClasses;
 }
  /**
   * This method is always called before writing an entity. If a refresh is needed, we detect that
   * here.
   */
  private void objectToDataInternal(final Object entity, final DatabaseEntry data)
      throws RefreshException {

    Format format = getValidFormat(entity);
    /* Before a write, check whether a refresh is needed. [#16655] */
    catalog.checkWriteInReplicaUpgradeMode();
    writeEntity(format, catalog, entity, data, rawAccess);
  }
Пример #6
0
 @Override
 public EntityMetadata getEntityMetadata(String className) {
   EntityMetadata metadata = null;
   Format format = catalog.getFormat(className);
   if (format != null && format.isCurrentVersion()) {
     metadata = format.getEntityMetadata();
   }
   return metadata;
 }
Пример #7
0
  public synchronized void close() throws DatabaseException {

    checkOpen();
    DatabaseException firstException = null;
    try {
      if (rawAccess) {
        boolean allClosed = catalog.close();
        assert allClosed;
      } else {
        synchronized (catalogPool) {
          Map<String, PersistCatalog> catalogMap = catalogPool.get(env);
          assert catalogMap != null;
          if (catalog.close()) {
            /* Remove when the reference count goes to zero. */
            catalogMap.remove(storeName);
          }
        }
      }
      catalog = null;
    } catch (DatabaseException e) {
      if (firstException == null) {
        firstException = e;
      }
    }
    firstException = closeDb(sequenceDb, firstException);
    for (SecondaryIndex index : secIndexMap.values()) {
      firstException = closeDb(index.getDatabase(), firstException);
      firstException = closeDb(index.getKeysDatabase(), firstException);
    }
    for (PrimaryIndex index : priIndexMap.values()) {
      firstException = closeDb(index.getDatabase(), firstException);
    }
    if (firstException != null) {
      throw firstException;
    }
  }
Пример #8
0
  public Store(Environment env, String storeName, StoreConfig config, boolean rawAccess)
      throws DatabaseException {

    this.env = env;
    this.storeName = storeName;
    this.rawAccess = rawAccess;

    if (env == null || storeName == null) {
      throw new NullPointerException("env and storeName parameters must not be null");
    }
    if (config != null) {
      model = config.getModel();
      mutations = config.getMutations();
    }
    if (config == null) {
      storeConfig = StoreConfig.DEFAULT;
    } else {
      storeConfig = config.cloneConfig();
    }

    storePrefix = NAME_PREFIX + storeName + NAME_SEPARATOR;
    priIndexMap = new HashMap<String, PrimaryIndex>();
    secIndexMap = new HashMap<String, SecondaryIndex>();
    priConfigMap = new HashMap<String, DatabaseConfig>();
    secConfigMap = new HashMap<String, SecondaryConfig>();
    keyBindingMap = new HashMap<String, PersistKeyBinding>();
    sequenceMap = new HashMap<String, Sequence>();
    sequenceConfigMap = new HashMap<String, SequenceConfig>();
    deferredWriteDatabases = new IdentityHashMap<Database, Object>();

    if (rawAccess) {
      /* Open a read-only catalog that uses the stored model. */
      if (model != null) {
        throw new IllegalArgumentException("A model may not be specified when opening a RawStore");
      }
      DatabaseConfig dbConfig = new DatabaseConfig();
      dbConfig.setReadOnly(true);
      dbConfig.setTransactional(storeConfig.getTransactional());
      catalog =
          new PersistCatalog(
              null,
              env,
              storePrefix,
              storePrefix + CATALOG_DB,
              dbConfig,
              model,
              mutations,
              rawAccess,
              this);
    } else {
      /* Open the shared catalog that uses the current model. */
      synchronized (catalogPool) {
        Map<String, PersistCatalog> catalogMap = catalogPool.get(env);
        if (catalogMap == null) {
          catalogMap = new HashMap<String, PersistCatalog>();
          catalogPool.put(env, catalogMap);
        }
        catalog = catalogMap.get(storeName);
        if (catalog != null) {
          catalog.openExisting();
        } else {
          Transaction txn = null;
          if (storeConfig.getTransactional() && env.getThreadTransaction() == null) {
            txn = env.beginTransaction(null, null);
          }
          boolean success = false;
          try {
            DatabaseConfig dbConfig = new DatabaseConfig();
            dbConfig.setAllowCreate(storeConfig.getAllowCreate());
            dbConfig.setReadOnly(storeConfig.getReadOnly());
            dbConfig.setTransactional(storeConfig.getTransactional());
            catalog =
                new PersistCatalog(
                    txn,
                    env,
                    storePrefix,
                    storePrefix + CATALOG_DB,
                    dbConfig,
                    model,
                    mutations,
                    rawAccess,
                    this);
            catalogMap.put(storeName, catalog);
            success = true;
          } finally {
            if (txn != null) {
              if (success) {
                txn.commit();
              } else {
                txn.abort();
              }
            }
          }
        }
      }
    }

    /* Get the merged mutations from the catalog. */
    mutations = catalog.getMutations();

    /*
     * If there is no model parameter, use the default or stored model
     * obtained from the catalog.
     */
    model = catalog.getResolvedModel();

    /*
     * Give the model a reference to the catalog to fully initialize the
     * model.  Only then may we initialize the Converter mutations, which
     * themselves may call model methods and expect the model to be fully
     * initialized.
     */
    ModelInternal.setCatalog(model, catalog);
    for (Converter converter : mutations.getConverters()) {
      converter.getConversion().initialize(model);
    }

    /*
     * For each existing entity with a relatedEntity reference, create an
     * inverse map (back pointer) from the class named in the relatedEntity
     * to the class containing the secondary key.  This is used to open the
     * class containing the secondary key whenever we open the
     * relatedEntity class, to configure foreign key constraints. Note that
     * we do not need to update this map as new primary indexes are
     * created, because opening the new index will setup the foreign key
     * constraints. [#15358]
     */
    inverseRelatedEntityMap = new HashMap<String, Set<String>>();
    List<Format> entityFormats = new ArrayList<Format>();
    catalog.getEntityFormats(entityFormats);
    for (Format entityFormat : entityFormats) {
      EntityMetadata entityMeta = entityFormat.getEntityMetadata();
      for (SecondaryKeyMetadata secKeyMeta : entityMeta.getSecondaryKeys().values()) {
        String relatedClsName = secKeyMeta.getRelatedEntity();
        if (relatedClsName != null) {
          Set<String> inverseClassNames = inverseRelatedEntityMap.get(relatedClsName);
          if (inverseClassNames == null) {
            inverseClassNames = new HashSet<String>();
            inverseRelatedEntityMap.put(relatedClsName, inverseClassNames);
          }
          inverseClassNames.add(entityMeta.getClassName());
        }
      }
    }
  }
Пример #9
0
 public void dumpCatalog() {
   catalog.dump();
 }