All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gwtorm.schema.RelationModel Maven / Gradle / Ivy

There is a newer version: 1.20
Show newest version
// Copyright 2008 Google Inc.
//
// 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.gwtorm.schema;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gwtorm.schema.sql.SqlDialect;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.PrimaryKey;
import com.google.gwtorm.server.Relation;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;

public abstract class RelationModel {
  protected String methodName;
  protected String relationName;
  protected Relation relation;
  protected final Map fieldsByFieldName;
  protected final Map columnsByColumnName;
  protected final SortedMap columnsById;
  protected KeyModel primaryKey;
  protected Collection queries;

  protected RelationModel() {
    fieldsByFieldName = Maps.newLinkedHashMap();
    columnsByColumnName = Maps.newLinkedHashMap();
    columnsById = Maps.newTreeMap();
    queries = Lists.newArrayList();
  }

  protected void initName(final String method, final Relation rel)
      throws OrmException {
    if (rel == null) {
      throw new OrmException("Method " + method + " is missing "
          + Relation.class.getName() + " annotation");
    }
    relation = rel;
    methodName = method;
    relationName = Util.any(relation.name(), Util.makeSqlFriendly(methodName));
  }

  protected void initColumns(final Collection allFields)
      throws OrmException {
    for (final ColumnModel field : allFields) {
      if (fieldsByFieldName.put(field.getFieldName(), field) != null) {
        throw new OrmException("Duplicate fields " + field.getFieldName());
      }
      if (columnsById.put(field.getColumnID(), field) != null) {
        throw new OrmException("Duplicate @Column id " + field.getColumnID()
            + " in " + field.getPathToFieldName());
      }

      if (field.isNested()) {
        for (final ColumnModel newCol : field.getAllLeafColumns()) {
          registerColumn(newCol);
        }
      } else {
        registerColumn(field);
      }
    }
  }

  private void registerColumn(final ColumnModel nc) throws OrmException {
    final ColumnModel name = columnsByColumnName.put(nc.getColumnName(), nc);
    if (name != null) {
      throw new OrmException("Duplicate columns " + nc.getColumnName() + " in "
          + getMethodName() + ":\n" + "prior " + name.getPathToFieldName()
          + "\n next  " + nc.getPathToFieldName());
    }
  }

  protected void initPrimaryKey(final String name, final PrimaryKey annotation)
      throws OrmException {
    if (primaryKey != null) {
      throw new OrmException("Duplicate primary key definitions");
    }

    final ColumnModel field = getField(annotation.value());
    if (field == null) {
      throw new OrmException("Field " + annotation.value() + " not in "
          + getEntityTypeClassName());
    }

    primaryKey = new KeyModel(name, field);
    for (final ColumnModel c : primaryKey.getAllLeafColumns()) {
      c.inPrimaryKey = true;
    }
  }

  protected void addQuery(final QueryModel q) throws OrmException {
    for (QueryModel e : queries) {
      if (e.getName().equals(q.getName())) {
        throw new OrmException("Duplicate query " + q.getName() //
            + " in " + getAccessInterfaceName());
      }
    }
    queries.add(q);
  }


  public String getMethodName() {
    return methodName;
  }

  public String getRelationName() {
    return relationName;
  }

  public int getRelationID() {
    return relation.id();
  }

  public Collection getDependentFields() {
    final ArrayList r = new ArrayList<>();
    for (final ColumnModel c : fieldsByFieldName.values()) {
      if (!c.rowVersion && (primaryKey == null || primaryKey.getField() != c)) {
        r.add(c);
      }
    }
    return r;
  }

  public Collection getDependentColumns() {
    final ArrayList r = new ArrayList<>();
    for (final ColumnModel c : columnsByColumnName.values()) {
      if (!c.inPrimaryKey && !c.rowVersion) {
        r.add(c);
      }
    }
    return r;
  }

  public Collection getRowVersionFields() {
    final ArrayList r = new ArrayList<>();
    for (final ColumnModel c : fieldsByFieldName.values()) {
      if (c.rowVersion) {
        r.add(c);
      }
    }
    return r;
  }

  public Collection getRowVersionColumns() {
    final ArrayList r = new ArrayList<>();
    for (final ColumnModel c : columnsByColumnName.values()) {
      if (c.rowVersion) {
        r.add(c);
      }
    }
    return r;
  }

  public KeyModel getPrimaryKey() {
    return primaryKey;
  }

  public Collection getPrimaryKeyColumns() {
    if (getPrimaryKey() != null) {
      return getPrimaryKey().getAllLeafColumns();
    }
    return Collections. emptyList();
  }

  public Collection getQueries() {
    return queries;
  }

  public Collection getColumns() {
    final ArrayList r = new ArrayList<>();
    r.addAll(getDependentColumns());
    r.addAll(getRowVersionColumns());
    r.addAll(getPrimaryKeyColumns());
    return r;
  }

  public Collection getFields() {
    return fieldsByFieldName.values();
  }

  public ColumnModel getField(final String name) {
    return fieldsByFieldName.get(name);
  }

  public ColumnModel getColumn(final String name) {
    return columnsByColumnName.get(name);
  }

  public String getCreateTableSql(final SqlDialect dialect) {
    final StringBuilder r = new StringBuilder();
    r.append("CREATE ");
    r.append(dialect.getTableTypeSql());
    r.append(" ");
    r.append(relationName);
    r.append(" (\n");

    for (final Iterator i = getColumns().iterator(); i.hasNext();) {
      final ColumnModel col = i.next();
      r.append(col.getColumnName());
      r.append(" ");
      r.append(dialect.getSqlTypeInfo(col).getSqlType(col, dialect));

      String check =
          dialect.getSqlTypeInfo(col).getCheckConstraint(col, dialect);
      if (check != null) {
        r.append(' ');
        r.append(check);
      }
      if (i.hasNext()) {
        r.append(",");
      }
      r.append("\n");
    }

    if (!getPrimaryKeyColumns().isEmpty()) {
      r.append(",PRIMARY KEY(");
      for (final Iterator i = getPrimaryKeyColumns().iterator(); i
          .hasNext();) {
        final ColumnModel col = i.next();
        r.append(col.getColumnName());
        if (i.hasNext()) {
          r.append(",");
        }
      }
      r.append(")\n");
    }

    r.append(")");
    dialect.appendCreateTableStorage(r, this);
    return r.toString();
  }

  public String getSelectSql(final SqlDialect dialect, final String tableAlias) {
    final StringBuilder r = new StringBuilder();
    r.append("SELECT ");
    for (final Iterator i = getColumns().iterator(); i.hasNext();) {
      final ColumnModel col = i.next();
      r.append(tableAlias);
      r.append('.');
      r.append(col.getColumnName());
      if (i.hasNext()) {
        r.append(",");
      }
    }
    r.append(" FROM ");
    r.append(relationName);
    r.append(' ');
    r.append(tableAlias);
    return r.toString();
  }

  public String getInsertOneSql(final SqlDialect dialect) {
    final StringBuilder r = new StringBuilder();
    r.append("INSERT INTO ");
    r.append(relationName);
    r.append("(");
    for (final Iterator i = getColumns().iterator(); i.hasNext();) {
      final ColumnModel col = i.next();
      r.append(col.getColumnName());
      if (i.hasNext()) {
        r.append(",");
      }
    }
    r.append(")VALUES(");
    int nth = 1;
    for (final Iterator i = getColumns().iterator(); i.hasNext();) {
      i.next();
      r.append(dialect.getParameterPlaceHolder(nth++));
      if (i.hasNext()) {
        r.append(",");
      }
    }
    r.append(")");
    return r.toString();
  }

  public String getUpdateOneSql(final SqlDialect dialect) {
    final StringBuilder r = new StringBuilder();
    r.append("UPDATE ");
    r.append(relationName);
    r.append(" SET ");
    List cols;
    int nth = 1;

    cols = new ArrayList<>();
    cols.addAll(getDependentColumns());
    cols.addAll(getRowVersionColumns());
    for (final Iterator i = cols.iterator(); i.hasNext();) {
      final ColumnModel col = i.next();
      r.append(col.getColumnName());
      r.append("=");
      r.append(dialect.getParameterPlaceHolder(nth++));
      if (i.hasNext()) {
        r.append(",");
      }
    }

    r.append(" WHERE ");
    cols = new ArrayList<>();
    cols.addAll(getPrimaryKeyColumns());
    cols.addAll(getRowVersionColumns());
    for (final Iterator i = cols.iterator(); i.hasNext();) {
      final ColumnModel col = i.next();
      r.append(col.getColumnName());
      r.append("=");
      r.append(dialect.getParameterPlaceHolder(nth++));
      if (i.hasNext()) {
        r.append(" AND ");
      }
    }
    return r.toString();
  }

  public String getDeleteOneSql(final SqlDialect dialect) {
    final StringBuilder r = new StringBuilder();
    r.append("DELETE FROM ");
    r.append(relationName);
    int nth = 1;
    r.append(" WHERE ");
    final List cols = new ArrayList<>();
    cols.addAll(getPrimaryKeyColumns());
    cols.addAll(getRowVersionColumns());
    for (final Iterator i = cols.iterator(); i.hasNext();) {
      final ColumnModel col = i.next();
      r.append(col.getColumnName());
      r.append("=");
      r.append(dialect.getParameterPlaceHolder(nth++));
      if (i.hasNext()) {
        r.append(" AND ");
      }
    }
    return r.toString();
  }

  public abstract String getAccessInterfaceName();

  public abstract String getEntityTypeClassName();

  @Override
  public String toString() {
    final StringBuilder r = new StringBuilder();
    r.append("Relation[\n");
    r.append("  method: " + getMethodName() + "\n");
    r.append("  table:  " + getRelationName() + "\n");
    r.append("  id:     " + getRelationID() + "\n");
    r.append("  access: " + getAccessInterfaceName() + "\n");
    r.append("  entity: " + getEntityTypeClassName() + "\n");
    r.append("]");
    return r.toString();
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy