Грааль ограниченное создание таблицы - PullRequest
4 голосов
/ 14 октября 2010

Я бы хотел использовать функцию Grails для создания / обновления таблиц базы данных на ограниченной основе. В частности, я бы хотел, чтобы Grails управлял некоторыми таблицами, но не всеми.

Есть ли способ ограничить таблицы, управляемые Grails, или это предложение "все или ничего"?

Ответы [ 2 ]

11 голосов
/ 14 октября 2010

В целом это все или ничего, поскольку Grails использует функциональность Hibernate HBM2DDL. Но вы можете перехватить процесс, используя пользовательский подкласс конфигурации. Вот пример, который расширяет GrailsAnnotationConfiguration и переопределяет все три метода генерации SQL:

package com.yourcompany.yourapp;

import java.util.ArrayList;
import java.util.List;

import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration;
import org.hibernate.HibernateException;
import org.hibernate.dialect.Dialect;
import org.hibernate.tool.hbm2ddl.DatabaseMetadata;

public class MyConfiguration extends GrailsAnnotationConfiguration {

   private static final String[] IGNORE_NAMES = { "foo", "bar" };

   @Override
   public String[] generateDropSchemaScript(Dialect dialect) throws HibernateException {
      return prune(super.generateDropSchemaScript(dialect));
   }

   @Override
   public String[] generateSchemaCreationScript(Dialect dialect) throws HibernateException {
      return prune(super.generateSchemaCreationScript(dialect));
   }

   @Override
   public String[] generateSchemaUpdateScript(Dialect dialect, DatabaseMetadata databaseMetadata)
         throws HibernateException {
      return prune(super.generateSchemaUpdateScript(dialect, databaseMetadata));
   }

   private String[] prune(String[] script) {
      List<String> pruned = new ArrayList<String>();
      for (String command : script) {
         for (String ignoreName : IGNORE_NAMES) {
            if (!command.toLowerCase().contains(" table " + ignoreName + " ")) {
               pruned.add(command);
            }
         }
      }
      return pruned.toArray(new String[pruned.size()]);
   }
}

Вам не нужно переопределять все три, например, Вы можете разрешить создавать, но удалять обновления.

Это регистрируется в grails-app / conf / DataSource.groovy:

dataSource {
   pooled = true
   driverClassName = ...
   username = ...
   password = ...
   configClass = com.yourcompany.yourapp.MyConfiguration
}

Обратите внимание, что класс должен быть написан на Java из-за проблемы с закрытыми методами в базовом классе, конфликтующими с методами, которые Groovy добавляет ко всем классам groovy.

2 голосов
/ 18 мая 2011

Спасибо за исправление, Стив. Я пересылаю исправление выше, но отформатировано для stackoverflow. Когда я впервые попробовал это, я упустил тот факт, что оригинальная if (! command.toLowerCase()...) изменила логику в исправлении как if (command.toLowerCase()...), что фактически сделало ее похожей на dbCreate = "create-drop" в моей конфигурации / DataSource. Groovy не имел никакого эффекта. Я даже работал с исходным кодом HTML с этой страницы, чтобы увидеть намеченные разрывы строк в коде, но все же пропустил этот жизненно важный фрагмент логики :-( Как только я получил это введенное правильно, он прекрасно работал.

private String[] prune(String[] script) {
    List<String> pruned = new ArrayList<String>();
    for (String command : script) {

        boolean ignore = false;

        for (String ignoreName : IGNORE_NAMES) {
            if (command.toLowerCase().contains(" table " + ignoreName.toLowerCase() + " ")) {
                ignore = true;
                break;
            }
        }    

        if (!ignore) {
            pruned.add(command);
        }
    }
    return pruned.toArray(new String[pruned.size()]);
}
...