* Create new_code_periods table along with dto and daotags/8.0
@@ -77,6 +77,7 @@ public final class SqTables { | |||
"live_measures", | |||
"manual_measures", | |||
"metrics", | |||
"new_code_periods", | |||
"notifications", | |||
"organizations", | |||
"organization_alm_bindings", |
@@ -49,6 +49,7 @@ import org.sonar.db.measure.LiveMeasureDao; | |||
import org.sonar.db.measure.MeasureDao; | |||
import org.sonar.db.measure.custom.CustomMeasureDao; | |||
import org.sonar.db.metric.MetricDao; | |||
import org.sonar.db.newcodeperiod.NewCodePeriodDao; | |||
import org.sonar.db.notification.NotificationQueueDao; | |||
import org.sonar.db.organization.OrganizationDao; | |||
import org.sonar.db.organization.OrganizationMemberDao; | |||
@@ -122,6 +123,7 @@ public class DaoModule extends Module { | |||
LiveMeasureDao.class, | |||
MeasureDao.class, | |||
MetricDao.class, | |||
NewCodePeriodDao.class, | |||
NotificationQueueDao.class, | |||
OrganizationAlmBindingDao.class, | |||
OrganizationDao.class, |
@@ -47,6 +47,7 @@ import org.sonar.db.measure.LiveMeasureDao; | |||
import org.sonar.db.measure.MeasureDao; | |||
import org.sonar.db.measure.custom.CustomMeasureDao; | |||
import org.sonar.db.metric.MetricDao; | |||
import org.sonar.db.newcodeperiod.NewCodePeriodDao; | |||
import org.sonar.db.notification.NotificationQueueDao; | |||
import org.sonar.db.organization.OrganizationDao; | |||
import org.sonar.db.organization.OrganizationMemberDao; | |||
@@ -152,6 +153,7 @@ public class DbClient { | |||
private final WebhookDeliveryDao webhookDeliveryDao; | |||
private final ProjectMappingsDao projectMappingsDao; | |||
private final OrganizationAlmBindingDao organizationAlmBindingDao; | |||
private final NewCodePeriodDao newCodePeriodDao; | |||
public DbClient(Database database, MyBatis myBatis, DBSessions dbSessions, Dao... daos) { | |||
this.database = database; | |||
@@ -224,6 +226,7 @@ public class DbClient { | |||
projectMappingsDao = getDao(map, ProjectMappingsDao.class); | |||
organizationAlmBindingDao = getDao(map, OrganizationAlmBindingDao.class); | |||
internalComponentPropertiesDao = getDao(map, InternalComponentPropertiesDao.class); | |||
newCodePeriodDao = getDao(map, NewCodePeriodDao.class); | |||
} | |||
public DbSession openSession(boolean batch) { | |||
@@ -491,4 +494,8 @@ public class DbClient { | |||
public InternalComponentPropertiesDao internalComponentPropertiesDao() { | |||
return internalComponentPropertiesDao; | |||
} | |||
public NewCodePeriodDao newCodePeriodDao() { | |||
return newCodePeriodDao; | |||
} | |||
} |
@@ -80,6 +80,7 @@ import org.sonar.db.measure.MeasureMapper; | |||
import org.sonar.db.measure.custom.CustomMeasureDto; | |||
import org.sonar.db.measure.custom.CustomMeasureMapper; | |||
import org.sonar.db.metric.MetricMapper; | |||
import org.sonar.db.newcodeperiod.NewCodePeriodMapper; | |||
import org.sonar.db.notification.NotificationQueueDto; | |||
import org.sonar.db.notification.NotificationQueueMapper; | |||
import org.sonar.db.organization.OrganizationDto; | |||
@@ -252,6 +253,7 @@ public class MyBatis implements Startable { | |||
IssueMapper.class, | |||
MeasureMapper.class, | |||
MetricMapper.class, | |||
NewCodePeriodMapper.class, | |||
NotificationQueueMapper.class, | |||
OrganizationAlmBindingMapper.class, | |||
OrganizationMapper.class, |
@@ -0,0 +1,74 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2019 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.db.newcodeperiod; | |||
import java.util.Optional; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.db.Dao; | |||
import org.sonar.db.DbSession; | |||
import static java.util.Objects.requireNonNull; | |||
public class NewCodePeriodDao implements Dao { | |||
private final System2 system2; | |||
public NewCodePeriodDao(System2 system2) { | |||
this.system2 = system2; | |||
} | |||
public Optional<NewCodePeriodDto> selectByUuid(DbSession dbSession, String uuid) { | |||
return mapper(dbSession).selectByUuid(uuid); | |||
} | |||
public NewCodePeriodDto selectGlobal(DbSession dbSession) { | |||
return mapper(dbSession).selectGlobal(); | |||
} | |||
public void insert(DbSession dbSession, NewCodePeriodDto dto) { | |||
requireNonNull(dto.getType(), "Type of NewCodePeriod must be specified."); | |||
requireNonNull(dto.getValue(), "Value of NewCodePeriod must be specified."); | |||
long currentTime = system2.now(); | |||
mapper(dbSession).insert(dto.setCreatedAt(currentTime).setUpdatedAt(currentTime)); | |||
} | |||
public void update(DbSession dbSession, NewCodePeriodDto dto) { | |||
requireNonNull(dto.getType(), "Type of NewCodePeriod must be specified."); | |||
requireNonNull(dto.getValue(), "Value of NewCodePeriod must be specified."); | |||
mapper(dbSession).update(dto.setUpdatedAt(system2.now())); | |||
} | |||
public Optional<NewCodePeriodDto> selectByProject(DbSession dbSession, String projectUuid) { | |||
requireNonNull(projectUuid, "Project uuid must be specified."); | |||
return Optional.ofNullable(mapper(dbSession).selectByProject(projectUuid)); | |||
} | |||
public Optional<NewCodePeriodDto> selectByBranch(DbSession dbSession, String projectUuid, String branchUuid) { | |||
requireNonNull(projectUuid, "Project uuid must be specified."); | |||
requireNonNull(branchUuid, "Branch uuid must be specified."); | |||
return Optional.ofNullable(mapper(dbSession).selectByBranch(projectUuid, branchUuid)); | |||
} | |||
private static NewCodePeriodMapper mapper(DbSession session) { | |||
return session.getMapper(NewCodePeriodMapper.class); | |||
} | |||
} |
@@ -0,0 +1,97 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2019 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.db.newcodeperiod; | |||
import javax.annotation.CheckForNull; | |||
public class NewCodePeriodDto { | |||
private String uuid; | |||
private String projectUuid; | |||
private String branchUuid; | |||
private NewCodePeriodType type; | |||
private String value; | |||
private long updatedAt; | |||
private long createdAt; | |||
public long getCreatedAt() { | |||
return createdAt; | |||
} | |||
public NewCodePeriodDto setCreatedAt(long createdAt) { | |||
this.createdAt = createdAt; | |||
return this; | |||
} | |||
public long getUpdatedAt() { | |||
return updatedAt; | |||
} | |||
public NewCodePeriodDto setUpdatedAt(long updatedAt) { | |||
this.updatedAt = updatedAt; | |||
return this; | |||
} | |||
public String getUuid() { | |||
return uuid; | |||
} | |||
public NewCodePeriodDto setUuid(String uuid) { | |||
this.uuid = uuid; | |||
return this; | |||
} | |||
@CheckForNull | |||
public String getProjectUuid() { | |||
return projectUuid; | |||
} | |||
public NewCodePeriodDto setProjectUuid(String projectUuid) { | |||
this.projectUuid = projectUuid; | |||
return this; | |||
} | |||
@CheckForNull | |||
public String getBranchUuid() { | |||
return branchUuid; | |||
} | |||
public NewCodePeriodDto setBranchUuid(String branchUuid) { | |||
this.branchUuid = branchUuid; | |||
return this; | |||
} | |||
public NewCodePeriodType getType() { | |||
return type; | |||
} | |||
public NewCodePeriodDto setType(NewCodePeriodType type) { | |||
this.type = type; | |||
return this; | |||
} | |||
public String getValue() { | |||
return value; | |||
} | |||
public NewCodePeriodDto setValue(String value) { | |||
this.value = value; | |||
return this; | |||
} | |||
} |
@@ -0,0 +1,38 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2019 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.db.newcodeperiod; | |||
import java.util.Optional; | |||
import org.apache.ibatis.annotations.Param; | |||
public interface NewCodePeriodMapper { | |||
Optional<NewCodePeriodDto> selectByUuid(String uuid); | |||
NewCodePeriodDto selectGlobal(); | |||
void insert(NewCodePeriodDto dto); | |||
void update(NewCodePeriodDto dto); | |||
NewCodePeriodDto selectByProject(String projectUuid); | |||
NewCodePeriodDto selectByBranch(@Param("projectUuid") String projectUuid, @Param("branchUuid") String branchUuid); | |||
} |
@@ -0,0 +1,27 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2019 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.db.newcodeperiod; | |||
public enum NewCodePeriodType { | |||
PREVIOUS_VERSION, | |||
NUMBER_OF_DAYS, | |||
DATE, | |||
SPECIFIC_ANALYSIS | |||
} |
@@ -0,0 +1,74 @@ | |||
<?xml version="1.0" encoding="UTF-8" ?> | |||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd"> | |||
<mapper namespace="org.sonar.db.newcodeperiod.NewCodePeriodMapper"> | |||
<sql id="newCodePeriodMapperColumns"> | |||
ncp.uuid, | |||
ncp.project_uuid as projectUuid, | |||
ncp.branch_uuid as branchUuid, | |||
ncp.type, | |||
ncp.value, | |||
ncp.updated_at as updatedAt, | |||
ncp.created_at as createdAt | |||
</sql> | |||
<select id="selectByUuid" parameterType="map" resultType="org.sonar.db.newcodeperiod.NewCodePeriodDto"> | |||
SELECT | |||
<include refid="newCodePeriodMapperColumns"/> | |||
FROM new_code_periods ncp | |||
WHERE | |||
ncp.uuid = #{uuid, jdbcType=VARCHAR} | |||
</select> | |||
<select id="selectGlobal" parameterType="map" resultType="org.sonar.db.newcodeperiod.NewCodePeriodDto"> | |||
SELECT | |||
<include refid="newCodePeriodMapperColumns"/> | |||
FROM new_code_periods ncp | |||
WHERE | |||
ncp.project_uuid is null | |||
AND ncp.branch_uuid is null | |||
</select> | |||
<insert id="insert" parameterType="org.sonar.db.newcodeperiod.NewCodePeriodDto"> | |||
INSERT INTO new_code_periods ( | |||
uuid, project_uuid, branch_uuid, type, value, updated_at, created_at) | |||
VALUES ( | |||
#{uuid, jdbcType=VARCHAR}, | |||
#{projectUuid, jdbcType=VARCHAR}, | |||
#{branchUuid, jdbcType=VARCHAR}, | |||
#{type, jdbcType=VARCHAR}, | |||
#{value, jdbcType=VARCHAR}, | |||
#{updatedAt, jdbcType=TIMESTAMP}, | |||
#{createdAt, jdbcType=TIMESTAMP} | |||
) | |||
</insert> | |||
<update id="update" parameterType="org.sonar.db.newcodeperiod.NewCodePeriodDto"> | |||
update new_code_periods | |||
set | |||
type=#{type, jdbcType=VARCHAR}, | |||
value=#{value, jdbcType=VARCHAR}, | |||
updated_at=#{updatedAt, jdbcType=TIMESTAMP} | |||
where uuid=#{uuid} | |||
</update> | |||
<select id="selectByProject" parameterType="map" resultType="org.sonar.db.newcodeperiod.NewCodePeriodDto"> | |||
SELECT | |||
<include refid="newCodePeriodMapperColumns"/> | |||
FROM new_code_periods ncp | |||
WHERE | |||
ncp.project_uuid=#{projectUuid, jdbcType=VARCHAR} | |||
AND ncp.branch_uuid is null | |||
</select> | |||
<select id="selectByBranch" parameterType="map" resultType="org.sonar.db.newcodeperiod.NewCodePeriodDto"> | |||
SELECT | |||
<include refid="newCodePeriodMapperColumns"/> | |||
FROM new_code_periods ncp | |||
WHERE | |||
ncp.project_uuid=#{projectUuid, jdbcType=VARCHAR} | |||
AND ncp.branch_uuid=#{branchUuid, jdbcType=VARCHAR} | |||
</select> | |||
</mapper> |
@@ -0,0 +1,183 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2019 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.db.newcodeperiod; | |||
import java.util.Optional; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.DbTester; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class NewCodePeriodDaoTest { | |||
@Rule | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
private DbSession dbSession = db.getSession(); | |||
private NewCodePeriodDao underTest = new NewCodePeriodDao(System2.INSTANCE); | |||
@Test | |||
public void insert_new_code_period() { | |||
underTest.insert(dbSession, new NewCodePeriodDto() | |||
.setUuid("uuid-1") | |||
.setProjectUuid("proj-uuid") | |||
.setBranchUuid("branch-uuid") | |||
.setType(NewCodePeriodType.NUMBER_OF_DAYS) | |||
.setValue("5")); | |||
Optional<NewCodePeriodDto> resultOpt = underTest.selectByUuid(dbSession, "uuid-1"); | |||
assertThat(resultOpt).isNotNull(); | |||
assertThat(resultOpt).isNotEmpty(); | |||
NewCodePeriodDto result = resultOpt.get(); | |||
assertThat(result.getUuid()).isEqualTo("uuid-1"); | |||
assertThat(result.getProjectUuid()).isEqualTo("proj-uuid"); | |||
assertThat(result.getBranchUuid()).isEqualTo("branch-uuid"); | |||
assertThat(result.getType()).isEqualTo(NewCodePeriodType.NUMBER_OF_DAYS); | |||
assertThat(result.getValue()).isEqualTo("5"); | |||
assertThat(result.getCreatedAt()).isNotEqualTo(0); | |||
assertThat(result.getUpdatedAt()).isNotEqualTo(0); | |||
} | |||
@Test | |||
public void update_new_code_period() { | |||
NewCodePeriodDto dto = db.newCodePeriods().insert(new NewCodePeriodDto() | |||
.setUuid("uuid-1") | |||
.setProjectUuid("proj-uuid") | |||
.setBranchUuid("branch-uuid") | |||
.setType(NewCodePeriodType.NUMBER_OF_DAYS) | |||
.setValue("5")); | |||
underTest.update(dbSession, new NewCodePeriodDto() | |||
.setUuid(dto.getUuid()) | |||
.setType(NewCodePeriodType.SPECIFIC_ANALYSIS) | |||
.setValue("analysis-uuid")); | |||
Optional<NewCodePeriodDto> resultOpt = underTest.selectByUuid(dbSession, "uuid-1"); | |||
assertThat(resultOpt).isNotNull(); | |||
assertThat(resultOpt).isNotEmpty(); | |||
NewCodePeriodDto result = resultOpt.get(); | |||
assertThat(result.getUuid()).isEqualTo("uuid-1"); | |||
assertThat(result.getProjectUuid()).isEqualTo("proj-uuid"); | |||
assertThat(result.getBranchUuid()).isEqualTo("branch-uuid"); | |||
assertThat(result.getType()).isEqualTo(NewCodePeriodType.SPECIFIC_ANALYSIS); | |||
assertThat(result.getValue()).isEqualTo("analysis-uuid"); | |||
assertThat(result.getCreatedAt()).isNotEqualTo(0); | |||
assertThat(result.getUpdatedAt()).isNotEqualTo(0); | |||
} | |||
@Test | |||
public void select_by_project_and_branch_uuids() { | |||
NewCodePeriodDto dto = db.newCodePeriods().insert(new NewCodePeriodDto() | |||
.setUuid("uuid-1") | |||
.setProjectUuid("proj-uuid") | |||
.setBranchUuid("branch-uuid") | |||
.setType(NewCodePeriodType.NUMBER_OF_DAYS) | |||
.setValue("5")); | |||
Optional<NewCodePeriodDto> resultOpt = underTest.selectByBranch(dbSession, dto.getProjectUuid(), dto.getBranchUuid()); | |||
assertThat(resultOpt).isNotNull(); | |||
assertThat(resultOpt).isNotEmpty(); | |||
NewCodePeriodDto result = resultOpt.get(); | |||
assertThat(result.getUuid()).isEqualTo("uuid-1"); | |||
assertThat(result.getProjectUuid()).isEqualTo("proj-uuid"); | |||
assertThat(result.getBranchUuid()).isEqualTo("branch-uuid"); | |||
assertThat(result.getType()).isEqualTo(NewCodePeriodType.NUMBER_OF_DAYS); | |||
assertThat(result.getValue()).isEqualTo("5"); | |||
assertThat(result.getCreatedAt()).isNotEqualTo(0); | |||
assertThat(result.getUpdatedAt()).isNotEqualTo(0); | |||
} | |||
@Test | |||
public void select_by_project_uuid() { | |||
NewCodePeriodDto dto = db.newCodePeriods().insert(new NewCodePeriodDto() | |||
.setUuid("uuid-1") | |||
.setProjectUuid("proj-uuid") | |||
.setBranchUuid(null) | |||
.setType(NewCodePeriodType.NUMBER_OF_DAYS) | |||
.setValue("5")); | |||
Optional<NewCodePeriodDto> resultOpt = underTest.selectByProject(dbSession, dto.getProjectUuid()); | |||
assertThat(resultOpt).isNotNull(); | |||
assertThat(resultOpt).isNotEmpty(); | |||
NewCodePeriodDto result = resultOpt.get(); | |||
assertThat(result.getUuid()).isEqualTo("uuid-1"); | |||
assertThat(result.getProjectUuid()).isEqualTo("proj-uuid"); | |||
assertThat(result.getBranchUuid()).isNull(); | |||
assertThat(result.getType()).isEqualTo(NewCodePeriodType.NUMBER_OF_DAYS); | |||
assertThat(result.getValue()).isEqualTo("5"); | |||
assertThat(result.getCreatedAt()).isNotEqualTo(0); | |||
assertThat(result.getUpdatedAt()).isNotEqualTo(0); | |||
} | |||
@Test | |||
public void select_global() { | |||
db.newCodePeriods().insert(new NewCodePeriodDto() | |||
.setUuid("uuid-1") | |||
.setProjectUuid(null) | |||
.setBranchUuid(null) | |||
.setType(NewCodePeriodType.NUMBER_OF_DAYS) | |||
.setValue("30")); | |||
NewCodePeriodDto result = underTest.selectGlobal(dbSession); | |||
assertThat(result.getUuid()).isEqualTo("uuid-1"); | |||
assertThat(result.getProjectUuid()).isNull(); | |||
assertThat(result.getBranchUuid()).isNull(); | |||
assertThat(result.getType()).isEqualTo(NewCodePeriodType.NUMBER_OF_DAYS); | |||
assertThat(result.getValue()).isEqualTo("30"); | |||
assertThat(result.getCreatedAt()).isNotEqualTo(0); | |||
assertThat(result.getUpdatedAt()).isNotEqualTo(0); | |||
} | |||
@Test | |||
public void fail_select_by_project_and_branch_uuids_if_project_uuid_not_provided() { | |||
expectedException.expect(NullPointerException.class); | |||
expectedException.expectMessage("Project uuid must be specified."); | |||
underTest.selectByBranch(dbSession, null, "random-uuid"); | |||
} | |||
@Test | |||
public void fail_select_by_project_and_branch_uuids_if_branch_uuid_not_provided() { | |||
expectedException.expect(NullPointerException.class); | |||
expectedException.expectMessage("Branch uuid must be specified."); | |||
underTest.selectByBranch(dbSession, "random-uuid", null); | |||
} | |||
@Test | |||
public void fail_select_by_project_uuid_if_project_uuid_not_provided() { | |||
expectedException.expect(NullPointerException.class); | |||
expectedException.expectMessage("Project uuid must be specified."); | |||
underTest.selectByProject(dbSession, null); | |||
} | |||
} |
@@ -0,0 +1,38 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2019 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.db.newcodeperiod; | |||
import org.sonar.db.DbTester; | |||
public class NewCodePeriodDbTester { | |||
private final DbTester dbTester; | |||
public NewCodePeriodDbTester(DbTester dbTester) { | |||
this.dbTester = dbTester; | |||
} | |||
public NewCodePeriodDto insert(NewCodePeriodDto dto) { | |||
dbTester.getDbClient().newCodePeriodDao().insert(dbTester.getSession(), dto); | |||
dbTester.getSession().commit(); | |||
return dto; | |||
} | |||
} |
@@ -0,0 +1,53 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2019 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.db.newcodeperiod; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.api.utils.System2; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class NewCodePeriodDtoTest { | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
@Test | |||
public void getters_and_setters() { | |||
long currentTime = System2.INSTANCE.now(); | |||
NewCodePeriodDto newCodePeriodDto = new NewCodePeriodDto() | |||
.setUuid("uuid") | |||
.setProjectUuid("projectUuid") | |||
.setBranchUuid("branchUuid") | |||
.setCreatedAt(currentTime) | |||
.setUpdatedAt(currentTime) | |||
.setType(NewCodePeriodType.DATE) | |||
.setValue("2018-01-02"); | |||
assertThat(newCodePeriodDto.getUuid()).isEqualTo("uuid"); | |||
assertThat(newCodePeriodDto.getProjectUuid()).isEqualTo("projectUuid"); | |||
assertThat(newCodePeriodDto.getBranchUuid()).isEqualTo("branchUuid"); | |||
assertThat(newCodePeriodDto.getCreatedAt()).isEqualTo(currentTime); | |||
assertThat(newCodePeriodDto.getUpdatedAt()).isEqualTo(currentTime); | |||
assertThat(newCodePeriodDto.getType()).isEqualTo(NewCodePeriodType.DATE); | |||
assertThat(newCodePeriodDto.getValue()).isEqualTo("2018-01-02"); | |||
} | |||
} |
@@ -39,6 +39,7 @@ import org.sonar.db.event.EventDbTester; | |||
import org.sonar.db.favorite.FavoriteDbTester; | |||
import org.sonar.db.issue.IssueDbTester; | |||
import org.sonar.db.measure.MeasureDbTester; | |||
import org.sonar.db.newcodeperiod.NewCodePeriodDbTester; | |||
import org.sonar.db.notification.NotificationDbTester; | |||
import org.sonar.db.organization.OrganizationDbTester; | |||
import org.sonar.db.organization.OrganizationDto; | |||
@@ -84,6 +85,7 @@ public class DbTester extends AbstractDbTester<TestDbImpl> { | |||
private final QualityGateDbTester qualityGateDbTester; | |||
private final IssueDbTester issueDbTester; | |||
private final RuleDbTester ruleDbTester; | |||
private final NewCodePeriodDbTester newCodePeriodTester; | |||
private final NotificationDbTester notificationDbTester; | |||
private final RootFlagAssertions rootFlagAssertions; | |||
private final QualityProfileDbTester qualityProfileDbTester; | |||
@@ -121,6 +123,7 @@ public class DbTester extends AbstractDbTester<TestDbImpl> { | |||
this.webhookDeliveryDbTester = new WebhookDeliveryDbTester(this); | |||
this.almDbTester = new AlmDbTester(this); | |||
this.internalComponentPropertyTester = new InternalComponentPropertyDbTester(this); | |||
this.newCodePeriodTester = new NewCodePeriodDbTester(this); | |||
} | |||
public static DbTester create() { | |||
@@ -251,6 +254,10 @@ public class DbTester extends AbstractDbTester<TestDbImpl> { | |||
return ruleDbTester; | |||
} | |||
public NewCodePeriodDbTester newCodePeriods() { | |||
return newCodePeriodTester; | |||
} | |||
public NotificationDbTester notifications() { | |||
return notificationDbTester; | |||
} |
@@ -0,0 +1,112 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2019 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.platform.db.migration.version.v80; | |||
import java.sql.Connection; | |||
import java.sql.SQLException; | |||
import org.sonar.db.Database; | |||
import org.sonar.db.DatabaseUtils; | |||
import org.sonar.server.platform.db.migration.def.BigIntegerColumnDef; | |||
import org.sonar.server.platform.db.migration.def.VarcharColumnDef; | |||
import org.sonar.server.platform.db.migration.sql.CreateTableBuilder; | |||
import org.sonar.server.platform.db.migration.step.DdlChange; | |||
import static org.sonar.server.platform.db.migration.def.BigIntegerColumnDef.newBigIntegerColumnDefBuilder; | |||
import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.UUID_SIZE; | |||
import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; | |||
public class CreateNewCodePeriodTable extends DdlChange { | |||
private static final String TABLE_NAME = "new_code_periods"; | |||
private static final VarcharColumnDef UUID_COLUMN = newVarcharColumnDefBuilder() | |||
.setColumnName("uuid") | |||
.setIsNullable(false) | |||
.setLimit(UUID_SIZE) | |||
.build(); | |||
private static final VarcharColumnDef PROJECT_UUID_COLUMN = newVarcharColumnDefBuilder() | |||
.setColumnName("project_uuid") | |||
.setIsNullable(true) | |||
.setLimit(UUID_SIZE) | |||
.build(); | |||
private static final VarcharColumnDef BRANCH_UUID_COLUMN = newVarcharColumnDefBuilder() | |||
.setColumnName("branch_uuid") | |||
.setIsNullable(true) | |||
.setLimit(UUID_SIZE) | |||
.build(); | |||
/** | |||
* Available values: | |||
* * PREVIOUS_VERSION | |||
* * NUMBER_OF_DAYS | |||
* * DATE | |||
* * SPECIFIC_ANALYSIS | |||
*/ | |||
private static final VarcharColumnDef TYPE = newVarcharColumnDefBuilder() | |||
.setColumnName("type") | |||
.setIsNullable(false) | |||
.setLimit(30) | |||
.build(); | |||
private static final VarcharColumnDef VALUE = newVarcharColumnDefBuilder() | |||
.setColumnName("value") | |||
.setIsNullable(false) | |||
.setLimit(40) | |||
.build(); | |||
private static final BigIntegerColumnDef UPDATED_AT = newBigIntegerColumnDefBuilder() | |||
.setColumnName("updated_at") | |||
.setIsNullable(false) | |||
.build(); | |||
private static final BigIntegerColumnDef CREATED_AT = newBigIntegerColumnDefBuilder() | |||
.setColumnName("created_at") | |||
.setIsNullable(false) | |||
.build(); | |||
public CreateNewCodePeriodTable(Database db) { | |||
super(db); | |||
} | |||
@Override | |||
public void execute(Context context) throws SQLException { | |||
if (tableExists()) { | |||
return; | |||
} | |||
context.execute(new CreateTableBuilder(getDialect(), TABLE_NAME) | |||
.addPkColumn(UUID_COLUMN) | |||
.addColumn(PROJECT_UUID_COLUMN) | |||
.addColumn(BRANCH_UUID_COLUMN) | |||
.addColumn(TYPE) | |||
.addColumn(VALUE) | |||
.addColumn(UPDATED_AT) | |||
.addColumn(CREATED_AT) | |||
.build()); | |||
} | |||
private boolean tableExists() throws SQLException { | |||
try (Connection connection = getDatabase().getDataSource().getConnection()) { | |||
return DatabaseUtils.tableExists(TABLE_NAME, connection); | |||
} | |||
} | |||
} |
@@ -32,6 +32,8 @@ public class DbVersion80 implements DbVersion { | |||
.add(3003, "Populate ProjectQualityGate table from Properties table", PopulateProjectQualityGatesTable.class) | |||
.add(3004, "Rename ANALYSIS_PROPERTIES.SNAPSHOT_UUID to ANALYSIS_UUID", RenameAnalysisPropertiesSnapshotUuid.class) | |||
.add(3005, "Remove default quality gate property from Properties table", RemoveDefaultQualityGateFromPropertiesTable.class) | |||
.add(3006, "Create NEW_CODE_PERIOD table", CreateNewCodePeriodTable.class) | |||
.add(3007, "Populate NEW_CODE_PERIOD table", PopulateNewCodePeriodTable.class) | |||
; | |||
} | |||
} |
@@ -0,0 +1,100 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2019 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.platform.db.migration.version.v80; | |||
import java.sql.SQLException; | |||
import java.util.List; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.core.util.UuidFactory; | |||
import org.sonar.db.Database; | |||
import org.sonar.server.platform.db.migration.step.DataChange; | |||
import org.sonar.server.platform.db.migration.step.Upsert; | |||
public class PopulateNewCodePeriodTable extends DataChange { | |||
private final UuidFactory uuidFactory; | |||
private final System2 system2; | |||
public PopulateNewCodePeriodTable(Database db, UuidFactory uuidFactory, System2 system2) { | |||
super(db); | |||
this.uuidFactory = uuidFactory; | |||
this.system2 = system2; | |||
} | |||
@Override | |||
protected void execute(Context context) throws SQLException { | |||
List<ProjectBranchCodePeriod> projectBranchCodePeriods = context.prepareSelect( | |||
"select pb.uuid, pb.project_uuid, pb.manual_baseline_analysis_uuid from project_branches pb where pb.manual_baseline_analysis_uuid is not null") | |||
.list(row -> { | |||
String branchUuid = row.getString(1); | |||
String projectUuid = row.getString(2); | |||
String manualBaselineAnalysisUuid = row.getString(3); | |||
return new ProjectBranchCodePeriod(branchUuid, projectUuid, manualBaselineAnalysisUuid); | |||
}); | |||
if (!projectBranchCodePeriods.isEmpty()) { | |||
populateProjectBranchCodePeriods(context, projectBranchCodePeriods); | |||
} | |||
} | |||
private void populateProjectBranchCodePeriods(Context context, List<ProjectBranchCodePeriod> projectBranchCodePeriods) throws SQLException { | |||
Upsert insertQuery = prepareInsertProjectQualityGateQuery(context); | |||
for (ProjectBranchCodePeriod projectBranchCodePeriod : projectBranchCodePeriods) { | |||
long currenTime = system2.now(); | |||
insertQuery | |||
.setString(1, uuidFactory.create()) | |||
.setString(2, projectBranchCodePeriod.projectUuid) | |||
.setString(3, projectBranchCodePeriod.branchUuid) | |||
.setString(4, "SPECIFIC_ANALYSIS") | |||
.setString(5, projectBranchCodePeriod.manualBaselineAnalysisUuid) | |||
.setLong(6, currenTime) | |||
.setLong(7, currenTime) | |||
.addBatch(); | |||
} | |||
insertQuery | |||
.execute() | |||
.commit(); | |||
} | |||
private static Upsert prepareInsertProjectQualityGateQuery(Context context) throws SQLException { | |||
return context.prepareUpsert("insert into new_code_periods(" + | |||
"uuid, " + | |||
"project_uuid," + | |||
"branch_uuid," + | |||
"type," + | |||
"value," + | |||
"updated_at," + | |||
"created_at" + | |||
") VALUES (?, ?, ?, ?, ?, ?, ?)"); | |||
} | |||
private static class ProjectBranchCodePeriod { | |||
private final String branchUuid; | |||
private final String projectUuid; | |||
private final String manualBaselineAnalysisUuid; | |||
ProjectBranchCodePeriod(String branchUuid, String projectUuid, String manualBaselineAnalysisUuid) { | |||
this.branchUuid = branchUuid; | |||
this.projectUuid = projectUuid; | |||
this.manualBaselineAnalysisUuid = manualBaselineAnalysisUuid; | |||
} | |||
} | |||
} |
@@ -0,0 +1,61 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2019 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.platform.db.migration.version.v80; | |||
import java.sql.SQLException; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.db.CoreDbTester; | |||
import static java.sql.Types.BIGINT; | |||
import static java.sql.Types.VARCHAR; | |||
public class CreateNewCodePeriodTableTest { | |||
private static final String TABLE_NAME = "new_code_periods"; | |||
@Rule | |||
public CoreDbTester dbTester = CoreDbTester.createEmpty(); | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
private CreateNewCodePeriodTable underTest = new CreateNewCodePeriodTable(dbTester.database()); | |||
@Test | |||
public void table_has_been_created() throws SQLException { | |||
underTest.execute(); | |||
dbTester.assertTableExists(TABLE_NAME); | |||
dbTester.assertPrimaryKey(TABLE_NAME, "pk_new_code_periods", "uuid"); | |||
dbTester.assertColumnDefinition(TABLE_NAME, "uuid", VARCHAR, 40, false); | |||
dbTester.assertColumnDefinition(TABLE_NAME, "project_uuid", VARCHAR, 40, true); | |||
dbTester.assertColumnDefinition(TABLE_NAME, "branch_uuid", VARCHAR, 40, true); | |||
dbTester.assertColumnDefinition(TABLE_NAME, "type", VARCHAR, 30, false); | |||
dbTester.assertColumnDefinition(TABLE_NAME, "value", VARCHAR, 40, false); | |||
dbTester.assertColumnDefinition(TABLE_NAME, "updated_at", BIGINT, 20, false); | |||
dbTester.assertColumnDefinition(TABLE_NAME, "created_at", BIGINT, 20, false); | |||
//script should not fail if executed twice | |||
underTest.execute(); | |||
} | |||
} |
@@ -35,7 +35,7 @@ public class DbVersion80Test { | |||
@Test | |||
public void verify_migration_count() { | |||
verifyMigrationCount(underTest, 6); | |||
verifyMigrationCount(underTest, 8); | |||
} | |||
} |
@@ -0,0 +1,73 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2019 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.platform.db.migration.version.v80; | |||
import java.sql.SQLException; | |||
import org.junit.Assert; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.core.util.UuidFactoryImpl; | |||
import org.sonar.db.CoreDbTester; | |||
public class PopulateNewCodePeriodTableTest { | |||
private static final String NEW_CODE_PERIODS_TABLE_NAME = "new_code_periods"; | |||
private static final String PROJECT_BRANCHES_TABLE_NAME = "project_branches"; | |||
private static final int NUMBER_OF_PROJECT_BRANCHES_TO_INSERT = 10; | |||
@Rule | |||
public CoreDbTester dbTester = CoreDbTester.createForSchema(PopulateNewCodePeriodTableTest.class, "schema.sql"); | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
private PopulateNewCodePeriodTable underTest = new PopulateNewCodePeriodTable(dbTester.database(), UuidFactoryImpl.INSTANCE, System2.INSTANCE); | |||
@Test | |||
public void copy_manual_baseline_analysis_to_new_code_period_table() throws SQLException { | |||
for (long i = 1; i <= NUMBER_OF_PROJECT_BRANCHES_TO_INSERT; i++) { | |||
insertProjectBranch(i); | |||
} | |||
underTest.execute(); | |||
int propertiesCount = dbTester.countRowsOfTable(NEW_CODE_PERIODS_TABLE_NAME); | |||
Assert.assertEquals(10, propertiesCount); | |||
//should not fail if executed twice | |||
underTest.execute(); | |||
} | |||
private void insertProjectBranch(long counter) { | |||
dbTester.executeInsert( | |||
PROJECT_BRANCHES_TABLE_NAME, | |||
"UUID", "pb-uuid-" + counter, | |||
"PROJECT_UUID", "pb-uuid-" + counter, | |||
"KEE", "pb-key-" + counter, | |||
"KEY_TYPE", "TSR", | |||
"BRANCH_TYPE", "LONG", | |||
"MERGE_BRANCH_UUID", "mb-uuid-" + counter, | |||
"MANUAL_BASELINE_ANALYSIS_UUID", "mba-uuid" + counter, | |||
"CREATED_AT", System2.INSTANCE.now(), | |||
"UPDATED_AT", System2.INSTANCE.now() | |||
); | |||
} | |||
} |
@@ -861,6 +861,17 @@ CREATE TABLE "ANALYSIS_PROPERTIES" ( | |||
); | |||
CREATE INDEX "SNAPSHOT_UUID" ON "ANALYSIS_PROPERTIES" ("SNAPSHOT_UUID"); | |||
CREATE TABLE "NEW_CODE_PERIODS" ( | |||
"UUID" VARCHAR(40) NOT NULL, | |||
"PROJECT_UUID" VARCHAR(40), | |||
"BRANCH_UUID" VARCHAR(40), | |||
"TYPE" VARCHAR(30) NOT NULL, | |||
"VALUE" VARCHAR(40) NOT NULL, | |||
"UPDATED_AT" BIGINT NOT NULL, | |||
"CREATED_AT" BIGINT NOT NULL, | |||
CONSTRAINT "PK_NEW_CODE_PERIOD" PRIMARY KEY ("UUID") | |||
); | |||
CREATE TABLE "WEBHOOKS" ( | |||
"UUID" VARCHAR(40) NOT NULL, |
@@ -0,0 +1,27 @@ | |||
CREATE TABLE "PROJECT_BRANCHES" ( | |||
"UUID" VARCHAR(50) NOT NULL, | |||
"PROJECT_UUID" VARCHAR(50) NOT NULL, | |||
"KEE" VARCHAR(255) NOT NULL, | |||
"KEY_TYPE" VARCHAR(12) NOT NULL, | |||
"BRANCH_TYPE" VARCHAR(12), | |||
"MERGE_BRANCH_UUID" VARCHAR(50), | |||
"PULL_REQUEST_BINARY" BLOB, | |||
"MANUAL_BASELINE_ANALYSIS_UUID" VARCHAR(40), | |||
"CREATED_AT" BIGINT NOT NULL, | |||
"UPDATED_AT" BIGINT NOT NULL, | |||
CONSTRAINT "PK_PROJECT_BRANCHES" PRIMARY KEY ("UUID") | |||
); | |||
CREATE UNIQUE INDEX "PROJECT_BRANCHES_KEE_KEY_TYPE" ON "PROJECT_BRANCHES" ("PROJECT_UUID", "KEE", "KEY_TYPE"); | |||
CREATE TABLE "NEW_CODE_PERIODS" ( | |||
"UUID" VARCHAR(40) NOT NULL, | |||
"PROJECT_UUID" VARCHAR(40), | |||
"BRANCH_UUID" VARCHAR(40), | |||
"TYPE" VARCHAR(30) NOT NULL, | |||
"VALUE" VARCHAR(40) NOT NULL, | |||
"UPDATED_AT" BIGINT NOT NULL, | |||
"CREATED_AT" BIGINT NOT NULL, | |||
CONSTRAINT "PK_NEW_CODE_PERIOD" PRIMARY KEY ("UUID") | |||
); |