Rich eForm Migration

This page describes the migration of Indivica Rich eForms to Oscar eForms


Preface

Some Oscar sites have a different version of the eForm tables called richeform. This page describes how to convert the richeform to standard Oscar eforms.

Warning: Do NOT do this unless you are very comfortable with MySQL commands and procedures.  It is very easy to destroy your existing Oscar database with a single line.

 Document Version History

This document is copyright by Earl Wertheimer 2014 © under the Creative Commons Attribution-Share Alike 3.0 Unported License

 

 

The major difference is that the richeform does not have the .html code as part of the database. So in addition to converting the database data, the .html code has to be imported into the Oscar eform tables.

The different tables are:

richeform
richeform_instances
richeform_values

 

The following SQL scripts and procedure will help in the analysis and conversion of the richeform to eform.

Note: It contains many commands used to understand, analyse and restart the conversion procedure.

 

If you are converting from Indivica to Oscar, then the destination eform tables should be empty. That makes the process much easier.

 

I created a temporary table (ew_reform_html) to contain the eform html that has to be converted.

 

-- analyse existing data in richeform select r.rfid, rin.rfuuid, count(*), r.form_name, r.file_name, r.status
from richeform_instances rin
left join richeform r on rin.rfuuid = r.uuid
group by rin.rfuuid ;   
   
-- with x-ref (contains source html)
select r.rfid, rin.rfuuid, count(*), r.form_name, r.file_name, r.status, ew.rfid
from richeform_instances rin
left join richeform r on rin.rfuuid = r.uuid
left join ew_reform_html ew on rin.rfuuid = ew.uuid
group by rin.rfuuid ;   
   
   
select v.instanceid, count(*) from richeform_values v
left join richeform_instances i on v.instanceid = i.instanceid ;
 
select v.instanceid, v.demographic_no, count(*) from richeform_values v
left join richeform_instances i on v.instanceid = i.instanceid
group by v.instanceid, v.demographic_no ;
 
select val.instanceid, val.var_name, left(val.var_value,40) 
from richeform_values val
left join richeform_instances i on val.instanceid = i.instanceid
where i.rfuuid = ( select uuid from richeform where rfid = 61 )
order by val.instanceid, val.var_name
limit 100 ;
 
 
--eform info
select fid, form_name, file_name, subject, status, patient_independent from eform ;
 
select ed.fid, count(*), ef.form_name, ef.file_name, length(ef.form_html), ef.subject, ef.status, ef.patient_independent  
from eform_data ed
left join eform ef on ed.fid = ef.fid
group by ed.fid ;
 
 
 
--create table to hold richeform html
delete from ew_reform_html ;
alter table ew_reform_html auto_increment = 1 ;
 
drop table ew_reform_html ;
 
create table ew_reform_html (
id         int(8) UNIQUE PRIMARY KEY auto_increment,
uuid       varchar(50),
rfid	     int(11),
form_html  mediumtext,
used       tinyint ) ;


 
--html in /var/lib/tomcat6/webapps/oscar/richeform/html
 
--WinSCP html files to Oscar /home/earlw/import
                        
                          

ls -l
copy screen to clipboard, column mode,
 
-- run client rich eform loading.  loads html into ew_reform_html
set sql_mode = 'NO_BACKSLASH_ESCAPES' ;
load data local infile '/home/earlw/import/07faae12-6baa-41ed-b8a1-edc80f34c336.html' into table ew_reform_html fields terminated by 'tsnbf' lines terminated by 'tsnbf' ( form_html ) set uuid = '07faae12-6baa-41ed-b8a1-edc80f34c336' ;
load data local infile '/home/earlw/import/richtextletter-orig-nofax.txt' into table ew_reform_html fields terminated by 'tsnbf' lines terminated by 'tsnbf' ( form_html ) set uuid = 'richtextletter-orig-nofax' ;
 
-- flag records that are used
update ew_reform_html set used = 1
where uuid in ( select distinct rfuuid from richeform_instances ) ;
 
-- keep richeform.rfid
update ew_reform_html set rfid = ( select rfid from richeform where ew_reform_html.uuid = richeform.uuid ) ;
 
select ew.id, ew.rfid, ew.uuid, ew.used from ew_reform_html ew join richeform r on ew.uuid = r.uuid ;
 
 
 
-- check x-ref
select r.rfid, r.form_name, r.file_name, r.uuid, ew.uuid from richeform r left join ew_reform_html ew on r.uuid = ew.uuid ;
 
-- backup eform data
create table bu_eform like eform ;
insert into bu_eform select * from eform ;
create table bu_eform_data like eform_data ;
insert into bu_eform_data select * from eform_data ;
create table bu_eform_values like eform_values ;
insert into bu_eform_values select * from eform_values ;
 
mysqldump --add-drop-table -uroot -p<password> oscar_mcmaster > oscar_20130127.sql
 
 
-- build eform from richeform and ew_reform_html
insert into eform (
form_name, file_name, subject, form_date, form_time, form_creator, status, form_html, patient_independent )
( select 
r.form_name, r.file_name, r.subject, r.form_date, r.form_time, r.form_creator, r.status, ew.form_html, r.patient_independent
from richeform r
left join ew_reform_html ew on r.uuid = ew.uuid
where r.status = 1 
and ew.used = 1 ) ;
 
 
 
-- restore eform data (for restarts & testing)
delete from eform ;
alter table eform auto_increment = 1 ;
delete from eform_data ;
alter table eform_data auto_increment = 1 ;
delete from eform_values ;
alter table eform_values auto_increment = 1 ;
 
 
call pr_richeform2eform;
 
-- restore (if needed)
insert into eform select * from bu_eform ;
insert into eform_data select * from bu_eform_data ;
insert into eform_values select * from bu_eform_values ;
 
 
select count(*) from richeform ;
select count(*) from richeform_instances ;
select count(*) from richeform_values ;
 
select count(*) from eform ;
select count(*) from eform_data ;
select count(*) from eform_values ;
 
select uuid from richeform where form_name = 'Rich Text Letter' and status = 1 ;
select instanceid, demographic_no from richeform_instances where rfuuid IN ( select uuid from richeform where form_name = 'Rich Text Letter' and status = 1 ) ;
select instanceid from richeform_instances where demographic_no = 4154 and rfuuid IN ( select uuid from richeformwhere form_name = 'CPP' and status = 1 ) ;
select * from richeform_values where instanceid = ( select instanceid from richeform_instances where rfuuid = ( select uuid from richeform where form_name = 'CHF Flowsheet' and status = 1 ) ) ;
 
select fid from eform where form_name = 'Rich Text Letter' and status = 1 ;
select fdid, form_date from eform_data where demographic_no = 4154 and fid = ( select fid from eform where form_name = 'Surface Anatomy' and status = 1 ) ;
select * from eform_values where fdid = ( select DISTINCT fdid from eform_data where demographic_no = 4154 and fid = ( select fid from eform where form_name = 'Surface Anatomy' and status = 1 ) ) ;

 Stored procedure: 

DROP PROCEDURE IF EXISTS `pr_richeform2eform` ;
delimiter $$
CREATE PROCEDURE `pr_richeform2eform`() 
BEGIN 
-- transfer data from Indivica richeform to Oscar eform

-- call pr_richeform2eform;
DECLARE v_done INT DEFAULT 0; 
DECLARE v_MaxID, v_count, v_recs, v_eform_fid, v_eform_data_fdid INT ;
-- declare data vars
DECLARE d_instanceid, d_demographic_no, d_status, d_patient_independent INT;
DECLARE d_form_date     date ;
DECLARE d_form_time     time ;
DECLARE d_var_name      varchar(30);
DECLARE d_rfuuid        varchar(50);
DECLARE d_subject, d_form_provider, d_form_name     varchar(255);
DECLARE d_var_value     text;
-- declare temp vars
DECLARE t_instanceid, t_last_instanceid, t_demographic_no, t_rfid  INT;
DECLARE t_file_name, t_form_creator             varchar(255);
DECLARE t_form_html, t_Str, t_Fld               mediumtext ;
DECLARE t_Loc, t_Pos, t_Beg, t_End, t_Len       INT ;
DECLARE cur1 CURSOR FOR 
   SELECT val.instanceid, val.var_name, val.var_value, val.demographic_no,
          ins.rfuuid, ins.demographic_no, ins.status, ins.subject, ins.form_date, ins.form_time, 
          ins.patient_independent, ins.form_provider, ins.form_name
     FROM richeform_values val
-- lookup richeform_instances
     JOIN richeform_instances ins on val.instanceid = ins.instanceid
 ORDER BY ins.instanceid ;
-- Surface Anatomy, D# 4154     
-- WHERE ins.instanceid = 2600
-- CPP, D# 4154     
-- WHERE ins.instanceid = 2601
-- WHERE ins.demographic_no = 4763
-- lookup x-ref for html
-- LEFT JOIN ew_reform_html ew on in.rfuuid = ew.uuid
-- lookup warning types
-- left join richeform_values val on in.instanceid = val.instanceid
    
DECLARE CONTINUE HANDLER FOR NOT FOUND 
SET v_done = 1; 
-- get count
SELECT max(instanceid) INTO v_MaxID FROM richeform_values ;
SET v_count = 99999 ; 
SET t_last_instanceid = -1 ;
  
OPEN cur1; 
    read_loop: 
    LOOP FETCH cur1 INTO
        d_instanceid, d_var_name, d_var_value, d_demographic_no,
        d_rfuuid, t_demographic_no, d_status, d_subject, d_form_date, d_form_time, 
        d_patient_independent, d_form_provider, d_form_name ;
        
    IF v_done THEN LEAVE read_loop; END IF; 
    set v_count = v_count + 1 ;  
    IF v_count > 1000 THEN
        SELECT concat( ' Working on InstanceID ', d_instanceid, ' of ', v_MaxID ) ;
        SET v_count = 0 ;
    END IF;
-- new instanceid.  Do header processing    
    IF t_last_instanceid <> d_instanceid THEN
        SET t_last_instanceid = d_instanceid ;
-- lookup richeform.  MUST exist!
        SELECT rfid, file_name, form_creator, count(*) INTO t_rfid, t_file_name, t_form_creator, v_recs 
            FROM richeform WHERE uuid = d_rfuuid ;
-- lookup ew_reform_html for form_html.  MUST exist!
        SELECT form_html INTO t_form_html FROM ew_reform_html where uuid = d_rfuuid ;  
      
-- check if eform exists.  If not, create it
        SELECT fid, count(*) INTO v_eform_fid, v_recs FROM eform WHERE form_name = d_form_name ;
        IF v_recs = 0 THEN
            INSERT INTO eform (
                form_name, file_name, subject, form_date, form_time, form_creator, 
                status, form_html, patient_independent )
            VALUES (
                d_form_name, t_file_name, d_subject, d_form_date, d_form_time, t_form_creator, 
                d_status, t_form_html, d_patient_independent );
        
            SELECT LAST_INSERT_ID() INTO v_eform_fid ;
        END IF; 
-- update src="${oscar_image_path}
        WHILE LOCATE( 'src="${oscar_image_path}', t_form_html ) > 0 DO
            SET t_Loc = LOCATE( 'src="${oscar_image_path}', t_form_html ) ;
            IF t_Loc > 0 then 
                SET t_Pos = t_Loc + 4 ;
                SET t_Str = '../eform/displayImage.do?imagefile=' ;
                SET t_form_html = concat( left( t_form_html, t_Pos) , t_Str, mid( t_Form_html, t_Loc + 24 ) ) ;
            END IF;    
        END WHILE;
        
-- update <form action=
        SET t_Loc = LOCATE( '<form ', t_form_html ) ;
        IF t_Loc > 0 THEN
            SET t_Pos = t_Loc + 5 ;
            SET t_Str = CONCAT( 'action="../eform/addEForm.do?efmid=', v_eform_fid, '&efmdemographic_no=', d_demographic_no, 
                                '&efmprovider_no=', d_form_provider, '&eform_link=null" ' ) ;
            SET t_form_html = concat( left( t_form_html, t_Pos) , t_Str, mid( t_Form_html, t_Pos + 1 ) ) ;
        END IF;    
-- write eform_data 
        INSERT INTO eform_data (
            fid, form_name, subject, demographic_no, status, form_date, form_time, 
            form_provider, form_data, patient_independent )
        VALUES (
            v_eform_fid, d_form_name, d_subject, d_demographic_no, d_status, d_form_date, d_form_time, 
            d_form_provider, t_form_html, d_patient_independent );
            
        SELECT LAST_INSERT_ID() INTO v_eform_data_fdid ;
        
-- TESTING:  SELECT concat( 'html=', t_form_html ) ;
        
    END IF;
-- special fields:  subject, SubmitButton, uuid
-- find var_name in html and insert var_value    
    SET t_Fld = CONCAT( 'name="', d_var_name, '"' ) ;
    SET t_Loc = LOCATE(  t_Fld, t_form_html );
    
    IF d_var_name = 'SubmitButton' THEN SET t_Loc = 0 ;  END IF ;
    
    IF t_Loc > 0 THEN
        SET t_Str = SUBSTRING_INDEX( LEFT( t_form_html,t_Loc), '<', -1 );
        SET t_Beg = t_Loc - LENGTH(t_Str) ;
        SET t_End = LOCATE( '>', MID(t_form_html,t_Loc)) + t_Loc - 1 ; 
        SET t_Len = t_End - t_Beg + 1 ;
        
-- TEST: SELECT concat( 't_Fld=', t_Fld, ' t_Str=', t_Str, ' t_Beg=', t_Beg, ' t_End=', t_End, ' t_Loc=', t_Loc, ' HTML=[', MID(t_form_html,t_Beg,t_Len), ']' ) ;
            
-- go back to < and find out type of field ( <textarea,     
        IF LOCATE( '<textarea', MID(t_form_html,t_Beg,t_Len)) > 0 THEN
-- put value after >
            SET t_form_html = concat( left( t_form_html, t_End) , d_var_value, mid( t_Form_html, t_End + 1 ) ) ;
        ELSE
            
            IF LOCATE( '<input', MID(t_form_html,t_Beg,t_Len)) > 0 THEN
            
-- if type="checkbox" before closing >
                IF LOCATE( 'type="checkbox"', MID(t_form_html,t_Beg,t_Len) ) > 0 THEN
-- move to end of name="d_var_name"
                    SET t_Pos = t_Loc + 7 + length( d_var_name ) ;
                    SET t_form_html = concat( left( t_form_html, t_Pos) , 'checked ', mid( t_Form_html, t_Pos + 1 ) ) ;
                ELSE
                    SET t_Pos = t_Loc + 7 + length( d_var_name ) ;
                    SET t_form_html = concat( left( t_form_html, t_Pos) , 'value="', d_var_value, '" ', mid( t_Form_html, t_Pos + 1 ) ) ;
                END IF ;    
            END IF ;
        END IF ;
        
        UPDATE eform_data SET form_data = t_form_html WHERE fdid = v_eform_data_fdid ;    
            
        INSERT INTO eform_values (
            fdid, fid, demographic_no, var_name, var_value )
        VALUES (
            v_eform_data_fdid, v_eform_fid, d_demographic_no, d_var_name, d_var_value ) ;
            
    END IF ;
  
END LOOP; 
CLOSE cur1; 
END
$$
delimiter ;