Project

General

Profile

Enregistrer des tables dans la base de données

La base de données utilisée est une base de données embarquée H2.

Les modules peuvent modifier la base de données pour ajouter des tables et des contraintes sur la base de données. Pour cela, il faut créer une classe implémentant Schema et l'enregistrer dans le SchemaManager de la manière suivante :

Schema schema = new TestSchema();

Managers.getManager(ISchemaManager.class).registerSchema(schema);

En pratique, il est plus simple d'hériter d'AbstractSchema que directement de Schema. Voici les méthodes qu'il faut redéfinir en héritant d'AbstractSchema :

  • Version getVersion() : Retourne la version du schéma. Cela permet de gérer les mises à jour des schémas qui est géré par le manager
  • String getID() : Retourne l'identifiant unique du schéma. Veillez à donner un nom lié au module qui ne soit pas ensuite utilisé pour un autre schéma.
  • String[] getDependencies() : Retourne un tableau contenant tous les schémas dont dépend le schéma que vous implémentez
  • void install() : Installe le schéma. Cette méthode doit créer toutes les tables et index nécessaires dans la base de données.
  • void update(Version from) : Met à jour le schéma depuis la version passée en paramètre. Le paramètre vous permet de mettre à jour en fonction de ce qui a changé depuis la version spécifiée.
  • void importDataFromHSQL(Iterable<Insert> inserts) : Cette méthode ne vous sera pas utile. Elle ne concerne que les modules qui ont été créé avant le passage à la base de données H2.

Voici un example de schéma venant du module Movies :

/**
 * The database schema for the Movies Module.
 *
 * @author Baptiste Wicht
 */
public final class MoviesSchema extends AbstractSchema {
    private static final String ALTER_TABLE = "ALTER TABLE ";
    private static final String INSERT_INTO = "INSERT INTO ";
    private static final String CREATE_TABLE = "CREATE TABLE ";

    @Override
    public Version getVersion() {
        return new Version("1.2");
    }

    @Override
    public String getId() {
        return "Movies-Schema";
    }

    @Override
    public String[] getDependencies() {
        return new String[]{"PrimaryUtils-Schema"};
    }

    @Override
    public void install() {
        createDataTables();
        createReferentialIntegrityConstraints();
    }

    @Override
    public void update(Version from) {
        String fromVersion = from.getVersion();

        if ("1.0".equals(fromVersion) || "1.1".equals(fromVersion)) {
            if ("1.0".equals(fromVersion)) {
                createReferentialIntegrityConstraints();
            }

            correctUnicityConstraints();
            addInformationColumns();
        }
    }

    /**
     * Correct the unicity constraints.
     */
    private void correctUnicityConstraints() {
        update(ALTER_TABLE + IDaoMovies.TABLE + " DROP CONSTRAINT CONSTRAINT_INDEX_3F");
        update(ALTER_TABLE + IDaoMovies.TABLE + " ADD CONSTRAINT UNIQUE_FILE UNIQUE(FILE)");
    }

    /**
     * Add the informations column.
     */
    private void addInformationColumns() {
        update(ALTER_TABLE + IDaoMovies.TABLE + " ADD DURATION BIGINT");
        update(ALTER_TABLE + IDaoMovies.TABLE + " ADD RESOLUTION VARCHAR(11)");
        update(ALTER_TABLE + IDaoMovies.TABLE + " ADD IMAGE VARCHAR(150)");
        update(ALTER_TABLE + IDaoCategories.TABLE + " ADD THE_PARENT_FK INT");
        update(ALTER_TABLE + IDaoCategories.TABLE + " ADD FOREIGN KEY (THE_PARENT_FK) REFERENCES  " + IDaoCategories.TABLE + "  (ID) ON UPDATE SET NULL");
    }

    /**
     * Create the data tables.
     */
    private void createDataTables() {
        update(CREATE_TABLE + IDaoMovies.MOVIES_CATEGORIES_TABLE + " (THE_MOVIE_FK INT NOT NULL, THE_CATEGORY_FK INT NOT NULL)");
        update(CREATE_TABLE + IDaoCategories.TABLE + " (ID INT IDENTITY PRIMARY KEY, TITLE VARCHAR(100) NOT NULL UNIQUE, THE_PARENT_FK INT, THE_COLLECTION_FK INT NOT NULL)");
        update(CREATE_TABLE + IDaoMovies.TABLE + " (ID INT IDENTITY PRIMARY KEY, TITLE VARCHAR(100) NOT NULL, NOTE INT NULL, FILE VARCHAR(200) NOT NULL UNIQUE, DURATION BIGINT, RESOLUTION VARCHAR(11), IMAGE VARCHAR(150), THE_COLLECTION_FK INT NOT NULL)");

        update("CREATE INDEX MOVIES_IDX ON " + IDaoMovies.TABLE + "(ID)");
        update("CREATE INDEX MOVIE_CATEGORIES_IDX ON " + IDaoCategories.TABLE + "(ID)");
    }

    /**
     * Create the constraints to maintain a referential integrity in the database.
     */
    private void createReferentialIntegrityConstraints() {
        update(ALTER_TABLE + IDaoMovies.MOVIES_CATEGORIES_TABLE + " ADD FOREIGN KEY (THE_MOVIE_FK) REFERENCES  " + IDaoMovies.TABLE + "  (ID) ON UPDATE SET NULL");
        update(ALTER_TABLE + IDaoMovies.MOVIES_CATEGORIES_TABLE + " ADD FOREIGN KEY (THE_CATEGORY_FK) REFERENCES  " + IDaoCategories.TABLE + "  (ID) ON UPDATE SET NULL");
        update(ALTER_TABLE + IDaoCategories.TABLE + " ADD FOREIGN KEY (THE_COLLECTION_FK) REFERENCES  " + IDaoCollections.TABLE + "  (ID) ON UPDATE SET NULL");
        update(ALTER_TABLE + IDaoMovies.TABLE + " ADD FOREIGN KEY (THE_COLLECTION_FK) REFERENCES  " + IDaoCollections.TABLE + "  (ID) ON UPDATE SET NULL");
        update(ALTER_TABLE + IDaoCategories.TABLE + " ADD FOREIGN KEY (THE_PARENT_FK) REFERENCES  " + IDaoCategories.TABLE + "  (ID) ON UPDATE SET NULL");
    }

    @Override
    public void importDataFromHSQL(Iterable<Insert> inserts) {/* Not useful here */}
}

Il vous faut utiliser la méthode update() pour exécuter des opérations sur la base de données.