001/*-
002 * #%L
003 * HAPI FHIR Server - SQL Migration
004 * %%
005 * Copyright (C) 2014 - 2024 Smile CDR, Inc.
006 * %%
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 * You may obtain a copy of the License at
010 *
011 *      http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 * #L%
019 */
020package ca.uhn.fhir.jpa.migrate.entity;
021
022import ca.uhn.fhir.jpa.migrate.taskdef.BaseTask;
023import ca.uhn.fhir.util.VersionEnum;
024import jakarta.persistence.Column;
025import jakarta.persistence.Entity;
026import jakarta.persistence.GeneratedValue;
027import jakarta.persistence.GenerationType;
028import jakarta.persistence.Id;
029import org.hibernate.annotations.GenericGenerator;
030import org.springframework.jdbc.core.PreparedStatementSetter;
031import org.springframework.jdbc.core.RowMapper;
032
033import java.util.Date;
034
035// Note even though we are using javax.persistence annotations here, we are managing these records outside of jpa
036// so these annotations are for informational purposes only
037@Entity
038public class HapiMigrationEntity {
039        public static final int VERSION_MAX_SIZE = 50;
040        public static final int DESCRIPTION_MAX_SIZE = 200;
041        public static final int TYPE_MAX_SIZE = 20;
042        public static final int SCRIPT_MAX_SIZE = 1000;
043        public static final int INSTALLED_BY_MAX_SIZE = 100;
044        public static final int CREATE_TABLE_PID = -1;
045        public static final String INITIAL_RECORD_DESCRIPTION = "<< HAPI FHIR Schema History table created >>";
046        public static final String INITIAL_RECORD_SCRIPT = "HAPI FHIR";
047
048        @Id
049        @GenericGenerator(
050                        name = "SEQ_FLY_HFJ_MIGRATION",
051                        strategy = "ca.uhn.fhir.jpa.model.dialect.HapiSequenceStyleGenerator")
052        @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_FLY_HFJ_MIGRATION")
053        @Column(name = "INSTALLED_RANK")
054        private Integer myPid;
055
056        @Column(name = "VERSION", length = VERSION_MAX_SIZE)
057        private String myVersion;
058
059        @Column(name = "DESCRIPTION", length = DESCRIPTION_MAX_SIZE)
060        private String myDescription;
061
062        @Column(name = "TYPE", length = TYPE_MAX_SIZE)
063        private String myType;
064
065        @Column(name = "SCRIPT", length = SCRIPT_MAX_SIZE)
066        private String myScript;
067
068        @Column(name = "CHECKSUM")
069        private Integer myChecksum;
070
071        @Column(name = "INSTALLED_BY", length = INSTALLED_BY_MAX_SIZE)
072        private String myInstalledBy;
073
074        @Column(name = "INSTALLED_ON")
075        private Date myInstalledOn;
076
077        @Column(name = "EXECUTION_TIME")
078        private Integer myExecutionTime;
079
080        @Column(name = "SUCCESS")
081        private Boolean mySuccess;
082
083        public static HapiMigrationEntity tableCreatedRecord() {
084                HapiMigrationEntity retVal = new HapiMigrationEntity();
085                retVal.setPid(CREATE_TABLE_PID);
086                retVal.setDescription(INITIAL_RECORD_DESCRIPTION);
087                retVal.setType("TABLE");
088                retVal.setScript(INITIAL_RECORD_SCRIPT);
089                retVal.setInstalledBy(VersionEnum.latestVersion().name());
090                retVal.setInstalledOn(new Date());
091                retVal.setExecutionTime(0);
092                retVal.setSuccess(true);
093                return retVal;
094        }
095
096        public Integer getPid() {
097                return myPid;
098        }
099
100        public void setPid(Integer thePid) {
101                myPid = thePid;
102        }
103
104        public String getVersion() {
105                return myVersion;
106        }
107
108        public void setVersion(String theVersion) {
109                myVersion = theVersion;
110        }
111
112        public String getDescription() {
113                return myDescription;
114        }
115
116        public void setDescription(String theDescription) {
117                myDescription = theDescription;
118        }
119
120        public String getType() {
121                return myType;
122        }
123
124        public void setType(String theType) {
125                myType = theType;
126        }
127
128        public String getScript() {
129                return myScript;
130        }
131
132        public void setScript(String theScript) {
133                myScript = theScript;
134        }
135
136        public Integer getChecksum() {
137                return myChecksum;
138        }
139
140        public void setChecksum(Integer theChecksum) {
141                myChecksum = theChecksum;
142        }
143
144        public String getInstalledBy() {
145                return myInstalledBy;
146        }
147
148        public void setInstalledBy(String theInstalledBy) {
149                myInstalledBy = theInstalledBy;
150        }
151
152        public Date getInstalledOn() {
153                return myInstalledOn;
154        }
155
156        public void setInstalledOn(Date theInstalledOn) {
157                myInstalledOn = theInstalledOn;
158        }
159
160        public Integer getExecutionTime() {
161                return myExecutionTime;
162        }
163
164        public void setExecutionTime(Integer theExecutionTime) {
165                myExecutionTime = theExecutionTime;
166        }
167
168        public Boolean getSuccess() {
169                return mySuccess;
170        }
171
172        public void setSuccess(Boolean theSuccess) {
173                mySuccess = theSuccess;
174        }
175
176        public static HapiMigrationEntity fromBaseTask(BaseTask theTask) {
177                HapiMigrationEntity retval = new HapiMigrationEntity();
178                retval.setVersion(theTask.getMigrationVersion());
179                retval.setDescription(theTask.getDescription());
180                retval.setChecksum(theTask.hashCode());
181                retval.setType("JDBC");
182                return retval;
183        }
184
185        public static RowMapper<HapiMigrationEntity> rowMapper() {
186                return (rs, rowNum) -> {
187                        HapiMigrationEntity entity = new HapiMigrationEntity();
188                        entity.setPid(rs.getInt(1));
189                        entity.setVersion(rs.getString(2));
190                        entity.setDescription(rs.getString(3));
191                        entity.setType(rs.getString(4));
192                        entity.setScript(rs.getString(5));
193                        entity.setChecksum(rs.getInt(6));
194                        entity.setInstalledBy(rs.getString(7));
195                        entity.setInstalledOn(rs.getDate(8));
196                        entity.setExecutionTime(rs.getInt(9));
197                        entity.setSuccess(rs.getBoolean(10));
198                        return entity;
199                };
200        }
201
202        public PreparedStatementSetter asPreparedStatementSetter() {
203                return ps -> {
204                        ps.setInt(1, getPid());
205                        ps.setString(2, getVersion());
206                        ps.setString(3, getDescription());
207                        ps.setString(4, getType());
208                        ps.setString(5, getScript());
209                        if (getChecksum() == null) {
210                                ps.setNull(6, java.sql.Types.INTEGER);
211                        } else {
212                                ps.setInt(6, getChecksum());
213                        }
214                        ps.setString(7, getInstalledBy());
215                        ps.setDate(
216                                        8,
217                                        getInstalledOn() != null
218                                                        ? new java.sql.Date(getInstalledOn().getTime())
219                                                        : null);
220                        ps.setInt(9, getExecutionTime());
221                        ps.setBoolean(10, getSuccess());
222                };
223        }
224}