Conditional Scala Play Evolutions

309 Views Asked by At

I would like to implement an evolution that applies only if a condition is met on a Scala Play framework application. The condition is that the application should be in a certain environment.

I have this evolution right now:

# payments SCHEMA

# --- !Ups

INSERT INTO table1 (id, provider_name, provider_country, provider_code, status, flag)
VALUES (10, 'XXXXX', 'XX', 'XXXXX', '1', '0');

# --- !Downs
DELETE FROM table2
WHERE id = 10;

I want the evolution to run if this condition is met

if(config.env == 'dev'){
   //execute evolution
}

How do I achieve this? Is this a function of the evolution or the application logic?

2

There are 2 best solutions below

0
wwkudu On

One approach might be to use a stored procedure in conjunction with a db-based app 'setting'. Assume your app had an appSetting table for storing app settings.

create table appSetting (
  name varchar(63) not null primary key, 
  value varchar(255)
) ;
-- insert into appSetting values ('environment','dev');

Then, something along the following lines would create a tmpLog table (or insert a value into table1) only if appSetting has a value of 'dev' for setting 'environment' at the time of running the evolution:

# --- !Ups
create procedure doEvolution31()
  begin
    declare environment varchar(31);;
    select value
      into environment
      from appSetting
    where name='environment'
    ;;
    if (environment='dev') then
      create table tmpLog (id int not null primary key, text varchar(255));;
      -- or INSERT INTO table1 (id, provider_name, provider_country, provider_code, status, flag) VALUES (10, 'XXXXX', 'XX', 'XXXXX', '1', '0');
    end if;;
  end
;
call doEvolution31();

# --- !Downs
drop procedure doEvolution31;
drop table if exists tmpLog;
-- or delete from table2 where id=10;

You don't mention which db you are using. The above is MYSQL syntax. There might be a way to get a config value into the stored proc, perhaps via some sbt magic, but I think we would use the above if we had such a requirement. (BTW The double semicolons are for escaping out a single semicolon so that individual statements of the procedures are not executed when the procedure is being created.)

0
Alexandr Sova On

Why do you need it at all? Don't you use separate db for different environments as it's being told at documentation? If you do - then you probably have different db configurations, probably at different files. That, probably, looks something like that:

# application.conf
db.default {
    driver=com.mysql.jdbc.Driver
    url="jdbc:mysql://localhost/playdb"
    username=playdbuser
    password="a strong password"
}
# dev.conf
db.dev {
    driver=com.mysql.jdbc.Driver
    url="jdbc:mysql://localhost/playdb"
    username=playdbuser
    password="a strong password"
}
# staging.conf
db.staging {
    driver=com.mysql.jdbc.Driver
    url="jdbc:mysql://localhost/playdb"
    username=playdbuser
    password="a strong password"
}
# prod.conf
db.prod {
    driver=com.mysql.jdbc.Driver
    url="jdbc:mysql://localhost/playdb"
    username=playdbuser
    password="a strong password"
}

Actually nothing stops you to make it the same db but don't - just use proper db per environment. Assuming you are using jdbc connector and PlayEvolutions plugin - just put your evolution to right directory and you'll achieve what you want. The other question is actually: "How to use proper db per environment?" And the answer is strongly depend on your choice of DI.