001/*-
002 * #%L
003 * HAPI FHIR Server - SQL Migration
004 * %%
005 * Copyright (C) 2014 - 2025 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 RESULT_MAX_SIZE = 100;
045        public static final int CREATE_TABLE_PID = -1;
046        public static final String INITIAL_RECORD_DESCRIPTION = "<< HAPI FHIR Schema History table created >>";
047        public static final String INITIAL_RECORD_SCRIPT = "HAPI FHIR";
048
049        @Id
050        @GenericGenerator(
051                        name = "SEQ_FLY_HFJ_MIGRATION",
052                        strategy = "ca.uhn.fhir.jpa.model.dialect.HapiSequenceStyleGenerator")
053        @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_FLY_HFJ_MIGRATION")
054        @Column(name = "INSTALLED_RANK")
055        private Integer myPid;
056
057        @Column(name = "VERSION", length = VERSION_MAX_SIZE)
058        private String myVersion;
059
060        @Column(name = "DESCRIPTION", length = DESCRIPTION_MAX_SIZE)
061        private String myDescription;
062
063        @Column(name = "TYPE", length = TYPE_MAX_SIZE)
064        private String myType;
065
066        @Column(name = "SCRIPT", length = SCRIPT_MAX_SIZE)
067        private String myScript;
068
069        @Column(name = "CHECKSUM")
070        private Integer myChecksum;
071
072        @Column(name = "INSTALLED_BY", length = INSTALLED_BY_MAX_SIZE)
073        private String myInstalledBy;
074
075        @Column(name = "INSTALLED_ON")
076        private Date myInstalledOn;
077
078        @Column(name = "EXECUTION_TIME")
079        private Integer myExecutionTime;
080
081        @Column(name = "SUCCESS")
082        private Boolean mySuccess;
083
084        @Column(name = "RESULT", length = RESULT_MAX_SIZE)
085        private String myResult;
086
087        public static HapiMigrationEntity tableCreatedRecord() {
088                HapiMigrationEntity retVal = new HapiMigrationEntity();
089                retVal.setPid(CREATE_TABLE_PID);
090                retVal.setDescription(INITIAL_RECORD_DESCRIPTION);
091                retVal.setType("TABLE");
092                retVal.setScript(INITIAL_RECORD_SCRIPT);
093                retVal.setInstalledBy(VersionEnum.latestVersion().name());
094                retVal.setInstalledOn(new Date());
095                retVal.setExecutionTime(0);
096                retVal.setSuccess(true);
097                return retVal;
098        }
099
100        public Integer getPid() {
101                return myPid;
102        }
103
104        public void setPid(Integer thePid) {
105                myPid = thePid;
106        }
107
108        public String getVersion() {
109                return myVersion;
110        }
111
112        public void setVersion(String theVersion) {
113                myVersion = theVersion;
114        }
115
116        public String getDescription() {
117                return myDescription;
118        }
119
120        public void setDescription(String theDescription) {
121                myDescription = theDescription;
122        }
123
124        public String getType() {
125                return myType;
126        }
127
128        public void setType(String theType) {
129                myType = theType;
130        }
131
132        public String getScript() {
133                return myScript;
134        }
135
136        public void setScript(String theScript) {
137                myScript = theScript;
138        }
139
140        public Integer getChecksum() {
141                return myChecksum;
142        }
143
144        public void setChecksum(Integer theChecksum) {
145                myChecksum = theChecksum;
146        }
147
148        public String getInstalledBy() {
149                return myInstalledBy;
150        }
151
152        public void setInstalledBy(String theInstalledBy) {
153                myInstalledBy = theInstalledBy;
154        }
155
156        public Date getInstalledOn() {
157                return myInstalledOn;
158        }
159
160        public void setInstalledOn(Date theInstalledOn) {
161                myInstalledOn = theInstalledOn;
162        }
163
164        public Integer getExecutionTime() {
165                return myExecutionTime;
166        }
167
168        public void setExecutionTime(Integer theExecutionTime) {
169                myExecutionTime = theExecutionTime;
170        }
171
172        public Boolean getSuccess() {
173                return mySuccess;
174        }
175
176        public void setSuccess(Boolean theSuccess) {
177                mySuccess = theSuccess;
178        }
179
180        public static HapiMigrationEntity fromBaseTask(BaseTask theTask) {
181                HapiMigrationEntity retval = new HapiMigrationEntity();
182                retval.setVersion(theTask.getMigrationVersion());
183                retval.setDescription(theTask.getDescription());
184                retval.setChecksum(theTask.hashCode());
185                retval.setType("JDBC");
186                return retval;
187        }
188
189        public static RowMapper<HapiMigrationEntity> rowMapper() {
190                return (rs, rowNum) -> {
191                        HapiMigrationEntity entity = new HapiMigrationEntity();
192                        entity.setPid(rs.getInt(1));
193                        entity.setVersion(rs.getString(2));
194                        entity.setDescription(rs.getString(3));
195                        entity.setType(rs.getString(4));
196                        entity.setScript(rs.getString(5));
197                        entity.setChecksum(rs.getInt(6));
198                        entity.setInstalledBy(rs.getString(7));
199                        entity.setInstalledOn(rs.getDate(8));
200                        entity.setExecutionTime(rs.getInt(9));
201                        entity.setSuccess(rs.getBoolean(10));
202                        entity.setResult(rs.getString(11));
203                        return entity;
204                };
205        }
206
207        public PreparedStatementSetter asPreparedStatementSetter() {
208                return ps -> {
209                        ps.setInt(1, getPid());
210                        ps.setString(2, getVersion());
211                        ps.setString(3, getDescription());
212                        ps.setString(4, getType());
213                        ps.setString(5, getScript());
214                        if (getChecksum() == null) {
215                                ps.setNull(6, java.sql.Types.INTEGER);
216                        } else {
217                                ps.setInt(6, getChecksum());
218                        }
219                        ps.setString(7, getInstalledBy());
220                        ps.setDate(
221                                        8,
222                                        getInstalledOn() != null
223                                                        ? new java.sql.Date(getInstalledOn().getTime())
224                                                        : null);
225                        ps.setInt(9, getExecutionTime());
226                        ps.setBoolean(10, getSuccess());
227                        ps.setString(11, getResult());
228                };
229        }
230
231        public String getResult() {
232                return myResult;
233        }
234
235        public void setResult(String theResult) {
236                myResult = theResult;
237        }
238}