diff options
author | simonbrandhof <simon.brandhof@gmail.com> | 2010-09-06 14:08:06 +0000 |
---|---|---|
committer | simonbrandhof <simon.brandhof@gmail.com> | 2010-09-06 14:08:06 +0000 |
commit | aeadc1f9129274949daaa57738c7c4550bdfbc7b (patch) | |
tree | 08dadf5ef7474fc41d1d48f74648f1ba8b55f34d /sonar-core | |
download | sonarqube-aeadc1f9129274949daaa57738c7c4550bdfbc7b.tar.gz sonarqube-aeadc1f9129274949daaa57738c7c4550bdfbc7b.zip |
SONAR-236 remove deprecated code from checkstyle plugin + display default value of rule parameters in Q profile console
Diffstat (limited to 'sonar-core')
140 files changed, 7883 insertions, 0 deletions
diff --git a/sonar-core/pom.xml b/sonar-core/pom.xml new file mode 100644 index 00000000000..2874417e059 --- /dev/null +++ b/sonar-core/pom.xml @@ -0,0 +1,90 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar</artifactId> + <version>2.3-SNAPSHOT</version> + </parent> + <artifactId>sonar-core</artifactId> + <name>Sonar :: Core</name> + <description>Core components shared to batch and server</description> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>test-jar</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>sonar-plugin-api</artifactId> + </dependency> + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-core</artifactId> + </dependency> + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-annotations</artifactId> + </dependency> + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-commons-annotations</artifactId> + </dependency> + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-entitymanager</artifactId> + </dependency> + <dependency> + <groupId>geronimo-spec</groupId> + <artifactId>geronimo-spec-jta</artifactId> + </dependency> + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-ehcache</artifactId> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-all</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest-all</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-classic</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.dbunit</groupId> + <artifactId>dbunit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>hsqldb</groupId> + <artifactId>hsqldb</artifactId> + <scope>test</scope> + </dependency> + </dependencies> +</project>
\ No newline at end of file diff --git a/sonar-core/src/main/java/org/sonar/api/database/configuration/DatabaseConfiguration.java b/sonar-core/src/main/java/org/sonar/api/database/configuration/DatabaseConfiguration.java new file mode 100644 index 00000000000..cd945c5425b --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/api/database/configuration/DatabaseConfiguration.java @@ -0,0 +1,68 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.api.database.configuration; + +import org.apache.commons.configuration.BaseConfiguration; +import org.sonar.api.database.DatabaseSession; +import org.sonar.jpa.session.DatabaseSessionFactory; + +import java.util.List; + +/** + * IMPORTANT : This class can't be moved to org.sonar.jpa.dao for backward-compatibility reasons. + * This class is still used in some plugins. + * + * @since 1.10 + */ +public class DatabaseConfiguration extends BaseConfiguration { + private DatabaseSessionFactory sessionFactory; + private DatabaseSession session; + + public DatabaseConfiguration(DatabaseSessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + load(); + } + + public DatabaseConfiguration(DatabaseSession session) { + this.session = session; + load(); + } + + public void load() { + clear(); + + List<Property> properties = getSession() + .createQuery("from " + Property.class.getSimpleName() + " p where p.resourceId is null and p.userId is null") + .getResultList(); + + if (properties != null) { + for (Property property : properties) { + setProperty(property.getKey(), property.getValue()); + } + } + } + + private DatabaseSession getSession() { + if (session != null) { + return session; + } + return sessionFactory.getSession(); + } +}
\ No newline at end of file diff --git a/sonar-core/src/main/java/org/sonar/api/database/configuration/Property.java b/sonar-core/src/main/java/org/sonar/api/database/configuration/Property.java new file mode 100644 index 00000000000..efafbcc508d --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/api/database/configuration/Property.java @@ -0,0 +1,149 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.api.database.configuration; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; +import org.sonar.api.database.BaseIdentifiable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Lob; +import javax.persistence.Table; + +/** + * IMPORTANT : This class can't be moved to org.sonar.jpa.dao for backward-compatibility reasons. + * This class is still used in some plugins. + * + * @since 1.10 + */ +@Entity +@Table(name = "properties") +public class Property extends BaseIdentifiable { + + @Column(name = "prop_key", updatable = true, nullable = true) + private String key; + + @Column(name = "text_value", updatable = true, nullable = true, length = 167772150) + @Lob + private char[] value; + + @Column(name = "resource_id", updatable = true, nullable = true) + private Integer resourceId; + + @Column(name = "user_id", updatable = true, nullable = true) + private Integer userId; + + public Property(String key, String value) { + this(key, value, null); + } + + public Property(String key, String value, Integer resourceId) { + this.key = key; + if (value != null) { + this.value = value.toCharArray(); + + } else { + this.value = null; + } + this.resourceId = resourceId; + } + + public Property() { + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + if (value != null) { + return new String(value); + } + return null; + } + + public void setValue(String value) { + if (value != null) { + this.value = value.toCharArray(); + } else { + this.value = null; + } + } + + public Integer getResourceId() { + return resourceId; + } + + public void setResourceId(Integer resourceId) { + this.resourceId = resourceId; + } + + public Integer getUserId() { + return userId; + } + + public Property setUserId(Integer userId) { + this.userId = userId; + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Property property = (Property) o; + if (!key.equals(property.key)) { + return false; + } + if (resourceId != null ? !resourceId.equals(property.resourceId) : property.resourceId != null) { + return false; + } + return !(userId != null ? !userId.equals(property.userId) : property.userId != null); + + } + + @Override + public int hashCode() { + int result = key.hashCode(); + result = 31 * result + (resourceId != null ? resourceId.hashCode() : 0); + result = 31 * result + (userId != null ? userId.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + .append("key", key) + .append("resource", resourceId) + .append("user", userId) + .append("value", value) + .toString(); + } +} diff --git a/sonar-core/src/main/java/org/sonar/api/database/configuration/ResourceDatabaseConfiguration.java b/sonar-core/src/main/java/org/sonar/api/database/configuration/ResourceDatabaseConfiguration.java new file mode 100644 index 00000000000..4cead063e31 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/api/database/configuration/ResourceDatabaseConfiguration.java @@ -0,0 +1,88 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.api.database.configuration; + +import org.apache.commons.configuration.BaseConfiguration; +import org.sonar.jpa.session.DatabaseSessionFactory; +import org.sonar.api.database.model.ResourceModel; + +import java.util.List; + +/** + * + * IMPORTANT : This class can't be moved to org.sonar.jpa.dao for backward-compatibility reasons. + * This class is still used in some plugins. + * + * @since 1.10 + */ +public class ResourceDatabaseConfiguration extends BaseConfiguration { + private final DatabaseSessionFactory sessionFactory; + private Integer resourceId = null; + + public ResourceDatabaseConfiguration(DatabaseSessionFactory sessionFactory, ResourceModel resource) { + this.sessionFactory = sessionFactory; + if (resource != null) { + this.resourceId = resource.getId(); + } + load(); + } + + public ResourceDatabaseConfiguration(DatabaseSessionFactory sessionFactory, Integer resourceId) { + this.sessionFactory = sessionFactory; + this.resourceId = resourceId; + load(); + } + + public ResourceDatabaseConfiguration(DatabaseSessionFactory sessionFactory, String resourceKey) { + this.sessionFactory = sessionFactory; + + ResourceModel resource = sessionFactory.getSession().getSingleResult(ResourceModel.class, "key", resourceKey); + if (resource != null) { + this.resourceId = resource.getId(); + } + load(); + } + + public void load() { + clear(); + + loadResourceProperties(); + } + + private void loadResourceProperties() { + if (resourceId != null) { + List<Property> properties = sessionFactory.getSession() + .createQuery("from " + Property.class.getSimpleName() + " p where p.resourceId=:resourceId and p.userId is null") + .setParameter("resourceId", resourceId) + .getResultList(); + + registerProperties(properties); + } + } + + private void registerProperties(List<Property> properties) { + if (properties != null) { + for (Property property : properties) { + setProperty(property.getKey(), property.getValue()); + } + } + } + +} diff --git a/sonar-core/src/main/java/org/sonar/core/plugin/JpaPlugin.java b/sonar-core/src/main/java/org/sonar/core/plugin/JpaPlugin.java new file mode 100644 index 00000000000..c178f59acaa --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/plugin/JpaPlugin.java @@ -0,0 +1,249 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.core.plugin; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; +import org.hibernate.annotations.Cascade; +import org.sonar.api.database.BaseIdentifiable; + +import javax.persistence.*; +import java.net.URI; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * Installed plugins + * + * @since 2.2 + */ +@Entity +@Table(name = "plugins") +public class JpaPlugin extends BaseIdentifiable { + + @Column(name = "plugin_key", updatable = true, nullable = false, length = 100) + private String key; + + @Column(name = "version", updatable = true, nullable = true, length = 100) + private String version; + + @Column(name = "name", updatable = true, nullable = true, length = 100) + private String name; + + @Column(name = "description", updatable = true, nullable = true, length = 3000) + private String description; + + @Column(name = "organization", updatable = true, nullable = true, length = 100) + private String organization; + + @Column(name = "organization_url", updatable = true, nullable = true, length = 500) + private String organizationUrl; + + @Column(name = "license", updatable = true, nullable = true, length = 50) + private String license; + + @Column(name = "installation_date", updatable = true, nullable = true) + private Date installationDate; + + @Column(name = "plugin_class", updatable = true, nullable = true, length = 100) + private String pluginClass; + + @Column(name = "homepage", updatable = true, nullable = true, length = 500) + private String homepage; + + @Column(name = "core", updatable = true, nullable = true) + private Boolean core; + + @Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, + org.hibernate.annotations.CascadeType.DELETE, + org.hibernate.annotations.CascadeType.MERGE, + org.hibernate.annotations.CascadeType.PERSIST, + org.hibernate.annotations.CascadeType.DELETE_ORPHAN}) + @OneToMany(mappedBy = "plugin", cascade = {CascadeType.ALL}, fetch = FetchType.EAGER) + private List<JpaPluginFile> files = new ArrayList<JpaPluginFile>(); + + public JpaPlugin() { + } + + public JpaPlugin(String pluginKey) { + if (StringUtils.isBlank(pluginKey)) { + throw new IllegalArgumentException("LocalExtension.pluginKey can not be blank"); + } + this.key = pluginKey; + } + + public String getKey() { + return key; + } + + public JpaPlugin setKey(String s) { + this.key = s; + return this; + } + + public String getName() { + return name; + } + + public JpaPlugin setName(String name) { + this.name = name; + return this; + } + + public String getDescription() { + return description; + } + + public JpaPlugin setDescription(String description) { + this.description = description; + return this; + } + + public String getOrganization() { + return organization; + } + + public JpaPlugin setOrganization(String organization) { + this.organization = organization; + return this; + } + + public String getOrganizationUrl() { + return organizationUrl; + } + + public JpaPlugin setOrganizationUrl(URI uri) { + this.organizationUrl = (uri != null ? uri.toString() : null); + return this; + } + + public JpaPlugin setOrganizationUrl(String s) { + this.organizationUrl = s; + return this; + } + + public String getLicense() { + return license; + } + + public JpaPlugin setLicense(String license) { + this.license = license; + return this; + } + + public String getVersion() { + return version; + } + + public JpaPlugin setVersion(String s) { + this.version = s; + return this; + } + + public Date getInstallationDate() { + return installationDate; + } + + public JpaPlugin setInstallationDate(Date installationDate) { + this.installationDate = installationDate; + return this; + } + + public String getPluginClass() { + return pluginClass; + } + + public JpaPlugin setPluginClass(String s) { + this.pluginClass = s; + return this; + } + + public String getHomepage() { + return homepage; + } + + public JpaPlugin setHomepage(URI uri) { + this.homepage = (uri != null ? uri.toString() : null); + return this; + } + + public JpaPlugin setHomepage(String s) { + this.homepage = s; + return this; + } + + public Boolean isCore() { + return core; + } + + public JpaPlugin setCore(Boolean b) { + this.core = b; + return this; + } + + public void createFile(String filename) { + JpaPluginFile file = new JpaPluginFile(this, filename); + this.files.add(file); + } + + public List<JpaPluginFile> getFiles() { + return files; + } + + public void removeFiles() { + files.clear(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + JpaPlugin other = (JpaPlugin) o; + return key.equals(other.key); + } + + @Override + public int hashCode() { + return key.hashCode(); + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + .append("id", getId()) + .append("key", key) + .append("version", version) + .append("homepage", homepage) + .append("installationDate", installationDate) + .toString(); + } + + + public static JpaPlugin create(String pluginKey) { + return new JpaPlugin(pluginKey); + } + +} diff --git a/sonar-core/src/main/java/org/sonar/core/plugin/JpaPluginDao.java b/sonar-core/src/main/java/org/sonar/core/plugin/JpaPluginDao.java new file mode 100644 index 00000000000..1fe44ab9e7b --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/plugin/JpaPluginDao.java @@ -0,0 +1,79 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.core.plugin; + +import org.sonar.api.BatchComponent; +import org.sonar.api.ServerComponent; +import org.sonar.api.database.DatabaseSession; +import org.sonar.jpa.session.DatabaseSessionFactory; + +import javax.persistence.Query; +import java.util.ArrayList; +import java.util.List; + +/** + * @since 2.2 + */ +public class JpaPluginDao implements BatchComponent, ServerComponent { + + private DatabaseSessionFactory sessionFactory; + + public JpaPluginDao(DatabaseSessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } + + public List<JpaPlugin> getPlugins() { + DatabaseSession session = sessionFactory.getSession(); + Query query = session.createQuery("FROM " + JpaPlugin.class.getSimpleName()); + return (List<JpaPlugin>) query.getResultList(); + } + + public List<JpaPluginFile> getPluginFiles() { + DatabaseSession session = sessionFactory.getSession(); + Query query = session.createQuery("FROM " + JpaPluginFile.class.getSimpleName()); + return (List<JpaPluginFile>) query.getResultList(); + } + + public void register(List<JpaPlugin> plugins) { + DatabaseSession session = sessionFactory.getSession(); + List<Integer> ids = new ArrayList<Integer>(); + for (JpaPlugin plugin : plugins) { + session.saveWithoutFlush(plugin); + ids.add(plugin.getId()); + } + session.commit(); + + if (ids.isEmpty()) { + session.createQuery("DELETE " + JpaPluginFile.class.getSimpleName()).executeUpdate(); + session.createQuery("DELETE " + JpaPlugin.class.getSimpleName()).executeUpdate(); + + } else { + Query query = session.createQuery("DELETE " + JpaPluginFile.class.getSimpleName() + " WHERE plugin.id NOT IN (:ids)"); + query.setParameter("ids", ids); + query.executeUpdate(); + + query = session.createQuery("DELETE " + JpaPlugin.class.getSimpleName() + " WHERE id NOT IN (:ids)"); + query.setParameter("ids", ids); + query.executeUpdate(); + + } + session.commit(); + } +} diff --git a/sonar-core/src/main/java/org/sonar/core/plugin/JpaPluginFile.java b/sonar-core/src/main/java/org/sonar/core/plugin/JpaPluginFile.java new file mode 100644 index 00000000000..03c4934e4aa --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/plugin/JpaPluginFile.java @@ -0,0 +1,74 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.core.plugin; + +import org.sonar.api.database.BaseIdentifiable; + +import javax.persistence.*; + +/** + * @since 2.2 + */ +@Entity +@Table(name = "plugin_files") +public class JpaPluginFile extends BaseIdentifiable { + + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "plugin_id") + private JpaPlugin plugin; + + @Column(name = "filename", updatable = true, nullable = false, length = 100) + private String filename; + + public JpaPluginFile() { + } + + public JpaPluginFile(JpaPlugin plugin, String filename) { + this.plugin = plugin; + this.filename = filename; + } + + public JpaPlugin getPlugin() { + return plugin; + } + + public String getPluginKey() { + return plugin.getKey(); + } + + public void setPlugin(JpaPlugin plugin) { + this.plugin = plugin; + } + + public String getFilename() { + return filename; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + public String getPath() { + return new StringBuilder() + .append(plugin.getKey()) + .append("/") + .append(filename).toString(); + } +} diff --git a/sonar-core/src/main/java/org/sonar/core/purge/AbstractPurge.java b/sonar-core/src/main/java/org/sonar/core/purge/AbstractPurge.java new file mode 100644 index 00000000000..fe1d9bf40b9 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/purge/AbstractPurge.java @@ -0,0 +1,117 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.core.purge; + +import org.sonar.api.batch.Purge; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.*; +import org.sonar.api.design.DependencyDto; + +import javax.persistence.Query; +import java.util.List; + +public abstract class AbstractPurge implements Purge { + + private static final int MAX_IN_ELEMENTS = 950; + + private int sqlInPageSize = MAX_IN_ELEMENTS; + private DatabaseSession session; + + public AbstractPurge(DatabaseSession session) { + this.session = session; + } + + protected DatabaseSession getSession() { + return session; + } + + /** + * Delete SNAPSHOTS and all dependent tables (MEASURES, ...) + */ + protected void deleteSnapshotData(List<Integer> snapshotIds) { + deleteMeasuresBySnapshotId(snapshotIds); + deleteSources(snapshotIds); + deleteViolations(snapshotIds); + deleteDependencies(snapshotIds); + deleteSnapshots(snapshotIds); + } + + protected void deleteDependencies(List<Integer> snapshotIds) { + executeQuery(snapshotIds, "delete from " + DependencyDto.class.getSimpleName() + " d where d.fromSnapshotId in (:ids)"); + executeQuery(snapshotIds, "delete from " + DependencyDto.class.getSimpleName() + " d where d.toSnapshotId in (:ids)"); + } + + /** + * Delete all measures, including MEASURE_DATA + */ + protected void deleteMeasuresBySnapshotId(List<Integer> snapshotIds) { + executeQuery(snapshotIds, "delete from " + MeasureData.class.getSimpleName() + " m where m.snapshotId in (:ids)"); + executeQuery(snapshotIds, "delete from " + MeasureModel.class.getSimpleName() + " m where m.snapshotId in (:ids)"); + } + + /** + * Delete all measures, including MEASURE_DATA + */ + protected void deleteMeasuresById(List<Integer> measureIds) { + executeQuery(measureIds, "delete from " + MeasureData.class.getSimpleName() + " m where m.measure.id in (:ids)"); + executeQuery(measureIds, "delete from " + MeasureModel.class.getSimpleName() + " m where m.id in (:ids)"); + } + + /** + * Delete SNAPSHOT_SOURCES table + */ + protected void deleteSources(List<Integer> snapshotIds) { + executeQuery(snapshotIds, "delete from " + SnapshotSource.class.getSimpleName() + " e where e.snapshotId in (:ids)"); + } + + /** + * Delete violations (RULE_FAILURES table) + */ + protected void deleteViolations(List<Integer> snapshotIds) { + executeQuery(snapshotIds, "delete from " + RuleFailureModel.class.getSimpleName() + " e where e.snapshotId in (:ids)"); + } + + /** + * Delete SNAPSHOTS table + */ + protected void deleteSnapshots(List<Integer> snapshotIds) { + executeQuery(snapshotIds, "delete from " + Snapshot.class.getSimpleName() + " s where s.id in (:ids)"); + } + + + /** + * Paginate execution of SQL requests to avoid exceeding size of rollback segment + */ + protected void executeQuery(List<Integer> ids, String hql) { + if (ids == null || ids.isEmpty()) { + return; + } + + int index = 0; + while (index < ids.size()) { + Query query = session.createQuery(hql); + List<Integer> paginedSids = ids.subList(index, Math.min(ids.size(), index + sqlInPageSize)); + query.setParameter("ids", paginedSids); + query.executeUpdate(); + index += sqlInPageSize; + session.commit(); + } + } +} diff --git a/sonar-core/src/main/java/org/sonar/core/purge/DefaultPurgeContext.java b/sonar-core/src/main/java/org/sonar/core/purge/DefaultPurgeContext.java new file mode 100644 index 00000000000..f2106a6bd58 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/purge/DefaultPurgeContext.java @@ -0,0 +1,86 @@ +package org.sonar.core.purge; + +import org.apache.commons.lang.builder.ToStringBuilder; +import org.sonar.api.batch.PurgeContext; +import org.sonar.api.database.model.Snapshot; + +public class DefaultPurgeContext implements PurgeContext { + + private Integer currentSid; + private Integer lastSid; + + public DefaultPurgeContext() { + } + + public DefaultPurgeContext(Snapshot currentSnapshot) { + this(currentSnapshot, null); + } + + public DefaultPurgeContext(Snapshot currentSnapshot, Snapshot lastSnapshot) { + if (currentSnapshot != null) { + currentSid = currentSnapshot.getId(); + } + if (lastSnapshot != null) { + lastSid = lastSnapshot.getId(); + } + } + + public DefaultPurgeContext(Integer currentSid, Integer lastSid) { + this.currentSid = currentSid; + this.lastSid = lastSid; + } + + public DefaultPurgeContext setLastSnapshotId(Integer lastSid) { + this.lastSid = lastSid; + return this; + } + + public DefaultPurgeContext setCurrentSnapshotId(Integer currentSid) { + this.currentSid = currentSid; + return this; + } + + public Integer getPreviousSnapshotId() { + return lastSid; + } + + public Integer getLastSnapshotId() { + return currentSid; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + DefaultPurgeContext context = (DefaultPurgeContext) o; + + if (!currentSid.equals(context.currentSid)) { + return false; + } + if (lastSid != null ? !lastSid.equals(context.lastSid) : context.lastSid != null) { + return false; + } + + return true; + } + + @Override + public int hashCode() { + int result = lastSid != null ? lastSid.hashCode() : 0; + result = 31 * result + currentSid.hashCode(); + return result; + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .append("currentSid", currentSid) + .append("lastSid", lastSid) + .toString(); + } +} diff --git a/sonar-core/src/main/java/org/sonar/core/qualitymodel/DefaultModelProvider.java b/sonar-core/src/main/java/org/sonar/core/qualitymodel/DefaultModelProvider.java new file mode 100644 index 00000000000..7f8f561bc97 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/qualitymodel/DefaultModelProvider.java @@ -0,0 +1,129 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.core.qualitymodel; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.LoggerFactory; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.qualitymodel.Model; +import org.sonar.api.qualitymodel.ModelDefinition; +import org.sonar.api.qualitymodel.ModelProvider; +import org.sonar.api.utils.Logs; +import org.sonar.api.utils.SonarException; +import org.sonar.jpa.session.DatabaseSessionFactory; + +import javax.persistence.Query; + +public class DefaultModelProvider implements ModelProvider { + + private ModelDefinition[] definitions; + private DatabaseSessionFactory sessionFactory; + + public DefaultModelProvider(DatabaseSessionFactory sessionFactory, ModelDefinition[] definitions) { + this.sessionFactory = sessionFactory; + this.definitions = definitions; + } + + /** + * this constructor is used when there are no templates + */ + public DefaultModelProvider(DatabaseSessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + this.definitions = new ModelDefinition[0]; + } + + /** + * Executed when the server starts + */ + public void registerDefinitions() { + DatabaseSession session = sessionFactory.getSession(); + for (ModelDefinition definition : definitions) { + if (StringUtils.isNotBlank(definition.getName()) && !exists(session, definition.getName())) { + Logs.INFO.info("Register quality model: " + definition.getName()); + Model model = definition.create(); + if (StringUtils.isBlank(model.getName())) { + model.setName(definition.getName()); + } + insert(session, model); + session.commit(); + } + } + } + + public Model reset(String name) { + ModelDefinition definition = findDefinitionByName(name); + if (definition == null) { + throw new SonarException("Can not reset quality model. Definition not found: " + name); + } + + LoggerFactory.getLogger(getClass()).info("Reset quality model: " + name); + Model model = definition.create(); + return reset(model); + } + + + + Model reset(Model model) { + DatabaseSession session = sessionFactory.getSession(); + try { + delete(session, model.getName()); + model = insert(session, model); + session.commit(); + return model; + + } catch (RuntimeException e) { + session.rollback(); + throw e; + } + } + + public ModelDefinition findDefinitionByName(String name) { + for (ModelDefinition definition : definitions) { + if (StringUtils.equals(name, definition.getName())) { + return definition; + } + } + return null; + } + + public Model findByName(String name) { + DatabaseSession session = sessionFactory.getSession(); + return session.getSingleResult(Model.class, "name", name); + } + + public static void delete(DatabaseSession session, String name) { + Model model = session.getSingleResult(Model.class, "name", name); + if (model != null) { + session.removeWithoutFlush(model); + session.commit(); + } + } + + public static Model insert(DatabaseSession session, Model model) { + return (Model) session.saveWithoutFlush(model); + } + + public static boolean exists(DatabaseSession session, String name) { + Query query = session.getEntityManager().createQuery("SELECT COUNT(qm) FROM " + Model.class.getSimpleName() + " qm WHERE qm.name=:name"); + query.setParameter("name", name); + Number count = (Number) query.getSingleResult(); + return count.intValue() > 0; + } +} diff --git a/sonar-core/src/main/java/org/sonar/core/rule/DefaultRuleProvider.java b/sonar-core/src/main/java/org/sonar/core/rule/DefaultRuleProvider.java new file mode 100644 index 00000000000..faac5971355 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/rule/DefaultRuleProvider.java @@ -0,0 +1,75 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.core.rule; + +import org.apache.commons.lang.StringUtils; +import org.sonar.api.rules.Rule; +import org.sonar.api.rules.RuleProvider; +import org.sonar.api.rules.RuleQuery; +import org.sonar.jpa.session.DatabaseSessionFactory; + +import javax.persistence.Query; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +public class DefaultRuleProvider implements RuleProvider { + + private DatabaseSessionFactory sessionFactory; + + public DefaultRuleProvider(DatabaseSessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } + + public Rule findByKey(String repositoryKey, String key) { + return sessionFactory.getSession().getSingleResult(Rule.class, "pluginName", repositoryKey, "key", key, "enabled", true); + } + + public Rule find(RuleQuery query) { + return (Rule) createHqlQuery(query).getSingleResult(); + } + + public Collection<Rule> findAll(RuleQuery query) { + return createHqlQuery(query).getResultList(); + } + + private Query createHqlQuery(RuleQuery query) { + StringBuilder hql = new StringBuilder().append("from ").append(Rule.class.getSimpleName()).append(" where enabled=true "); + Map<String,Object> params = new HashMap<String,Object>(); + if (StringUtils.isNotBlank(query.getRepositoryKey())) { + hql.append("AND pluginName=:repositoryKey"); + params.put("repositoryKey", query.getRepositoryKey()); + } + if (StringUtils.isNotBlank(query.getKey())) { + hql.append("AND key=:key"); + params.put("key", query.getKey()); + } + if (StringUtils.isNotBlank(query.getConfigKey())) { + hql.append("AND configKey=:configKey"); + params.put("configKey", query.getConfigKey()); + } + + Query hqlQuery = sessionFactory.getSession().createQuery(hql.toString()); + for (Map.Entry<String, Object> entry : params.entrySet()) { + hqlQuery.setParameter(entry.getKey(), entry.getValue()); + } + return hqlQuery; + } +} diff --git a/sonar-core/src/main/java/org/sonar/jpa/dao/AsyncMeasuresDao.java b/sonar-core/src/main/java/org/sonar/jpa/dao/AsyncMeasuresDao.java new file mode 100644 index 00000000000..4e2ece885ab --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/dao/AsyncMeasuresDao.java @@ -0,0 +1,196 @@ +/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.jpa.dao;
+
+import org.sonar.api.database.DatabaseSession;
+import org.sonar.api.database.model.AsyncMeasureSnapshot;
+import org.sonar.api.database.model.MeasureModel;
+import org.sonar.api.database.model.ResourceModel;
+import org.sonar.api.database.model.Snapshot;
+
+import javax.persistence.NoResultException;
+import javax.persistence.Query;
+import java.util.Date;
+import java.util.List;
+
+public class AsyncMeasuresDao extends BaseDao {
+
+ public AsyncMeasuresDao(DatabaseSession session) {
+ super(session);
+ }
+
+ public MeasureModel getAsyncMeasure(Long asyncMeasureId) {
+ return getSession().getEntityManager().find(MeasureModel.class, asyncMeasureId);
+ }
+
+ public void deleteAsyncMeasure(MeasureModel asyncMeasure) {
+ deleteAsyncMeasureSnapshots(asyncMeasure.getId());
+ getSession().remove(asyncMeasure);
+ }
+
+ public Snapshot getPreviousSnapshot(Snapshot s) {
+ try {
+ return (Snapshot) getSession().createQuery(
+ "SELECT s FROM Snapshot s " +
+ "WHERE s.createdAt<:date " +
+ "AND s.scope=:scope " +
+ "AND s.resourceId=:resourceId " +
+ "ORDER BY s.createdAt DESC")
+ .setParameter("date", s.getCreatedAt())
+ .setParameter("scope", s.getScope())
+ .setParameter("resourceId", s.getResourceId())
+ .setMaxResults(1)
+ .getSingleResult();
+ } catch (NoResultException ex) {
+ return null;
+ }
+ }
+
+ public List<Snapshot> getNextSnapshotsUntilDate(MeasureModel measure, Date date) {
+ Query query = getSession().createQuery(
+ "SELECT s FROM Snapshot s " +
+ "WHERE s.resourceId=:projectId " +
+ "AND s.createdAt>=:beginDate " +
+ (date != null ? "AND s.createdAt<:endDate " : "") +
+ "AND s.scope=:scope " +
+ "ORDER BY s.createdAt ASC ")
+ .setParameter("projectId", measure.getProjectId())
+ .setParameter("beginDate", measure.getMeasureDate())
+ .setParameter("scope", ResourceModel.SCOPE_PROJECT);
+ if (date != null) {
+ query.setParameter("endDate", date);
+ }
+ return query.getResultList();
+ }
+
+ public AsyncMeasureSnapshot createAsyncMeasureSnapshot(Long asyncMeasureId, Integer snapshotId, Date AsyncMeasureDate, Date snapshotDate, Integer metricId, Integer projectId) {
+ AsyncMeasureSnapshot asyncMeasureSnapshot = new AsyncMeasureSnapshot(asyncMeasureId, snapshotId, AsyncMeasureDate, snapshotDate, metricId, projectId);
+ getSession().save(asyncMeasureSnapshot);
+ return asyncMeasureSnapshot;
+ }
+
+ public void updateAsyncMeasureSnapshot(AsyncMeasureSnapshot asyncMeasureSnapshot, Snapshot snapshot) {
+ if (snapshot != null) {
+ asyncMeasureSnapshot.setSnapshotId(snapshot.getId());
+ asyncMeasureSnapshot.setSnapshotDate(snapshot.getCreatedAt());
+ } else {
+ asyncMeasureSnapshot.setSnapshotId(null);
+ asyncMeasureSnapshot.setSnapshotDate(null);
+ }
+ getSession().merge(asyncMeasureSnapshot);
+ }
+
+ public void removeSnapshotFromAsyncMeasureSnapshot(AsyncMeasureSnapshot asyncMeasureSnapshot) {
+ asyncMeasureSnapshot.setSnapshotId(null);
+ asyncMeasureSnapshot.setSnapshotDate(null);
+ getSession().merge(asyncMeasureSnapshot);
+ }
+
+
+ public AsyncMeasureSnapshot getNextAsyncMeasureSnapshot(Integer projetcId, Integer metricId, Date date) {
+ try {
+ return (AsyncMeasureSnapshot) getSession().createQuery(
+ "SELECT ams FROM AsyncMeasureSnapshot ams " +
+ "WHERE ams.projectId=:projectId " +
+ "AND ams.metricId=:metricId " +
+ "AND ams.measureDate>:date " +
+ "ORDER BY ams.measureDate ASC")
+ .setParameter("projectId", projetcId)
+ .setParameter("metricId", metricId)
+ .setParameter("date", date)
+ .setMaxResults(1)
+ .getSingleResult();
+ } catch (NoResultException ex) {
+ return null;
+ }
+ }
+
+ public List<AsyncMeasureSnapshot> getNextAsyncMeasureSnapshotsUntilDate(MeasureModel asyncMeasure, Date endDate) {
+ Query query = getSession().createQuery(
+ "SELECT ams FROM AsyncMeasureSnapshot ams " +
+ "WHERE ams.projectId=:projectId " +
+ "AND ams.metricId=:metricId " +
+ (endDate != null ? "AND ams.measureDate<:endDate " : "") +
+ "AND ams.snapshotDate>=:measureDate " +
+ "ORDER BY ams.snapshotDate ASC ")
+ .setParameter("projectId", asyncMeasure.getProjectId())
+ .setParameter("metricId", asyncMeasure.getMetric().getId())
+ .setParameter("measureDate", asyncMeasure.getMeasureDate());
+ if (endDate != null) {
+ query.setParameter("endDate", endDate);
+ }
+ return query.getResultList();
+ }
+
+ public List<AsyncMeasureSnapshot> getPreviousAsyncMeasureSnapshots(Integer projectId, Date beginDate, Date endDate) {
+ Query query = getSession().createQuery(
+ "SELECT ams FROM AsyncMeasureSnapshot ams " +
+ "WHERE ams.projectId=:projectId " +
+ "AND ams.measureDate<=:endDate " +
+ (beginDate != null ? "AND ams.measureDate>:beginDate " : "") +
+ "AND ams.snapshotId IS NULL " +
+ "ORDER BY ams.measureDate ASC")
+ .setParameter("projectId", projectId)
+ .setParameter("endDate", endDate);
+ if (beginDate != null) {
+ query.setParameter("beginDate", beginDate);
+ }
+ return query.getResultList();
+ }
+
+ public List<AsyncMeasureSnapshot> getAsyncMeasureSnapshotsFromSnapshotId(Integer snapshotId, List<Integer> metricIdsToExclude) {
+ Query query = getSession().createQuery(
+ "SELECT ams FROM AsyncMeasureSnapshot ams " +
+ "WHERE ams.snapshotId=:snapshotId " +
+ (!metricIdsToExclude.isEmpty() ? "AND ams.metricId NOT IN (:metricIdsToExclude) " : "") +
+ "ORDER BY ams.measureDate ASC")
+ .setParameter("snapshotId", snapshotId);
+ if (!metricIdsToExclude.isEmpty()) {
+ query.setParameter("metricIdsToExclude", metricIdsToExclude);
+ }
+ return query.getResultList();
+ }
+
+ public AsyncMeasureSnapshot getLastAsyncMeasureSnapshot(Integer projetcId, Integer metricId, Date date) {
+ try {
+ return (AsyncMeasureSnapshot) getSession().createQuery(
+ "SELECT ams FROM AsyncMeasureSnapshot ams " +
+ "WHERE ams.projectId=:projectId " +
+ "AND ams.metricId=:metricId " +
+ "AND ams.measureDate<:date " +
+ "ORDER BY ams.measureDate DESC")
+ .setParameter("projectId", projetcId)
+ .setParameter("metricId", metricId)
+ .setParameter("date", date)
+ .setMaxResults(1)
+ .getSingleResult();
+ } catch (NoResultException ex) {
+ return null;
+ }
+ }
+
+ public void deleteAsyncMeasureSnapshots(Long asyncMeasureId) {
+ getSession().createQuery(
+ "DELETE FROM AsyncMeasureSnapshot ams WHERE ams.measureId=:measureId")
+ .setParameter("measureId", asyncMeasureId)
+ .executeUpdate();
+ }
+
+}
diff --git a/sonar-core/src/main/java/org/sonar/jpa/dao/AsyncMeasuresService.java b/sonar-core/src/main/java/org/sonar/jpa/dao/AsyncMeasuresService.java new file mode 100644 index 00000000000..ae296d1e356 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/dao/AsyncMeasuresService.java @@ -0,0 +1,130 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.dao; + +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.AsyncMeasureSnapshot; +import org.sonar.api.database.model.MeasureModel; +import org.sonar.api.database.model.Snapshot; + +import java.util.*; + +public class AsyncMeasuresService { + private final DatabaseSession session; + + public AsyncMeasuresService(DatabaseSession session) { + this.session = session; + } + + public void refresh(Snapshot snapshot) { + AsyncMeasuresDao dao = new AsyncMeasuresDao(session); + Snapshot previousSnapshot = dao.getPreviousSnapshot(snapshot); + Date datePreviousSnapshot = (previousSnapshot != null ? previousSnapshot.getCreatedAt() : null); + + List<AsyncMeasureSnapshot> previousAsyncMeasureSnapshots = dao.getPreviousAsyncMeasureSnapshots( + snapshot.getResourceId(), datePreviousSnapshot, snapshot.getCreatedAt()); + if (previousSnapshot != null) { + previousAsyncMeasureSnapshots.addAll(dao.getAsyncMeasureSnapshotsFromSnapshotId( + previousSnapshot.getId(), getMetricIds(previousAsyncMeasureSnapshots))); + } + + for (AsyncMeasureSnapshot asyncMeasureSnapshot : purge(previousAsyncMeasureSnapshots)) { + if (asyncMeasureSnapshot.getSnapshotId() == null) { + dao.updateAsyncMeasureSnapshot(asyncMeasureSnapshot, snapshot); + } else { + dao.createAsyncMeasureSnapshot( + asyncMeasureSnapshot.getMeasureId(), snapshot.getId(), asyncMeasureSnapshot.getMeasureDate(), + snapshot.getCreatedAt(), asyncMeasureSnapshot.getMetricId(), asyncMeasureSnapshot.getProjectId()); + } + } + session.commit(); + } + + public void registerMeasure(Long id) { + AsyncMeasuresDao dao = new AsyncMeasuresDao(session); + registerMeasure(dao.getAsyncMeasure(id), dao); + } + + private List<Integer> getMetricIds(List<AsyncMeasureSnapshot> list) { + List<Integer> ids = new ArrayList<Integer>(); + for (AsyncMeasureSnapshot ams : list) { + ids.add(ams.getMetricId()); + } + return ids; + } + + private Collection<AsyncMeasureSnapshot> purge(List<AsyncMeasureSnapshot> list) { + Map<Integer, AsyncMeasureSnapshot> measuresById = new LinkedHashMap<Integer, AsyncMeasureSnapshot>(); + for (AsyncMeasureSnapshot currentAsyncMeasureSnapshot : list) { + AsyncMeasureSnapshot asyncMeasureSnapshotFromMap = measuresById.get(currentAsyncMeasureSnapshot.getMetricId()); + if (asyncMeasureSnapshotFromMap != null) { + if (asyncMeasureSnapshotFromMap.getMeasureDate().before(currentAsyncMeasureSnapshot.getMeasureDate())) { + measuresById.put(currentAsyncMeasureSnapshot.getMetricId(), currentAsyncMeasureSnapshot); + } + } else { + measuresById.put(currentAsyncMeasureSnapshot.getMetricId(), currentAsyncMeasureSnapshot); + } + } + return measuresById.values(); + } + + + public void deleteMeasure(Long id) { + AsyncMeasuresDao dao = new AsyncMeasuresDao(session); + MeasureModel measure = dao.getAsyncMeasure(id); + AsyncMeasureSnapshot pastAsyncMeasureSnapshot = dao.getLastAsyncMeasureSnapshot(measure.getProjectId(), + measure.getMetric().getId(), measure.getMeasureDate()); + dao.deleteAsyncMeasure(measure); + if (pastAsyncMeasureSnapshot != null) { + MeasureModel pastAsyncMeasure = dao.getAsyncMeasure(pastAsyncMeasureSnapshot.getMeasureId()); + dao.deleteAsyncMeasureSnapshots(pastAsyncMeasureSnapshot.getMeasureId()); + registerMeasure(pastAsyncMeasure, dao); + } + session.commit(); + } + + private void registerMeasure(MeasureModel measure, AsyncMeasuresDao dao) { + AsyncMeasureSnapshot nextAsyncMeasureSnapshot = dao.getNextAsyncMeasureSnapshot( + measure.getProjectId(), measure.getMetric().getId(), measure.getMeasureDate()); + Date dateNextAsyncMeasure = (nextAsyncMeasureSnapshot != null) ? nextAsyncMeasureSnapshot.getMeasureDate() : null; + + List<AsyncMeasureSnapshot> nextAsyncMeasureSnapshots = dao.getNextAsyncMeasureSnapshotsUntilDate( + measure, dateNextAsyncMeasure); + if (!nextAsyncMeasureSnapshots.isEmpty()) { + for (AsyncMeasureSnapshot asyncMeasureSnapshot : nextAsyncMeasureSnapshots) { + dao.createAsyncMeasureSnapshot(measure.getId(), asyncMeasureSnapshot.getSnapshotId(), measure.getMeasureDate(), + asyncMeasureSnapshot.getSnapshotDate(), measure.getMetric().getId(), measure.getProjectId()); + dao.removeSnapshotFromAsyncMeasureSnapshot(asyncMeasureSnapshot); + } + } else { + List<Snapshot> nextSnapshotsUntilDate = dao.getNextSnapshotsUntilDate(measure, dateNextAsyncMeasure); + if (!nextSnapshotsUntilDate.isEmpty()) { + for (Snapshot nextSnapshot : nextSnapshotsUntilDate) { + dao.createAsyncMeasureSnapshot(measure.getId(), nextSnapshot.getId(), measure.getMeasureDate(), + nextSnapshot.getCreatedAt(), measure.getMetric().getId(), measure.getProjectId()); + } + } else { + dao.createAsyncMeasureSnapshot(measure.getId(), null, measure.getMeasureDate(), + null, measure.getMetric().getId(), measure.getProjectId()); + } + } + } + +}
\ No newline at end of file diff --git a/sonar-core/src/main/java/org/sonar/jpa/dao/BaseDao.java b/sonar-core/src/main/java/org/sonar/jpa/dao/BaseDao.java new file mode 100644 index 00000000000..3c5f441bf43 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/dao/BaseDao.java @@ -0,0 +1,38 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ + +package org.sonar.jpa.dao; + +import org.sonar.api.database.DatabaseSession; + +public class BaseDao { + + private final DatabaseSession session; + + public BaseDao(DatabaseSession session) { + super(); + this.session = session; + } + + public DatabaseSession getSession() { + return session; + } + +} diff --git a/sonar-core/src/main/java/org/sonar/jpa/dao/DaoFacade.java b/sonar-core/src/main/java/org/sonar/jpa/dao/DaoFacade.java new file mode 100644 index 00000000000..078b5c65396 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/dao/DaoFacade.java @@ -0,0 +1,53 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.dao; + +public class DaoFacade { + + private final RulesDao rulesDao; + private final MeasuresDao measuresDao; + private final AsyncMeasuresDao asyncMeasureDao; + private final ProfilesDao profilesDao; + + public DaoFacade(ProfilesDao profilesDao, RulesDao rulesDao, MeasuresDao measuresDao, AsyncMeasuresDao asyncMeasureDao) { + super(); + this.rulesDao = rulesDao; + this.measuresDao = measuresDao; + this.asyncMeasureDao = asyncMeasureDao; + this.profilesDao = profilesDao; + } + + public RulesDao getRulesDao() { + return rulesDao; + } + + public ProfilesDao getProfilesDao() { + return profilesDao; + } + + public MeasuresDao getMeasuresDao() { + return measuresDao; + } + + public AsyncMeasuresDao getAsyncMeasureDao() { + return asyncMeasureDao; + } + +} diff --git a/sonar-core/src/main/java/org/sonar/jpa/dao/MeasuresDao.java b/sonar-core/src/main/java/org/sonar/jpa/dao/MeasuresDao.java new file mode 100644 index 00000000000..77303c1c9ba --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/dao/MeasuresDao.java @@ -0,0 +1,120 @@ +/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.jpa.dao;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.Predicate;
+import org.sonar.api.database.DatabaseSession;
+import org.sonar.api.measures.Metric;
+
+import java.util.*;
+
+public class MeasuresDao extends BaseDao {
+
+ private final Map<String, Metric> metricsByName = new HashMap<String, Metric>();
+
+ public MeasuresDao(DatabaseSession session) {
+ super(session);
+ }
+
+ public Metric getMetric(Metric metric) {
+ return getMetricsByName().get(metric.getKey());
+ }
+
+ public List<Metric> getMetrics(List<Metric> metrics) {
+ List<Metric> result = new ArrayList<Metric>();
+ for (Metric metric : metrics) {
+ result.add(getMetric(metric));
+ }
+ return result;
+ }
+
+ public Metric getMetric(String metricName) {
+ return getMetricsByName().get(metricName);
+ }
+
+ public Collection<Metric> getMetrics() {
+ return getMetricsByName().values();
+ }
+
+ public Collection<Metric> getEnabledMetrics() {
+ return CollectionUtils.select(getMetricsByName().values(), new Predicate() {
+ public boolean evaluate(Object o) {
+ return ((Metric) o).getEnabled();
+ }
+ });
+ }
+
+ public Collection<Metric> getUserDefinedMetrics() {
+ return CollectionUtils.select(getMetricsByName().values(), new Predicate() {
+ public boolean evaluate(Object o) {
+ Metric m = (Metric) o;
+ return (m.getEnabled() && m.getOrigin() != Metric.Origin.JAV);
+ }
+ });
+ }
+
+ public void disableAutomaticMetrics() {
+ getSession().createQuery("update " + Metric.class.getSimpleName() + " m set m.enabled=false where m.userManaged=false").executeUpdate();
+ getSession().commit();
+ metricsByName.clear();
+ }
+
+ public void registerMetrics(Collection<Metric> metrics) {
+ if (metrics != null) {
+ for (Metric metric : metrics) {
+ metric.setEnabled(Boolean.TRUE);
+ persistMetric(metric);
+ }
+ getSession().commit();
+ }
+ }
+
+ public void persistMetric(Metric metric) {
+ Metric dbMetric = getMetric(metric);
+ if (dbMetric != null) {
+ dbMetric.merge(metric);
+ getSession().getEntityManager().merge(dbMetric);
+
+ } else {
+ getSession().getEntityManager().persist(metric);
+ }
+
+ metricsByName.clear();
+ }
+
+ public void disabledMetrics(Collection<Metric> metrics) {
+ for (Metric metric : metrics) {
+ metric.setEnabled(Boolean.FALSE);
+ getSession().getEntityManager().persist(metric);
+ metricsByName.put(metric.getName(), metric);
+ }
+ }
+
+ private Map<String, Metric> getMetricsByName() {
+ if (metricsByName.isEmpty()) {
+ List<Metric> metrics = getSession().getResults(Metric.class);
+ for (Metric metric : metrics) {
+ metricsByName.put(metric.getKey(), metric);
+ }
+ }
+ return metricsByName;
+ }
+}
diff --git a/sonar-core/src/main/java/org/sonar/jpa/dao/ProfilesDao.java b/sonar-core/src/main/java/org/sonar/jpa/dao/ProfilesDao.java new file mode 100644 index 00000000000..65944ab720b --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/dao/ProfilesDao.java @@ -0,0 +1,66 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.dao; + +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.ResourceModel; +import org.sonar.api.profiles.RulesProfile; + +import java.util.List; + +public class ProfilesDao extends BaseDao { + + public ProfilesDao(DatabaseSession session) { + super(session); + } + + public List<RulesProfile> getActiveProfiles() { + return getSession().getResults(RulesProfile.class, "defaultProfile", true); + } + + public RulesProfile getActiveProfile(String languageKey, String projectResourceKey) { + ResourceModel projectResource = getSession().getSingleResult(ResourceModel.class, "key", projectResourceKey, "scope", ResourceModel.SCOPE_PROJECT); + if (projectResource != null && projectResource.getRulesProfile() != null) { + return projectResource.getRulesProfile(); + } + return getSession().getSingleResult(RulesProfile.class, "defaultProfile", true, "language", languageKey); + } + + public List<RulesProfile> getProfiles(String languageKey) { + return getSession().getResults(RulesProfile.class, "language", languageKey); + } + + public List<RulesProfile> getProfiles() { + return getSession().getResults(RulesProfile.class); + } + + public List<RulesProfile> getProvidedProfiles() { + return getSession().getResults(RulesProfile.class, "provided", true); + } + + public RulesProfile getProfile(String languageKey, String profileName) { + return getSession().getSingleResult(RulesProfile.class, "language", languageKey, "name", profileName); + } + + public RulesProfile getProfileById(int profileId) { + return getSession().getEntityManager().getReference(RulesProfile.class, profileId); + } + +} diff --git a/sonar-core/src/main/java/org/sonar/jpa/dao/RulesDao.java b/sonar-core/src/main/java/org/sonar/jpa/dao/RulesDao.java new file mode 100644 index 00000000000..3f5788bae6c --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/dao/RulesDao.java @@ -0,0 +1,138 @@ +/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.jpa.dao;
+
+import org.sonar.api.database.DatabaseSession;
+import org.sonar.api.database.model.RuleFailureModel;
+import org.sonar.api.database.model.Snapshot;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.rules.*;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class RulesDao extends BaseDao {
+
+ private List<RulesCategory> rulesCategories;
+
+ public RulesDao(DatabaseSession session) {
+ super(session);
+ }
+
+ public List<Rule> getRules() {
+ return getSession().getResults(Rule.class, "enabled", true);
+ }
+
+ public List<Rule> getRulesByPlugin(String pluginKey) {
+ return getSession().getResults(Rule.class, "pluginName", pluginKey, "enabled", true);
+ }
+
+ public List<Rule> getRulesByCategory(RulesCategory categ) {
+ List<Rule> result = new ArrayList<Rule>();
+ for (Rule rule : getRules()) {
+ if (rule.getRulesCategory().equals(categ)) {
+ result.add(rule);
+ }
+ }
+ return result;
+ }
+
+ public Rule getRuleByKey(String pluginKey, String ruleKey) {
+ return getSession().getSingleResult(Rule.class, "key", ruleKey, "pluginName", pluginKey, "enabled", true);
+ }
+
+ public Long countRules(List<String> plugins, String categoryName) {
+ return (Long) getSession().createQuery(
+ "SELECT COUNT(r) FROM Rule r WHERE r.pluginName IN (:pluginNames) AND r.rulesCategory=:rulesCategory AND r.enabled=true").
+ setParameter("pluginNames", plugins).
+ setParameter("rulesCategory", getCategory(categoryName)).
+ getSingleResult();
+ }
+
+ public List<RulesCategory> getCategories() {
+ if (rulesCategories == null) {
+ rulesCategories = getSession().getResults(RulesCategory.class);
+ }
+ return rulesCategories;
+ }
+
+ public RulesCategory getCategory(String key) {
+ return getSession().getSingleResult(RulesCategory.class, "name", key);
+ }
+
+
+ public List<RuleParam> getRuleParams() {
+ return getSession().getResults(RuleParam.class);
+ }
+
+ public RuleParam getRuleParam(Rule rule, String paramKey) {
+ return getSession().getSingleResult(RuleParam.class, "rule", rule, "key", paramKey);
+ }
+
+ public void addActiveRulesToProfile(List<ActiveRule> activeRules, int profileId, String pluginKey) {
+ RulesProfile rulesProfile = getProfileById(profileId);
+ for (ActiveRule activeRule : activeRules) {
+ synchronizeRuleOfActiveRule(activeRule, pluginKey);
+ activeRule.setRulesProfile(rulesProfile);
+ getSession().save(activeRule);
+ }
+ }
+
+ public void deleteActiveRuleParameters(RuleParam ruleParam) {
+ getSession().createQuery(
+ "DELETE FROM ActiveRuleParam arp WHERE ruleParam=:param")
+ .setParameter("param", ruleParam)
+ .executeUpdate();
+ }
+
+ public List<RuleFailureModel> getViolations(Snapshot snapshot) {
+ return getSession().getResults(RuleFailureModel.class, "snapshotId", snapshot.getId());
+ }
+
+ public void synchronizeRuleOfActiveRule(ActiveRule activeRule, String pluginKey) {
+ Rule rule = activeRule.getRule();
+ Rule ruleFromDataBase = getRuleByKey(pluginKey, rule.getKey());
+ activeRule.setRule(ruleFromDataBase);
+ List<RuleParam> ruleParamsFromDataBase = getRuleParams();
+ for (ActiveRuleParam activeRuleParam : activeRule.getActiveRuleParams()) {
+ boolean found = false;
+ Iterator<RuleParam> iterator = ruleParamsFromDataBase.iterator();
+ while (iterator.hasNext() && !found) {
+ RuleParam ruleParamFromDataBase = iterator.next();
+ if (isRuleParamEqual(activeRuleParam.getRuleParam(), ruleParamFromDataBase, rule.getKey(), pluginKey)) {
+ activeRuleParam.setRuleParam(ruleParamFromDataBase);
+ found = true;
+ }
+ }
+ }
+ }
+
+ public boolean isRuleParamEqual(RuleParam ruleParam, RuleParam ruleParamFromDatabase, String ruleKey, String pluginKey) {
+ return ruleParam.getKey().equals(ruleParamFromDatabase.getKey()) &&
+ ruleKey.equals(ruleParamFromDatabase.getRule().getKey()) &&
+ ruleParamFromDatabase.getRule().getPluginName().equals(pluginKey);
+ }
+
+ public RulesProfile getProfileById(int profileId) {
+ return getSession().getEntityManager().getReference(RulesProfile.class, profileId);
+ }
+
+}
diff --git a/sonar-core/src/main/java/org/sonar/jpa/dialect/Derby.java b/sonar-core/src/main/java/org/sonar/jpa/dialect/Derby.java new file mode 100644 index 00000000000..ec54f8f059a --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/dialect/Derby.java @@ -0,0 +1,73 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.dialect; + +import org.apache.commons.lang.StringUtils; +import org.hibernate.dialect.DerbyDialect; +import org.hibernate.id.IdentityGenerator; +import org.sonar.api.database.DatabaseProperties; + +import java.sql.Types; + +/** + * @since 1.12 + */ +public class Derby implements Dialect { + + public String getId() { + return "derby"; + } + + public String getActiveRecordDialectCode() { + return "derby"; + } + + public Class<? extends org.hibernate.dialect.Dialect> getHibernateDialectClass() { + return DerbyWithDecimalDialect.class; + } + + public boolean matchesJdbcURL(String jdbcConnectionURL) { + return StringUtils.startsWithIgnoreCase(jdbcConnectionURL, "jdbc:derby:"); + } + + public static class DerbyWithDecimalDialect extends DerbyDialect { + public DerbyWithDecimalDialect() { + super(); + registerColumnType(Types.DOUBLE, "decimal"); + registerColumnType(Types.VARCHAR, DatabaseProperties.MAX_TEXT_SIZE, "clob"); + registerColumnType(Types.VARBINARY, "blob"); + + // Not possible to do alter column types in Derby + registerColumnType(Types.BIGINT, "integer"); + } + + /** + * To be compliant with Oracle, we define on each model (ch.hortis.sonar.model classes) + * a sequence generator. It works on mySQL because strategy = GenerationType.AUTO, so + * it equals GenerationType.IDENTITY. + * But on derby, AUTO becomes TABLE instead of IDENTITY. So we explicitly change this behavior. + */ + @Override + public Class getNativeIdentifierGeneratorClass() { + return IdentityGenerator.class; + } + } + +} diff --git a/sonar-core/src/main/java/org/sonar/jpa/dialect/Dialect.java b/sonar-core/src/main/java/org/sonar/jpa/dialect/Dialect.java new file mode 100644 index 00000000000..0f860ae4e32 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/dialect/Dialect.java @@ -0,0 +1,50 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.dialect; + +/** + * @since 1.12 + */ +public interface Dialect { + + /** + * @return the sonar dialect Id to be matched with the sonar.jdbc.dialect property when provided + */ + String getId(); + + /** + * @return the hibernate dialect class to be used + */ + Class<? extends org.hibernate.dialect.Dialect> getHibernateDialectClass(); + + /** + * @return the activerecord dialect to be used + */ + String getActiveRecordDialectCode(); + + /** + * Used to autodetect a dialect for a given driver URL + * + * @param jdbcConnectionURL a jdbc driver url such as jdbc:mysql://localhost:3306/sonar + * @return true if the dialect supports surch url + */ + boolean matchesJdbcURL(String jdbcConnectionURL); + +} diff --git a/sonar-core/src/main/java/org/sonar/jpa/dialect/DialectRepository.java b/sonar-core/src/main/java/org/sonar/jpa/dialect/DialectRepository.java new file mode 100644 index 00000000000..e05c3b92329 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/dialect/DialectRepository.java @@ -0,0 +1,93 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.dialect; + +import com.google.common.base.Predicate; +import com.google.common.collect.Iterators; +import org.apache.commons.lang.StringUtils; +import org.sonar.api.utils.SonarException; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.NoSuchElementException; + +/** + * @since 1.12 + */ +public final class DialectRepository { + + private DialectRepository() { + } + + private static List<Dialect> builtInDialects = getSupportedDialects(); + + public static Dialect find(final String dialectId, final String jdbcConnectionUrl) { + Dialect match = StringUtils.isNotEmpty(dialectId) ? findById(dialectId) : findByJdbcUrl(jdbcConnectionUrl); + if (match == null) { + throw new SonarException("Unable to determine database dialect to use within sonar with dialect " + dialectId + " jdbc url " + jdbcConnectionUrl); + } + return match; + } + + private static Dialect findByJdbcUrl(final String jdbcConnectionUrl) { + Dialect match = findDialect(builtInDialects, new Predicate<Dialect>() { + public boolean apply(Dialect dialect) { + return dialect.matchesJdbcURL(StringUtils.trimToEmpty(jdbcConnectionUrl)); + } + }); + return match; + } + + private static Dialect findById(final String dialectId) { + Dialect match = findDialect(builtInDialects, new Predicate<Dialect>() { + public boolean apply(Dialect dialect) { + return dialect.getId().equals(dialectId); + } + }); + // maybe a class name if no match + match = match == null ? getDialectByClassname(dialectId) : match; + return match; + } + + private static Dialect findDialect(Collection<Dialect> dialects, Predicate<Dialect> predicate) { + try { + return Iterators.find(dialects.iterator(), predicate); + } catch (NoSuchElementException ex) { + return null; + } + } + + private static Dialect getDialectByClassname(String dialectId) { + try { + Class<? extends Dialect> dialectClass = (Class<? extends Dialect>) DialectRepository.class.getClassLoader().loadClass(dialectId); + return dialectClass.newInstance(); + } catch (ClassNotFoundException e) { + // dialectId was not a class name :) + } catch (Exception e) { + throw new SonarException("Unable to instanciate dialect class", e); + } + return null; + } + + private static List<Dialect> getSupportedDialects() { + return Arrays.asList(new Derby(), new HsqlDb(), new MySql(), new Oracle(), new PostgreSql(), new MsSql()); + } +} diff --git a/sonar-core/src/main/java/org/sonar/jpa/dialect/HsqlDb.java b/sonar-core/src/main/java/org/sonar/jpa/dialect/HsqlDb.java new file mode 100644 index 00000000000..b6bb3a68392 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/dialect/HsqlDb.java @@ -0,0 +1,46 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.dialect; + +import org.apache.commons.lang.StringUtils; +import org.hibernate.dialect.HSQLDialect; + +/** + * @since 1.12 + */ +public class HsqlDb implements Dialect { + + public String getId() { + return "hsqldb"; + } + + public String getActiveRecordDialectCode() { + return "hsqldb"; + } + + public Class<? extends org.hibernate.dialect.Dialect> getHibernateDialectClass() { + return HSQLDialect.class; + } + + public boolean matchesJdbcURL(String jdbcConnectionURL) { + return StringUtils.startsWithIgnoreCase(jdbcConnectionURL, "jdbc:hsqldb:"); + } + +} diff --git a/sonar-core/src/main/java/org/sonar/jpa/dialect/MsSql.java b/sonar-core/src/main/java/org/sonar/jpa/dialect/MsSql.java new file mode 100644 index 00000000000..f59c2ee4240 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/dialect/MsSql.java @@ -0,0 +1,68 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.dialect; + +import org.apache.commons.lang.StringUtils; +import org.hibernate.HibernateException; +import org.hibernate.dialect.SQLServerDialect; +import org.sonar.api.database.DatabaseProperties; + +import java.sql.Types; + +public class MsSql implements Dialect { + + public String getId() { + return "mssql"; + } + + public String getActiveRecordDialectCode() { + return "sqlserver"; + } + + public Class<? extends org.hibernate.dialect.Dialect> getHibernateDialectClass() { + return MsSqlDialect.class; + } + + public boolean matchesJdbcURL(String jdbcConnectionURL) { + return StringUtils.startsWithIgnoreCase(jdbcConnectionURL, "jdbc:microsoft:sqlserver:") + || StringUtils.startsWithIgnoreCase(jdbcConnectionURL, "jdbc:jtds:sqlserver:"); + } + + public static class MsSqlDialect extends SQLServerDialect { + public MsSqlDialect() { + super(); + registerColumnType(Types.DOUBLE, "decimal"); + registerColumnType(Types.VARCHAR, 255, "nvarchar($l)"); + registerColumnType(Types.VARCHAR, DatabaseProperties.MAX_TEXT_SIZE, "nvarchar(max)"); + registerColumnType(Types.CHAR, "nchar(1)"); + registerColumnType(Types.CLOB, "nvarchar(max)"); + } + + public String getTypeName(int code, int length, int precision, int scale) throws HibernateException { + if (code != 2005) { + return super.getTypeName(code, length, precision, scale); + } else { + return "ntext"; + } + } + } + +} + diff --git a/sonar-core/src/main/java/org/sonar/jpa/dialect/MySql.java b/sonar-core/src/main/java/org/sonar/jpa/dialect/MySql.java new file mode 100644 index 00000000000..180dec0b1ee --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/dialect/MySql.java @@ -0,0 +1,59 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.dialect; + +import org.apache.commons.lang.StringUtils; +import org.hibernate.dialect.MySQLDialect; +import org.sonar.api.database.DatabaseProperties; + +import java.sql.Types; + +/** + * @since 1.12 + */ +public class MySql implements Dialect { + + public String getId() { + return "mysql"; + } + + public String getActiveRecordDialectCode() { + return "mysql"; + } + + public Class<? extends org.hibernate.dialect.Dialect> getHibernateDialectClass() { + return MySqlWithDecimalDialect.class; + } + + public boolean matchesJdbcURL(String jdbcConnectionURL) { + return StringUtils.startsWithIgnoreCase(jdbcConnectionURL, "jdbc:mysql:"); + } + + public static class MySqlWithDecimalDialect extends MySQLDialect { + public MySqlWithDecimalDialect() { + super(); + registerColumnType(Types.DOUBLE, "decimal precision"); + registerColumnType(Types.VARCHAR, DatabaseProperties.MAX_TEXT_SIZE, "mediumtext"); + registerColumnType(Types.CLOB, "mediumtext"); + registerColumnType(Types.BLOB, "blob"); + } + } + +} diff --git a/sonar-core/src/main/java/org/sonar/jpa/dialect/Oracle.java b/sonar-core/src/main/java/org/sonar/jpa/dialect/Oracle.java new file mode 100644 index 00000000000..ebec6753619 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/dialect/Oracle.java @@ -0,0 +1,63 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.dialect; + +import org.apache.commons.lang.StringUtils; +import org.hibernate.dialect.Oracle10gDialect; +import org.sonar.api.database.DatabaseProperties; + +import java.sql.Types; + +/** + * @since 1.12 + */ +public class Oracle implements Dialect { + + public String getId() { + return "oracle"; + } + + public String getActiveRecordDialectCode() { + return "oracle"; + } + + public Class<? extends org.hibernate.dialect.Dialect> getHibernateDialectClass() { + return Oracle10gWithDecimalDialect.class; + } + + public boolean matchesJdbcURL(String jdbcConnectionURL) { + return StringUtils.startsWithIgnoreCase(jdbcConnectionURL, "jdbc:oracle:"); + } + + public static class Oracle10gWithDecimalDialect extends Oracle10gDialect { + public Oracle10gWithDecimalDialect() { + super(); + registerColumnType(Types.DOUBLE, "number($p,$s)"); + registerColumnType(Types.VARCHAR, DatabaseProperties.MAX_TEXT_SIZE, "clob"); + registerColumnType(Types.VARBINARY, "blob"); + } + + @Override + public Class getNativeIdentifierGeneratorClass() { + return OracleSequenceGenerator.class; + } + } + +} diff --git a/sonar-core/src/main/java/org/sonar/jpa/dialect/OracleSequenceGenerator.java b/sonar-core/src/main/java/org/sonar/jpa/dialect/OracleSequenceGenerator.java new file mode 100644 index 00000000000..7fa1abfa2d1 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/dialect/OracleSequenceGenerator.java @@ -0,0 +1,55 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.dialect; + +import org.hibernate.MappingException; +import org.hibernate.dialect.Dialect; +import org.hibernate.id.PersistentIdentifierGenerator; +import org.hibernate.id.SequenceGenerator; +import org.hibernate.type.Type; + +import java.util.Properties; + +/** + * @since 1.10 + */ +public class OracleSequenceGenerator extends SequenceGenerator { + + public static final String SEQUENCE_NAME_SUFFIX = "_SEQ"; + + @Override + public void configure(Type type, Properties params, Dialect dialect) + throws MappingException { + + String tableName = params.getProperty(PersistentIdentifierGenerator.TABLE); + + if (tableName != null) { + StringBuilder sequenceNameBuilder = new StringBuilder(); + + sequenceNameBuilder.append(tableName); + sequenceNameBuilder.append(SEQUENCE_NAME_SUFFIX); + + params.setProperty(SEQUENCE, sequenceNameBuilder.toString().toUpperCase()); + } + + super.configure(type, params, dialect); + } + +} diff --git a/sonar-core/src/main/java/org/sonar/jpa/dialect/PostgreSQLSequenceGenerator.java b/sonar-core/src/main/java/org/sonar/jpa/dialect/PostgreSQLSequenceGenerator.java new file mode 100644 index 00000000000..12094ba0745 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/dialect/PostgreSQLSequenceGenerator.java @@ -0,0 +1,64 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.dialect; + +import org.hibernate.MappingException; +import org.hibernate.dialect.Dialect; +import org.hibernate.id.PersistentIdentifierGenerator; +import org.hibernate.id.SequenceGenerator; +import org.hibernate.type.Type; + +import java.util.Properties; + +/** + * if the underlying database is PostgreSQL, the sequence + * naming convention is different and includes the primary key + * column name + * + * @since 1.10 + */ +public class PostgreSQLSequenceGenerator extends SequenceGenerator { + + public static final String SEQUENCE_NAME_SEPARATOR = "_"; + public static final String SEQUENCE_NAME_SUFFIX = "seq"; + + @Override + public void configure(Type type, Properties params, Dialect dialect) + throws MappingException { + + String tableName = params.getProperty(PersistentIdentifierGenerator.TABLE); + String columnName = params.getProperty(PersistentIdentifierGenerator.PK); + + if (tableName != null && columnName != null) { + StringBuilder sequenceNameBuilder = new StringBuilder(); + + sequenceNameBuilder.append(tableName); + sequenceNameBuilder.append(SEQUENCE_NAME_SEPARATOR); + sequenceNameBuilder.append(columnName); + sequenceNameBuilder.append(SEQUENCE_NAME_SEPARATOR); + sequenceNameBuilder.append(SEQUENCE_NAME_SUFFIX); + + params.setProperty(SEQUENCE, sequenceNameBuilder.toString()); + } + + super.configure(type, params, dialect); + } + +} diff --git a/sonar-core/src/main/java/org/sonar/jpa/dialect/PostgreSql.java b/sonar-core/src/main/java/org/sonar/jpa/dialect/PostgreSql.java new file mode 100644 index 00000000000..7d7318e51eb --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/dialect/PostgreSql.java @@ -0,0 +1,60 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.dialect; + +import org.apache.commons.lang.StringUtils; +import org.hibernate.dialect.PostgreSQLDialect; + +import java.sql.Types; + +/** + * @since 1.12 + */ +public class PostgreSql implements Dialect { + + public String getId() { + return "postgresql"; + } + + public String getActiveRecordDialectCode() { + return "postgre"; + } + + public Class<? extends org.hibernate.dialect.Dialect> getHibernateDialectClass() { + return PostgreSQLWithDecimalDialect.class; + } + + public boolean matchesJdbcURL(String jdbcConnectionURL) { + return StringUtils.startsWithIgnoreCase(jdbcConnectionURL, "jdbc:postgresql:"); + } + + public static class PostgreSQLWithDecimalDialect extends PostgreSQLDialect { + public PostgreSQLWithDecimalDialect() { + super(); + registerColumnType(Types.DOUBLE, "numeric($p,$s)"); + } + + @Override + public Class getNativeIdentifierGeneratorClass() { + return PostgreSQLSequenceGenerator.class; + } + } + +} diff --git a/sonar-core/src/main/java/org/sonar/jpa/entity/SchemaMigration.java b/sonar-core/src/main/java/org/sonar/jpa/entity/SchemaMigration.java new file mode 100644 index 00000000000..5549aeff502 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/entity/SchemaMigration.java @@ -0,0 +1,95 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.entity; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import javax.persistence.*; + +@Entity +@Table(name = SchemaMigration.TABLE_NAME, uniqueConstraints = {@UniqueConstraint(columnNames = {"version"})}) +public class SchemaMigration { + + public final static int VERSION_UNKNOWN = -1; + public static final int LAST_VERSION = 137; + + public final static String TABLE_NAME = "schema_migrations"; + + @Id + @Column(name = "version", updatable = true) + private String version; + + public String getVersion() { + return version; + } + + public void setVersion(String s) { + this.version = s; + } + + public void setVersion(int i) { + this.version = String.valueOf(i); + } + + public static int getCurrentVersion(Connection connection) { + Statement stmt = null; + ResultSet rs = null; + int version = VERSION_UNKNOWN; + try { + stmt = connection.createStatement(); + rs = stmt.executeQuery("SELECT version FROM " + SchemaMigration.TABLE_NAME); + while (rs.next()) { + int i = Integer.parseInt(rs.getString(1)); + if (i > version) { + version = i; + } + } + } catch (SQLException e) { + // ignore + } finally { + close(rs); + close(stmt); + } + + return version; + } + + private static void close(ResultSet rs) { + if (rs != null) { + try { + rs.close(); + } catch (SQLException e) { + // why does close() throw a checked-exception ??? + } + } + } + + private static void close(Statement st) { + if (st != null) { + try { + st.close(); + } catch (SQLException e) { + // why does close() throw a checked-exception ??? + } + } + } +}
\ No newline at end of file diff --git a/sonar-core/src/main/java/org/sonar/jpa/session/AbstractDatabaseBatch.java b/sonar-core/src/main/java/org/sonar/jpa/session/AbstractDatabaseBatch.java new file mode 100644 index 00000000000..6f90114d5a8 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/session/AbstractDatabaseBatch.java @@ -0,0 +1,46 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.session; + +import org.picocontainer.MutablePicoContainer; +import org.sonar.api.database.DatabaseSession; + +public abstract class AbstractDatabaseBatch implements DatabaseBatch { + private MutablePicoContainer container; + + public void startIn(MutablePicoContainer container) { + this.container = container; + doStart(); + } + + protected abstract void doStart(); + + protected DatabaseSession getSession() { + return container.getComponent(DatabaseSession.class); + } + + protected <T> T getComponent(Class<T> clazz) { + return container.getComponent(clazz); + } + + protected MutablePicoContainer getContainer() { + return container; + } +} diff --git a/sonar-core/src/main/java/org/sonar/jpa/session/AbstractDatabaseConnector.java b/sonar-core/src/main/java/org/sonar/jpa/session/AbstractDatabaseConnector.java new file mode 100644 index 00000000000..ac778560a18 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/session/AbstractDatabaseConnector.java @@ -0,0 +1,241 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.session; + +import org.apache.commons.configuration.Configuration; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.database.DatabaseProperties; +import org.sonar.jpa.dialect.Dialect; +import org.sonar.jpa.dialect.DialectRepository; +import org.sonar.jpa.entity.SchemaMigration; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; + +public abstract class AbstractDatabaseConnector implements DatabaseConnector { + protected static final Logger LOG_SQL = LoggerFactory.getLogger("org.hibernate.SQL"); + protected static final Logger LOG = LoggerFactory.getLogger(AbstractDatabaseConnector.class); + + private Configuration configuration = null; + private EntityManagerFactory factory = null; + private int databaseVersion = SchemaMigration.VERSION_UNKNOWN; + private boolean operational = false; + private boolean started = false; + private boolean startsFailIfSchemaOutdated; + private Integer transactionIsolation = null; + private Dialect dialect = null; + + protected AbstractDatabaseConnector(Configuration configuration, boolean startsFailIfSchemaOutdated) { + this.configuration = configuration; + this.startsFailIfSchemaOutdated = startsFailIfSchemaOutdated; + } + + protected AbstractDatabaseConnector() { + } + + public Configuration getConfiguration() { + return configuration; + } + + public void setConfiguration(Configuration configuration) { + this.configuration = configuration; + } + + public String getDialectId() { + return dialect.getId(); + } + /** + * Indicates if the connector is operational : database connection OK and schema version OK + */ + public boolean isOperational() { + return operational; + } + + /** + * Indicates if the connector is started : database connection OK and schema version OK or KO + */ + protected boolean isStarted() { + return started; + } + + /** + * Get the JDBC transaction isolation defined by the configuration + * + * @return JDBC transaction isolation + */ + public Integer getTransactionIsolation() { + return transactionIsolation; + } + + public void start() { + if (!started) { + transactionIsolation = configuration.getInteger(DatabaseProperties.PROP_ISOLATION, null /* use driver default setting */); + String jdbcConnectionUrl = testConnection(); + dialect = DialectRepository.find(configuration.getString("sonar.jdbc.dialect"), jdbcConnectionUrl); + LoggerFactory.getLogger("org.sonar.INFO").info("Database dialect class " + dialect.getClass().getName()); + started = true; + } + if (!operational) { + boolean upToDate = upToDateSchemaVersion(); + if (!upToDate && startsFailIfSchemaOutdated) { + throw new DatabaseException(databaseVersion, SchemaMigration.LAST_VERSION); + } + if (upToDate) { + factory = createEntityManagerFactory(); + operational = true; + } + } + } + + public void stop() { + if (factory != null && factory.isOpen()) { + factory.close(); + factory = null; + } + operational = false; + started = false; + } + + public abstract void setupEntityManagerFactory(Properties factoryProps); + + public EntityManagerFactory getEntityManagerFactory() { + return factory; + } + + protected void setEntityManagerFactory(EntityManagerFactory factory) { + this.factory = factory; + } + + protected EntityManagerFactory createEntityManagerFactory() { + // other settings are stored into /META-INF/persistence.xml + Properties props = getHibernateProperties(); + logHibernateSettings(props); + return Persistence.createEntityManagerFactory("sonar", props); + } + + private void logHibernateSettings(Properties props) { + if (LOG.isDebugEnabled()) { + for (Map.Entry<Object, Object> entry : props.entrySet()) { + LOG.debug(entry.getKey() + ": " + entry.getValue()); + } + } + } + + protected Properties getHibernateProperties() { + Properties props = new Properties(); + if (transactionIsolation != null) { + props.put("hibernate.connection.isolation", Integer.toString(transactionIsolation)); + } + props.put("hibernate.hbm2ddl.auto", getConfiguration().getString(DatabaseProperties.PROP_HIBERNATE_HBM2DLL, "validate")); + props.put("hibernate.dialect", getDialectClass()); + + props.put("hibernate.generate_statistics", getConfiguration().getBoolean(DatabaseProperties.PROP_HIBERNATE_GENERATE_STATISTICS, false)); + props.put("hibernate.show_sql", Boolean.valueOf(LOG_SQL.isInfoEnabled()).toString()); + + Configuration subset = getConfiguration().subset("sonar.hibernate"); + for (Iterator keys = subset.getKeys(); keys.hasNext();) { + String key = (String) keys.next(); + if (StringUtils.isNotBlank((String)subset.getProperty(key))) { + props.put("hibernate." + key, subset.getProperty(key)); + } + } + + // custom impl setup + setupEntityManagerFactory(props); + + + return props; + } + + public EntityManager createEntityManager() { + return factory.createEntityManager(); + } + + private String testConnection() throws DatabaseException { + Connection connection = null; + try { + connection = getConnection(); + return connection.getMetaData().getURL(); + + } catch (SQLException e) { + throw new DatabaseException("Cannot open connection to database: " + e.getMessage(), e); + + } finally { + close(connection); + } + } + + protected int loadVersion() { + Connection connection = null; + try { + connection = getConnection(); + return SchemaMigration.getCurrentVersion(connection); + + } catch (SQLException e) { + // schema not created + return 0; + } finally { + close(connection); + } + } + + private void close(Connection connection) { + if (connection != null) { + try { + connection.close(); + } catch (SQLException e) { + // why does close() throw a checked-exception ??? + } + } + } + + protected boolean upToDateSchemaVersion() { + if (databaseVersion == SchemaMigration.LAST_VERSION) { + return true; + } + databaseVersion = loadVersion(); + return databaseVersion == SchemaMigration.LAST_VERSION; + } + + protected int getDatabaseVersion() { + return databaseVersion; + } + + public Dialect getDialect() { + return dialect; + } + + public String getDialectClass() { + String dialectClass = configuration.getString(DatabaseProperties.PROP_DIALECT_CLASS); + if (dialectClass == null && dialect != null) { + dialectClass = dialect.getHibernateDialectClass().getName(); + } + return dialectClass; + } + +} diff --git a/sonar-core/src/main/java/org/sonar/jpa/session/DatabaseBatch.java b/sonar-core/src/main/java/org/sonar/jpa/session/DatabaseBatch.java new file mode 100644 index 00000000000..8612b5c3f03 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/session/DatabaseBatch.java @@ -0,0 +1,27 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ + +package org.sonar.jpa.session; + +import org.picocontainer.MutablePicoContainer; + +public interface DatabaseBatch { + void startIn(MutablePicoContainer container); +} diff --git a/sonar-core/src/main/java/org/sonar/jpa/session/DatabaseConnector.java b/sonar-core/src/main/java/org/sonar/jpa/session/DatabaseConnector.java new file mode 100644 index 00000000000..952c2529a33 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/session/DatabaseConnector.java @@ -0,0 +1,39 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.session; + +import org.sonar.jpa.dialect.Dialect; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import java.sql.Connection; +import java.sql.SQLException; + +public interface DatabaseConnector { + + Dialect getDialect(); + + Connection getConnection() throws SQLException; + + EntityManagerFactory getEntityManagerFactory(); + + EntityManager createEntityManager(); + +} diff --git a/sonar-core/src/main/java/org/sonar/jpa/session/DatabaseException.java b/sonar-core/src/main/java/org/sonar/jpa/session/DatabaseException.java new file mode 100644 index 00000000000..46ec6d5cf26 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/session/DatabaseException.java @@ -0,0 +1,41 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.session; + +import javax.persistence.PersistenceException; + +public class DatabaseException extends PersistenceException { + + public DatabaseException(Throwable throwable) { + super(throwable); + } + + public DatabaseException(String message) { + super(message); + } + + public DatabaseException(String message, Throwable cause) { + super(message, cause); + } + + public DatabaseException(int version, int requiredVersion) { + super("Database schema must be updated [version/required=" + version + "/" + requiredVersion + "]. Please browse to your sonar homepage."); + } +} diff --git a/sonar-core/src/main/java/org/sonar/jpa/session/DatabaseSessionFactory.java b/sonar-core/src/main/java/org/sonar/jpa/session/DatabaseSessionFactory.java new file mode 100644 index 00000000000..8257f4c5cb2 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/session/DatabaseSessionFactory.java @@ -0,0 +1,29 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.session; + +import org.sonar.api.database.DatabaseSession; + +public interface DatabaseSessionFactory { + + DatabaseSession getSession(); + + void clear(); +} diff --git a/sonar-core/src/main/java/org/sonar/jpa/session/DatabaseSessionProvider.java b/sonar-core/src/main/java/org/sonar/jpa/session/DatabaseSessionProvider.java new file mode 100644 index 00000000000..8ea912e1b79 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/session/DatabaseSessionProvider.java @@ -0,0 +1,31 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.session; + +import org.picocontainer.injectors.ProviderAdapter; +import org.sonar.api.database.DatabaseSession; + +public class DatabaseSessionProvider extends ProviderAdapter { + + public DatabaseSession provide(DatabaseSessionFactory factory) { + return factory.getSession(); + } + +} diff --git a/sonar-core/src/main/java/org/sonar/jpa/session/DriverDatabaseConnector.java b/sonar-core/src/main/java/org/sonar/jpa/session/DriverDatabaseConnector.java new file mode 100644 index 00000000000..7f24d8cabea --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/session/DriverDatabaseConnector.java @@ -0,0 +1,152 @@ +package org.sonar.jpa.session; + +import org.apache.commons.configuration.Configuration; +import org.apache.commons.lang.StringUtils; +import org.sonar.api.database.DatabaseProperties; + +import java.sql.Connection; +import java.sql.Driver; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.Properties; + +public class DriverDatabaseConnector extends AbstractDatabaseConnector { + + private ClassLoader classloader; + + public DriverDatabaseConnector(Configuration configuration) { + super(configuration, true); + this.classloader = getClass().getClassLoader(); + } + + public DriverDatabaseConnector(Configuration configuration, ClassLoader classloader) { + super(configuration, true); + this.classloader = classloader; + } + + public String getDriver() { + String driver = getConfiguration().getString(DatabaseProperties.PROP_DRIVER); + if (driver == null) { + driver = getConfiguration().getString(DatabaseProperties.PROP_DRIVER_DEPRECATED); + } + if (driver == null) { + driver = DatabaseProperties.PROP_DRIVER_DEFAULT_VALUE; + } + return driver; + } + + public String getUrl() { + return getConfiguration().getString(DatabaseProperties.PROP_URL, DatabaseProperties.PROP_URL_DEFAULT_VALUE); + } + + public String getUsername() { + String username = getConfiguration().getString(DatabaseProperties.PROP_USER); + if (username == null) { + username = getConfiguration().getString(DatabaseProperties.PROP_USER_DEPRECATED); + } + if (username == null) { + username = DatabaseProperties.PROP_USER_DEFAULT_VALUE; + } + return username; + } + + public String getPassword() { + return getConfiguration().getString(DatabaseProperties.PROP_PASSWORD, DatabaseProperties.PROP_PASSWORD_DEFAULT_VALUE); + } + + public Connection getConnection() throws SQLException { + try { + /* + The sonar batch downloads the JDBC driver in a separated classloader. + This is a well-know problem of java.sql.DriverManager. The workaround + is to use a proxy. + See http://stackoverflow.com/questions/288828/how-to-use-a-jdbc-driver-from-an-arbitrary-location + */ + Driver driver = (Driver)classloader.loadClass(getDriver()).newInstance(); + DriverManager.registerDriver(new DriverProxy(driver)); + + } catch (Exception e) { + SQLException ex = new SQLException("SQL driver not found " + getDriver()); + ex.initCause(e); + throw ex; + } + return DriverManager.getConnection(getUrl(), getUsername(), getPassword()); + } + + @Override + public void setupEntityManagerFactory(Properties factoryProps) { + factoryProps.put("hibernate.connection.url", getUrl()); + factoryProps.put("hibernate.connection.driver_class", getDriver()); + factoryProps.put("hibernate.connection.username", getUsername()); + if (StringUtils.isNotEmpty(getPassword())) { + factoryProps.put("hibernate.connection.password", getPassword()); + } + } +} + +/** + * A Driver that stands in for another Driver. + * This is necessary because java.sql.DriverManager + * examines the Driver class class loader. + */ +final class DriverProxy implements Driver { + private final Driver target; + + DriverProxy(Driver target) { + if (target == null) { + throw new NullPointerException(); + } + this.target = target; + } + + public Driver getTarget() { + return target; + } + + public boolean acceptsURL(String url) throws SQLException { + return target.acceptsURL(url); + } + + public Connection connect( + String url, Properties info + ) throws SQLException { + return target.connect(url, info); + } + + public int getMajorVersion() { + return target.getMajorVersion(); + } + + public int getMinorVersion() { + return target.getMinorVersion(); + } + + public java.sql.DriverPropertyInfo[] getPropertyInfo( + String url, Properties info + ) throws SQLException { + return target.getPropertyInfo(url, info); + } + + public boolean jdbcCompliant() { + return target.jdbcCompliant(); + } + + @Override + public String toString() { + return "Proxy: " + target; + } + + @Override + public int hashCode() { + return target.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof org.sonar.jpa.session.DriverProxy)) { + return false; + } + org.sonar.jpa.session.DriverProxy other = (org.sonar.jpa.session.DriverProxy) obj; + return this.target.equals(other.target); + } +}
\ No newline at end of file diff --git a/sonar-core/src/main/java/org/sonar/jpa/session/JpaDatabaseSession.java b/sonar-core/src/main/java/org/sonar/jpa/session/JpaDatabaseSession.java new file mode 100644 index 00000000000..8390dd8fd6b --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/session/JpaDatabaseSession.java @@ -0,0 +1,222 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.session; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.LoggerFactory; +import org.sonar.api.database.DatabaseSession; + +import javax.persistence.EntityManager; +import javax.persistence.NoResultException; +import javax.persistence.NonUniqueResultException; +import javax.persistence.Query; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class JpaDatabaseSession extends DatabaseSession { + + private final DatabaseConnector connector; + private EntityManager entityManager = null; + private int index = 0; + private boolean inTransaction = false; + + public JpaDatabaseSession(DatabaseConnector connector) { + this.connector = connector; + } + + public EntityManager getEntityManager() { + return entityManager; + } + + public void start() { + entityManager = connector.createEntityManager(); + index = 0; + } + + public void stop() { + commit(); + if (entityManager != null && entityManager.isOpen()) { + entityManager.clear(); + entityManager.close(); + entityManager = null; + } + } + + public void commit() { + if (entityManager != null && inTransaction) { + if (entityManager.isOpen()) { + if (entityManager.getTransaction().getRollbackOnly()) { + entityManager.getTransaction().rollback(); + } else { + entityManager.getTransaction().commit(); + } + } + inTransaction = false; + index = 0; + } + } + + public void rollback() { + if (entityManager != null && inTransaction) { + entityManager.getTransaction().rollback(); + inTransaction = false; + index = 0; + } + } + + public <T> T save(T model) { + startTransaction(); + internalSave(model, true); + return model; + } + + public Object saveWithoutFlush(Object model) { + startTransaction(); + internalSave(model, false); + return model; + } + + public boolean contains(Object model) { + startTransaction(); + return entityManager.contains(model); + } + + public void save(Object... models) { + startTransaction(); + for (Object model : models) { + save(model); + } + } + + private void internalSave(Object model, boolean flushIfNeeded) { + entityManager.persist(model); + if (flushIfNeeded && (++index % BATCH_SIZE == 0)) { + flush(); + } + } + + public Object merge(Object model) { + startTransaction(); + return entityManager.merge(model); + } + + public void remove(Object model) { + startTransaction(); + entityManager.remove(model); + if (++index % BATCH_SIZE == 0) { + flush(); + } + } + + public void removeWithoutFlush(Object model) { + startTransaction(); + entityManager.remove(model); + } + + public <T> T reattach(Class<T> entityClass, Object primaryKey) { + startTransaction(); + return entityManager.getReference(entityClass, primaryKey); + } + + private void startTransaction() { + if (!inTransaction) { + entityManager.getTransaction().begin(); + inTransaction = true; + } + } + + public void flush() { + entityManager.flush(); + entityManager.clear(); + } + + public Query createQuery(String hql) { + startTransaction(); + return entityManager.createQuery(hql); + } + + public <T> T getSingleResult(Query query, T defaultValue) { + try { + return (T) query.getSingleResult(); + } catch (NoResultException ex) { + return defaultValue; + } + } + + public <T> T getEntity(Class<T> entityClass, Object id) { + startTransaction(); + return getEntityManager().find(entityClass, id); + } + + public <T> T getSingleResult(Class<T> entityClass, Object... criterias) { + try { + return getSingleResult(getQueryForCriterias(entityClass, true, criterias), (T) null); + + } catch (NonUniqueResultException ex) { + LoggerFactory.getLogger(JpaDatabaseSession.class).warn("NonUniqueResultException on entity {} with criterias : {}", + entityClass.getSimpleName(), StringUtils.join(criterias, ",")); + throw ex; + } + } + + public <T> List<T> getResults(Class<T> entityClass, Object... criterias) { + return getQueryForCriterias(entityClass, true, criterias).getResultList(); + } + + public <T> List<T> getResults(Class<T> entityClass) { + return getQueryForCriterias(entityClass, false, null).getResultList(); + } + + private Query getQueryForCriterias(Class<?> entityClass, boolean raiseError, Object... criterias) { + if (criterias == null && raiseError) { + throw new IllegalStateException("criterias parameter must be provided"); + } + startTransaction(); + StringBuilder hql = new StringBuilder("SELECT o FROM ").append(entityClass.getSimpleName()).append(" o"); + if (criterias != null) { + hql.append(" WHERE "); + Map<String, Object> mappedCriterias = new HashMap<String, Object>(); + for (int i = 0; i < criterias.length; i += 2) { + mappedCriterias.put((String) criterias[i], criterias[i + 1]); + } + buildCriteriasHQL(hql, mappedCriterias); + Query query = getEntityManager().createQuery(hql.toString()); + + for (Map.Entry<String, Object> entry : mappedCriterias.entrySet()) { + query.setParameter(entry.getKey(), entry.getValue()); + } + return query; + } + return getEntityManager().createQuery(hql.toString()); + } + + private void buildCriteriasHQL(StringBuilder hql, Map<String, Object> mappedCriterias) { + for (Iterator<String> i = mappedCriterias.keySet().iterator(); i.hasNext();) { + String criteria = i.next(); + hql.append("o.").append(criteria).append("=:").append(criteria); + if (i.hasNext()) { + hql.append(" AND "); + } + } + } + +} diff --git a/sonar-core/src/main/java/org/sonar/jpa/session/MemoryDatabaseConnector.java b/sonar-core/src/main/java/org/sonar/jpa/session/MemoryDatabaseConnector.java new file mode 100644 index 00000000000..5d00ddb02df --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/session/MemoryDatabaseConnector.java @@ -0,0 +1,101 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.session; + +import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.sonar.api.database.DatabaseProperties; +import org.sonar.jpa.entity.SchemaMigration; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import java.sql.Connection; + +public class MemoryDatabaseConnector extends DriverDatabaseConnector { + public static final String DRIVER = "org.hsqldb.jdbcDriver"; + public static final String URL = "jdbc:hsqldb:mem:sonar"; + public static final String USER = "sa"; + public static final String PASSWORD = ""; + public static final int ISOLATION = Connection.TRANSACTION_READ_UNCOMMITTED; + + private int version; + + public MemoryDatabaseConnector(Configuration config) { + super(config); + version = SchemaMigration.LAST_VERSION; + } + + public MemoryDatabaseConnector() { + this(getInMemoryConfiguration(true)); + } + + public MemoryDatabaseConnector(int version) { + this(getInMemoryConfiguration(true)); + this.version = version; + } + + protected static Configuration getInMemoryConfiguration(boolean createSchema) { + PropertiesConfiguration conf = new PropertiesConfiguration(); + conf.setProperty(DatabaseProperties.PROP_URL, URL); + conf.setProperty(DatabaseProperties.PROP_DRIVER, DRIVER); + conf.setProperty(DatabaseProperties.PROP_USER, USER); + conf.setProperty(DatabaseProperties.PROP_PASSWORD, PASSWORD); + conf.setProperty(DatabaseProperties.PROP_ISOLATION, ISOLATION); + if (createSchema) { + conf.setProperty(DatabaseProperties.PROP_HIBERNATE_HBM2DLL, "create-drop"); + } + return conf; + } + + @Override + public void start() { + try { + super.start(); + } catch (DatabaseException ex) { + if (!isStarted()) { + throw ex; + } + setEntityManagerFactory(createEntityManagerFactory()); + setupSchemaVersion(version); + } + } + + @Override + protected EntityManagerFactory createEntityManagerFactory() { + return super.createEntityManagerFactory(); + } + + protected void setupSchemaVersion(int version) { + SchemaMigration migration = new SchemaMigration(); + migration.setVersion(version); + EntityManager manager = null; + try { + manager = createEntityManager(); + manager.getTransaction().begin(); + manager.persist(migration); + manager.getTransaction().commit(); + + } finally { + if (manager != null) { + manager.close(); + } + } + } +}
\ No newline at end of file diff --git a/sonar-core/src/main/java/org/sonar/jpa/session/ThreadLocalDatabaseSessionFactory.java b/sonar-core/src/main/java/org/sonar/jpa/session/ThreadLocalDatabaseSessionFactory.java new file mode 100644 index 00000000000..75ef5f9de3f --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/jpa/session/ThreadLocalDatabaseSessionFactory.java @@ -0,0 +1,35 @@ +package org.sonar.jpa.session; + +import org.sonar.api.database.DatabaseSession; + +public class ThreadLocalDatabaseSessionFactory implements DatabaseSessionFactory { + + private final ThreadLocal<JpaDatabaseSession> threadSession = new ThreadLocal<JpaDatabaseSession>(); + private final DatabaseConnector connector; + + public ThreadLocalDatabaseSessionFactory(DatabaseConnector connector) { + this.connector = connector; + } + + public DatabaseSession getSession() { + JpaDatabaseSession session = threadSession.get(); + if (session == null) { + session = new JpaDatabaseSession(connector); + session.start(); + threadSession.set(session); + } + return session; + } + + public void clear() { + JpaDatabaseSession session = threadSession.get(); + if (session != null) { + session.stop(); + } + threadSession.set(null); + } + + public void stop() { + clear(); + } +} diff --git a/sonar-core/src/main/resources/META-INF/persistence.xml b/sonar-core/src/main/resources/META-INF/persistence.xml new file mode 100644 index 00000000000..2d3f56e0cbb --- /dev/null +++ b/sonar-core/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<persistence xmlns="http://java.sun.com/xml/ns/persistence" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" + version="1.0"> + <persistence-unit name="sonar" transaction-type="RESOURCE_LOCAL"> + <provider>org.hibernate.ejb.HibernatePersistence</provider> + + <class>org.sonar.jpa.entity.SchemaMigration</class> + <class>org.sonar.api.database.configuration.Property</class> + <class>org.sonar.api.qualitymodel.Model</class> + <class>org.sonar.api.qualitymodel.Characteristic</class> + <class>org.sonar.core.plugin.JpaPlugin</class> + <class>org.sonar.core.plugin.JpaPluginFile</class> + + <class>org.sonar.api.database.model.User</class> + <class>org.sonar.api.database.model.Snapshot</class> + <class>org.sonar.api.database.model.MeasureModel</class> + <class>org.sonar.api.database.model.MeasureData</class> + <class>org.sonar.api.design.DependencyDto</class> + <class>org.sonar.api.measures.Metric</class> + <class>org.sonar.api.database.model.ResourceModel</class> + <class>org.sonar.api.database.model.SnapshotSource</class> + <class>org.sonar.api.database.model.RuleFailureModel</class> + <class>org.sonar.api.security.UserRole</class> + <class>org.sonar.api.security.GroupRole</class> + <class>org.sonar.api.rules.Rule</class> + <class>org.sonar.api.rules.RuleParam</class> + <class>org.sonar.api.rules.RulesCategory</class> + <class>org.sonar.api.resources.ProjectLink</class> + <class>org.sonar.api.profiles.RulesProfile</class> + <class>org.sonar.api.rules.ActiveRule</class> + <class>org.sonar.api.rules.ActiveRuleParam</class> + <class>org.sonar.api.database.model.AsyncMeasureSnapshot</class> + <class>org.sonar.api.batch.Event</class> + <class>org.sonar.api.profiles.Alert</class> + + <properties> + <property name="hibernate.current_session_context_class" value="thread"/> + <property name="hibernate.connection.release_mode" value="after_transaction"/> + <property name="hibernate.bytecode.use_reflection_optimizer" value="true"/> + <property name="hibernate.query.factory_class" value="org.hibernate.hql.ast.ASTQueryTranslatorFactory"/> + <property name="hibernate.jdbc.batch_size" value="30"/> + <property name="hibernate.connection.useUnicode" value="true"/> + <property name="hibernate.connection.charSet" value="UTF-8"/> + <property name="hibernate.connection.characterEncoding" value="UTF-8"/> + <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/> + <property name="hibernate.cache.use_second_level_cache" value="false"/> + <property name="hibernate.cache.use_query_cache" value="false"/> + </properties> + </persistence-unit> +</persistence>
\ No newline at end of file diff --git a/sonar-core/src/main/resources/ehcache.xml b/sonar-core/src/main/resources/ehcache.xml new file mode 100644 index 00000000000..99e2597c98e --- /dev/null +++ b/sonar-core/src/main/resources/ehcache.xml @@ -0,0 +1,76 @@ +<ehcache> + <!--ehcache config ref + + name: + Sets the name of the cache. This is used to identify the cache. It must be unique. + + maxElementsInMemory: + Sets the maximum number of objects that will be created in memory + + maxElementsOnDisk: + Sets the maximum number of objects that will be maintained in the DiskStore + The default value is zero, meaning unlimited. + + eternal: + Sets whether elements are eternal. If eternal, timeouts are ignored and the + element is never expired. + + overflowToDisk: + Sets whether elements can overflow to disk when the memory store + has reached the maxInMemory limit. + + The following attributes are optional. + + timeToIdleSeconds: + Sets the time to idle for an element before it expires. + i.e. The maximum amount of time between accesses before an element expires + Is only used if the element is not eternal. + Optional attribute. A value of 0 means that an Element can idle for infinity. + The default value is 0. + + timeToLiveSeconds: + Sets the time to live for an element before it expires. + i.e. The maximum time between creation time and when an element expires. + Is only used if the element is not eternal. + Optional attribute. A value of 0 means that and Element can live for infinity. + The default value is 0. + + diskPersistent: + Whether the disk store persists between restarts of the Virtual Machine. + The default value is false. + + diskExpiryThreadIntervalSeconds: + The number of seconds between runs of the disk expiry thread. The default value + is 120 seconds. + + memoryStoreEvictionPolicy: + Policy would be enforced upon reaching the maxElementsInMemory limit. Default + policy is Least Recently Used (specified as LRU). Other policies available - + First In First Out (specified as FIFO) and Less Frequently Used + (specified as LFU) + --> + + <defaultCache + maxElementsInMemory="4096" + eternal="false" + timeToIdleSeconds="300" + timeToLiveSeconds="1200" + overflowToDisk="false" + memoryStoreEvictionPolicy="LRU"/> + + <cache + name="org.sonar.api.measures.Metric" + maxElementsInMemory="256" + eternal="false" + overflowToDisk="false"/> + <cache + name="org.sonar.api.rules.Rule" + maxElementsInMemory="4096" + eternal="false" + overflowToDisk="false"/> + <cache + name="org.sonar.api.rules.RulesCategory" + maxElementsInMemory="32" + eternal="true" + overflowToDisk="false"/> +</ehcache>
\ No newline at end of file diff --git a/sonar-core/src/test/java/org/sonar/api/database/configuration/DatabaseConfigurationTest.java b/sonar-core/src/test/java/org/sonar/api/database/configuration/DatabaseConfigurationTest.java new file mode 100644 index 00000000000..26a54faedff --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/api/database/configuration/DatabaseConfigurationTest.java @@ -0,0 +1,40 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.api.database.configuration; + +import org.junit.Test; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +public class DatabaseConfigurationTest extends AbstractDbUnitTestCase { + + @Test + public void shouldLoadPropertiesFromDatabase() { + setupData("some-properties"); + + DatabaseConfiguration configuration = new DatabaseConfiguration(getSessionFactory()); + + assertEquals("value1", configuration.getString("key1")); + assertEquals("value2", configuration.getString("key2")); + assertNull(configuration.getString("keyxxxx")); + } +} diff --git a/sonar-core/src/test/java/org/sonar/api/database/configuration/ResourceDatabaseConfigurationTest.java b/sonar-core/src/test/java/org/sonar/api/database/configuration/ResourceDatabaseConfigurationTest.java new file mode 100644 index 00000000000..a856d0729fd --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/api/database/configuration/ResourceDatabaseConfigurationTest.java @@ -0,0 +1,41 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.api.database.configuration; + +import org.apache.commons.collections.CollectionUtils; +import org.junit.Test; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +public class ResourceDatabaseConfigurationTest extends AbstractDbUnitTestCase { + + @Test + public void shouldNotLoadGlobalProperties() { + setupData("shouldNotLoadGlobalProperties"); + + ResourceDatabaseConfiguration conf = new ResourceDatabaseConfiguration(getSessionFactory(), 100); + assertEquals(2, CollectionUtils.size(conf.getKeys())); + assertEquals("project_value1", conf.getString("key1")); + assertNull(conf.getString("key2")); + } + +} diff --git a/sonar-core/src/test/java/org/sonar/core/plugin/JpaPluginDaoTest.java b/sonar-core/src/test/java/org/sonar/core/plugin/JpaPluginDaoTest.java new file mode 100644 index 00000000000..ba4e26a322b --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/plugin/JpaPluginDaoTest.java @@ -0,0 +1,120 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.core.plugin; + +import org.junit.Before; +import org.junit.Test; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import java.util.ArrayList; +import java.util.List; + +import static junit.framework.Assert.assertEquals; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +public class JpaPluginDaoTest extends AbstractDbUnitTestCase { + + private JpaPluginDao dao; + + @Before + public void before() { + dao = new JpaPluginDao(getSessionFactory()); + } + + @Test + public void getPlugins() { + setupData("shared"); + + List<JpaPlugin> plugins = dao.getPlugins(); + + assertEquals(1, plugins.size()); + assertEquals("checkstyle", plugins.get(0).getKey()); + assertEquals(2, plugins.get(0).getFiles().size()); + } + + + @Test + public void savePluginAndFiles() { + setupData("shared"); + JpaPlugin pmd = JpaPlugin.create("pmd"); + pmd.setCore(false); + pmd.setName("PMD"); + pmd.setVersion("2.2"); + pmd.setPluginClass("org.sonar.pmd.Main"); + + pmd.createFile("sonar-pmd-plugin-2.2.jar"); + pmd.createFile("pmd-extension.jar"); + pmd.createFile("pmd-extension2.jar"); + + getSession().saveWithoutFlush(pmd); + checkTables("savePluginAndFiles", "plugins", "plugin_files"); + } + + @Test + public void saveDeprecatedPlugin() { + setupData("shared"); + JpaPlugin pmd = JpaPlugin.create("pmd"); + pmd.setCore(false); + pmd.setName("PMD"); + pmd.setPluginClass("org.sonar.pmd.Main"); + + pmd.createFile("sonar-pmd-plugin-2.2.jar"); + + getSession().saveWithoutFlush(pmd); + checkTables("saveDeprecatedPlugin", "plugins", "plugin_files"); + } + + @Test + public void removePreviousFilesWhenRegisteringPlugin() { + setupData("shared"); + + List<JpaPlugin> plugins = dao.getPlugins(); + plugins.get(0).removeFiles(); + plugins.get(0).createFile("newfile.jar"); + + dao.register(plugins); + + checkTables("removePreviousFilesWhenRegisteringPlugin", "plugins", "plugin_files"); + } + + @Test + public void registerManyPlugins() { + setupData("shared"); + + List<JpaPlugin> plugins = createManyPlugins(); + dao.register(plugins); + + assertThat(dao.getPlugins().size(), is(150)); + assertThat(dao.getPluginFiles().size(), is(150 * 20)); // initial plugin "checkstyle" has been deleted + } + + private List<JpaPlugin> createManyPlugins() { + List<JpaPlugin> plugins = new ArrayList<JpaPlugin>(); + for (int i=0 ; i<150 ; i++) { + JpaPlugin plugin = JpaPlugin.create("plugin-" + i); + for (int j=0 ; j<20 ; j++) { + plugin.createFile("file-" + i + "-" + j + ".jar"); + } + plugins.add(plugin); + } + return plugins; + } +} diff --git a/sonar-core/src/test/java/org/sonar/core/plugin/JpaPluginTest.java b/sonar-core/src/test/java/org/sonar/core/plugin/JpaPluginTest.java new file mode 100644 index 00000000000..6a6d3cad2ca --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/plugin/JpaPluginTest.java @@ -0,0 +1,42 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.core.plugin; + +import org.junit.Test; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertFalse; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; + +public class JpaPluginTest { + + @Test + public void createPlugin() { + JpaPlugin plugin = JpaPlugin.create("foo"); + assertThat(plugin.getKey(), is("foo")); + + assertEquals(plugin, plugin); + assertEquals(plugin, JpaPlugin.create("foo")); + assertFalse(plugin.equals(JpaPlugin.create("bar"))); + } + + +} diff --git a/sonar-core/src/test/java/org/sonar/core/purge/AbstractPurgeTest.java b/sonar-core/src/test/java/org/sonar/core/purge/AbstractPurgeTest.java new file mode 100644 index 00000000000..5211d037cd3 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/purge/AbstractPurgeTest.java @@ -0,0 +1,39 @@ +package org.sonar.core.purge; + +import org.junit.Test; +import org.sonar.api.batch.PurgeContext; +import org.sonar.api.database.DatabaseSession; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import java.sql.SQLException; +import java.util.Arrays; + +/** + * Created by IntelliJ IDEA. + * User: SimonBrandhof + * Date: Jul 20, 2010 + * Time: 10:47:13 PM + * To change this template use File | Settings | File Templates. + */ +public class AbstractPurgeTest extends AbstractDbUnitTestCase { + + @Test + public void purgeSnapshots() throws SQLException { + setupData("purgeSnapshots"); + + final FakePurge purge = new FakePurge(getSession()); + purge.purge(null); + + checkTables("purgeSnapshots", "snapshots", "project_measures", "measure_data", "rule_failures", "snapshot_sources", "dependencies"); + } +} + +class FakePurge extends AbstractPurge { + public FakePurge(DatabaseSession session) { + super(session); + } + + public void purge(PurgeContext context) { + deleteSnapshotData(Arrays.asList(3, 4)); + } +}
\ No newline at end of file diff --git a/sonar-core/src/test/java/org/sonar/core/qualitymodel/DefaultModelProviderTest.java b/sonar-core/src/test/java/org/sonar/core/qualitymodel/DefaultModelProviderTest.java new file mode 100644 index 00000000000..beb59782327 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/qualitymodel/DefaultModelProviderTest.java @@ -0,0 +1,121 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.core.qualitymodel; + +import org.junit.Test; +import org.sonar.api.qualitymodel.Characteristic; +import org.sonar.api.qualitymodel.Model; +import org.sonar.api.qualitymodel.ModelDefinition; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.*; + +public class DefaultModelProviderTest extends AbstractDbUnitTestCase { + + @Test + public void reset() { + setupData("shared"); + DefaultModelProvider provider = new DefaultModelProvider(getSessionFactory()); + + Model model = Model.createByName("M1"); + Characteristic c1 = model.createCharacteristicByName("NEWM1C1"); + Characteristic c1a = model.createCharacteristicByName("NEWM1C1A"); + c1.addChild(c1a); + + model.createCharacteristicByName("NEWM1C2"); + model = provider.reset(model); + + model = getSession().getSingleResult(Model.class, "name", "M1"); + assertNotNull(model); + assertThat(model.getCharacteristics().size(), is(3)); + assertThat(model.getCharacteristicByName("NEWM1C1A").getParents().size(), is(1)); + assertNotNull(model.getCharacteristicByName("NEWM1C1A").getParent("NEWM1C1")); + } + + @Test + public void findByName() { + setupData("shared"); + DefaultModelProvider provider = new DefaultModelProvider(getSessionFactory()); + Model model = provider.findByName("M1"); + assertNotNull(model); + assertNotNull(model.getCharacteristicByName("M1C1")); + } + + @Test + public void findByNameNotFound() { + setupData("shared"); + DefaultModelProvider provider = new DefaultModelProvider(getSessionFactory()); + assertNull(provider.findByName("UNKNOWN")); + } + + @Test + public void noDefinitionsToRegister() { + setupData("shared"); + DefaultModelProvider provider = new DefaultModelProvider(getSessionFactory()); + provider.registerDefinitions(); + + // same state + List<Model> models = getSession().getResults(Model.class); + assertThat(models.size(), is(2)); + } + + @Test + public void registerOnlyNewDefinitions() { + setupData("shared"); + + ModelDefinition existingDefinition = new FakeDefinition("M1"); + ModelDefinition newDefinition = new FakeDefinition("NEWMODEL"); + + ModelDefinition[] definitions = new ModelDefinition[]{existingDefinition, newDefinition}; + DefaultModelProvider provider = new DefaultModelProvider(getSessionFactory(), definitions); + provider.registerDefinitions(); + + List<Model> models = getSession().getResults(Model.class); + assertThat(models.size(), is(3)); // 2 existing + one new + } + + @Test + public void exists() { + setupData("shared"); + assertTrue(DefaultModelProvider.exists(getSession(), "M1")); + } + + @Test + public void notExists() { + setupData("shared"); + assertFalse(DefaultModelProvider.exists(getSession(), "UNKNOWN")); + } +} + +class FakeDefinition extends ModelDefinition { + + public FakeDefinition(String name) { + super(name); + } + + @Override + public Model create() { + return Model.create(); + } + +}
\ No newline at end of file diff --git a/sonar-core/src/test/java/org/sonar/core/qualitymodel/ModelTest.java b/sonar-core/src/test/java/org/sonar/core/qualitymodel/ModelTest.java new file mode 100644 index 00000000000..a9793912a13 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/qualitymodel/ModelTest.java @@ -0,0 +1,106 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.core.qualitymodel; + +import org.junit.Test; +import org.sonar.api.qualitymodel.Characteristic; +import org.sonar.api.qualitymodel.Model; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.internal.matchers.IsCollectionContaining.hasItems; + +public class ModelTest extends AbstractDbUnitTestCase { + + @Test + public void saveModelAndCharacteristics() { + setupData("saveModelAndCharacteristics"); + Model model = Model.createByName("fake"); + model.createCharacteristicByName("Efficiency"); + model.createCharacteristicByName("Usability"); + getSession().save(model); + getSession().commit(); + + model = getSession().getSingleResult(Model.class, "name", "fake"); + assertThat(model.getName(), is("fake")); + assertThat(model.getCharacteristics().size(), is(2)); + assertThat(model.getRootCharacteristics().size(), is(2)); + assertNotNull(model.getCharacteristicByName("Efficiency")); + } + + /** + * max one parent by characteristic + */ + @Test + public void saveTreeOfCharacteristics() { + setupData("testTreeOfCharacteristics"); + Model model = Model.createByName("fake"); + + Characteristic efficiency = model.createCharacteristicByName("Efficiency"); + Characteristic usability = model.createCharacteristicByName("Usability"); + Characteristic cpuEfficiency = model.createCharacteristicByName("CPU Efficiency"); + Characteristic ramEfficiency = model.createCharacteristicByName("RAM Efficiency"); + + efficiency.addChildren(cpuEfficiency, ramEfficiency); + + getSession().save(model); + getSession().commit(); + + model = getSession().getSingleResult(Model.class, "name", "fake"); + assertThat(model.getCharacteristics().size(), is(4)); + assertThat(model.getCharacteristics(), hasItems(efficiency, usability, ramEfficiency, cpuEfficiency)); + assertThat(efficiency.getChildren(), hasItems(ramEfficiency, cpuEfficiency)); + assertTrue(ramEfficiency.getChildren().isEmpty()); + assertThat(ramEfficiency.getParents(), hasItems(efficiency)); + } + + /** + * many-to-many relation between characteristics + */ + @Test + public void testGraphOfCharacteristics() { + setupData("testGraphOfCharacteristics"); + Model model = Model.createByName("fake"); + + Characteristic level1a = model.createCharacteristicByName("level1a"); + Characteristic level1b = model.createCharacteristicByName("level1b"); + Characteristic level2a = model.createCharacteristicByName("level2a"); + Characteristic level2b = model.createCharacteristicByName("level2b"); + + level1a.addChildren(level2a, level2b); + level1b.addChildren(level2a, level2b); + + getSession().save(model); + getSession().commit(); + + Model persistedModel = getSession().getSingleResult(Model.class, "name", "fake"); + assertThat(persistedModel.getCharacteristics().size(), is(4)); + assertThat(persistedModel.getRootCharacteristics().size(), is(2)); + + assertThat(persistedModel.getCharacteristicByName("level1a").getChildren().size(), is(2)); + assertThat(persistedModel.getCharacteristicByName("level1b").getChildren().size(), is(2)); + + assertThat(persistedModel.getCharacteristicByName("level2a").getParents().size(), is(2)); + assertThat(persistedModel.getCharacteristicByName("level2b").getParents().size(), is(2)); + } +} diff --git a/sonar-core/src/test/java/org/sonar/core/rule/DefaultRuleProviderTest.java b/sonar-core/src/test/java/org/sonar/core/rule/DefaultRuleProviderTest.java new file mode 100644 index 00000000000..10830c4256f --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/rule/DefaultRuleProviderTest.java @@ -0,0 +1,83 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.core.rule; + +import org.junit.Test; +import org.sonar.api.rules.Rule; +import org.sonar.api.rules.RuleQuery; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import java.util.Collection; + +import static org.hamcrest.CoreMatchers.anyOf; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; + +public class DefaultRuleProviderTest extends AbstractDbUnitTestCase { + + @Test + public void findByKey() { + setupData("shared"); + DefaultRuleProvider provider = new DefaultRuleProvider(getSessionFactory()); + Rule rule = provider.findByKey("checkstyle", "com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"); + assertNotNull(rule); + assertThat(rule.getKey(), is("com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck")); + assertThat(rule.isEnabled(), is(true)); + } + + @Test + public void findRepositoryRules() { + setupData("shared"); + DefaultRuleProvider provider = new DefaultRuleProvider(getSessionFactory()); + Collection<Rule> rules = provider.findAll(RuleQuery.create().withRepositoryKey("checkstyle")); + assertNotNull(rules); + assertThat(rules.size(), is(2)); // only enabled checkstyle rules + } + + @Test + public void findAllEnabled() { + setupData("shared"); + DefaultRuleProvider provider = new DefaultRuleProvider(getSessionFactory()); + Collection<Rule> rules = provider.findAll(RuleQuery.create()); + assertNotNull(rules); + assertThat(rules.size(), is(3)); // only enabled checkstyle+pmd rules + for (Rule rule : rules) { + assertThat(rule.getId(), anyOf(is(1), is(3), is(4))); + } + } + + @Test + public void doNotFindDisabledRules() { + setupData("shared"); + DefaultRuleProvider provider = new DefaultRuleProvider(getSessionFactory()); + Rule rule = provider.findByKey("checkstyle", "DisabledCheck"); + assertNull(rule); + } + + @Test + public void doNotFindUnknownRules() { + setupData("shared"); + DefaultRuleProvider provider = new DefaultRuleProvider(getSessionFactory()); + Collection<Rule> rules = provider.findAll(RuleQuery.create().withRepositoryKey("unknown_repository")); + assertThat(rules.size(), is(0)); + } +} diff --git a/sonar-core/src/test/java/org/sonar/jpa/dao/AsyncMeasuresDaoTest.java b/sonar-core/src/test/java/org/sonar/jpa/dao/AsyncMeasuresDaoTest.java new file mode 100644 index 00000000000..3c70c3fd62c --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/jpa/dao/AsyncMeasuresDaoTest.java @@ -0,0 +1,165 @@ +/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.jpa.dao;
+
+import org.junit.Test;
+import org.sonar.api.database.model.AsyncMeasureSnapshot;
+import org.sonar.api.database.model.MeasureModel;
+import org.sonar.api.database.model.ResourceModel;
+import org.sonar.api.database.model.Snapshot;
+import org.sonar.jpa.test.AbstractDbUnitTestCase;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+public class AsyncMeasuresDaoTest extends AbstractDbUnitTestCase {
+
+ private static final int PROJECT_ID = 1;
+ private static final int METRIC_ID = 1;
+
+ @Test
+ public void testGetNextAsyncMeasureSnapshot() {
+ setupData("sharedFixture", "testGetNextAsyncMeasureSnapshot");
+
+ AsyncMeasuresDao asyncMeasuresDao = new AsyncMeasuresDao(getSession());
+ AsyncMeasureSnapshot asyncMeasure = asyncMeasuresDao.getNextAsyncMeasureSnapshot(
+ PROJECT_ID, METRIC_ID, stringToDate("2008-12-04 08:00:00.00"));
+
+ assertThat(asyncMeasure.getId(), is(3));
+ }
+
+ @Test
+ public void testGetNextSnapshotsUntilDate() {
+ setupData("sharedFixture", "testGetNextSnapshotsUntilDate");
+
+ AsyncMeasuresDao asyncMeasuresDao = new AsyncMeasuresDao(getSession());
+ MeasureModel asyncMeasure = getSession().getEntityManager().find(MeasureModel.class, 1l);
+ List<Snapshot> snapshotIds = asyncMeasuresDao.getNextSnapshotsUntilDate(
+ asyncMeasure, stringToDate("2008-12-06 12:00:00.00"));
+
+ assertThat(snapshotIds.size(), is(2));
+ assertThat(snapshotIds.get(0).getId(), is(2));
+ assertThat(snapshotIds.get(1).getId(), is(4));
+ }
+
+ @Test
+ public void testGetPreviousSnapshot() {
+ setupData("sharedFixture", "testGetPreviousSnapshot");
+ AsyncMeasuresDao asyncMeasuresDao = new AsyncMeasuresDao(getSession());
+ Snapshot s = new Snapshot();
+ s.setCreatedAt(stringToDate("2008-12-04 08:00:00.00"));
+ s.setScope(ResourceModel.SCOPE_PROJECT);
+ ResourceModel resource1 = getSession().getEntity(ResourceModel.class, 1);
+ ResourceModel resource2 = getSession().getEntity(ResourceModel.class, 2);
+
+ s.setResource(resource1);
+ assertThat(asyncMeasuresDao.getPreviousSnapshot(s).getId(), is(1));
+
+ s.setResource(resource2);
+ assertThat(asyncMeasuresDao.getPreviousSnapshot(s).getId(), is(5));
+ }
+
+ @Test
+ public void testGetNextAsyncMeasureSnapshotsUntilDate() {
+ setupData("sharedFixture", "testGetNextAsyncMeasureSnapshotsUntilDate");
+
+ AsyncMeasuresDao asyncMeasuresDao = new AsyncMeasuresDao(getSession());
+ MeasureModel asyncMeasure = getSession().getEntityManager().find(MeasureModel.class, 3l);
+ List<AsyncMeasureSnapshot> asyncMeasureSnapshots = asyncMeasuresDao.getNextAsyncMeasureSnapshotsUntilDate(
+ asyncMeasure, stringToDate("2008-12-06 08:00:00.00"));
+
+ assertThat(asyncMeasureSnapshots.size(), is(2));
+ assertThat(asyncMeasureSnapshots.get(0).getId(), is(2));
+ assertThat(asyncMeasureSnapshots.get(1).getId(), is(3));
+ }
+
+ @Test
+ public void testDeleteAsyncMeasure() {
+ setupData("sharedFixture", "testDeleteAsyncMeasure");
+
+ AsyncMeasuresDao asyncMeasuresDao = new AsyncMeasuresDao(getSession());
+ MeasureModel asyncMeasure = getSession().getEntityManager().find(MeasureModel.class, 1l);
+ asyncMeasuresDao.deleteAsyncMeasure(asyncMeasure);
+
+ getSession().commit();
+ checkTables("testDeleteAsyncMeasure", "project_measures", "async_measure_snapshots");
+ }
+
+ @Test
+ public void testGetAsyncMeasureSnapshotsFromSnapshotId() {
+ setupData("sharedFixture", "testGetAsyncMeasureSnapshotsFromSnapshotId");
+
+ AsyncMeasuresDao asyncMeasuresDao = new AsyncMeasuresDao(getSession());
+ Integer snapshotId = 1;
+ List<AsyncMeasureSnapshot> asyncMeasureSnapshots = asyncMeasuresDao.getAsyncMeasureSnapshotsFromSnapshotId(
+ snapshotId, Arrays.asList(1));
+ assertThat(asyncMeasureSnapshots.size(), is(1));
+ assertThat(asyncMeasureSnapshots.get(0).getId(), is(2));
+ }
+
+ @Test
+ public void testGetLastAsyncMeasureSnapshot() {
+ setupData("sharedFixture", "testGetLastAsyncMeasureSnapshot");
+
+ AsyncMeasuresDao asyncMeasuresDao = new AsyncMeasuresDao(getSession());
+ AsyncMeasureSnapshot asyncMeasureSnapshot = asyncMeasuresDao.getLastAsyncMeasureSnapshot(
+ PROJECT_ID, METRIC_ID, stringToDate("2008-12-04 12:00:00.00"));
+ assertThat(asyncMeasureSnapshot.getId(), is(2));
+ }
+
+ @Test
+ public void testDeleteAsyncMeasureSnapshots() {
+ setupData("sharedFixture", "testDeleteAsyncMeasureSnapshots");
+
+ AsyncMeasuresDao asyncMeasuresDao = new AsyncMeasuresDao(getSession());
+ asyncMeasuresDao.deleteAsyncMeasureSnapshots(1l);
+
+ checkTables("testDeleteAsyncMeasureSnapshots", "async_measure_snapshots");
+ }
+
+ @Test
+ public void testGetPreviousAsyncMeasureSnapshots() {
+ setupData("sharedFixture", "testGetPreviousAsyncMeasureSnapshots");
+
+ AsyncMeasuresDao asyncMeasuresDao = new AsyncMeasuresDao(getSession());
+ List<AsyncMeasureSnapshot> asyncMeasureSnapshots = asyncMeasuresDao.getPreviousAsyncMeasureSnapshots(
+ PROJECT_ID, stringToDate("2008-12-04 08:00:00.00"), stringToDate("2008-12-08 08:00:00.00"));
+ assertThat(asyncMeasureSnapshots.size(), is(2));
+ assertThat(asyncMeasureSnapshots.get(0).getId(), is(5));
+ assertThat(asyncMeasureSnapshots.get(1).getId(), is(6));
+ }
+
+
+ private static Date stringToDate(String sDate) {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SS");
+ try {
+ return sdf.parse(sDate);
+ } catch (ParseException e) {
+ throw new RuntimeException("Bad date format.");
+ }
+ }
+
+}
diff --git a/sonar-core/src/test/java/org/sonar/jpa/dao/AsyncMeasuresServiceTest.java b/sonar-core/src/test/java/org/sonar/jpa/dao/AsyncMeasuresServiceTest.java new file mode 100644 index 00000000000..9ef3ad41034 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/jpa/dao/AsyncMeasuresServiceTest.java @@ -0,0 +1,153 @@ +/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.jpa.dao;
+
+import org.junit.Test;
+import org.sonar.api.database.model.Snapshot;
+import org.sonar.jpa.test.AbstractDbUnitTestCase;
+
+public class AsyncMeasuresServiceTest extends AbstractDbUnitTestCase {
+
+ @Test
+ public void assignLatestMeasuresToLastSnapshot() {
+ setupData("sharedFixture", "assignLatestMeasuresToLastSnapshot");
+
+ AsyncMeasuresService asyncMeasuresService = new AsyncMeasuresService(getSession());
+ Snapshot snapshot = getSession().getEntityManager().find(Snapshot.class, 2);
+ asyncMeasuresService.refresh(snapshot);
+
+ checkTables("assignLatestMeasuresToLastSnapshot", "async_measure_snapshots");
+ }
+
+ @Test
+ public void assignNewMeasuresToLastSnapshot() {
+ setupData("sharedFixture", "assignNewMeasuresToLastSnapshot");
+
+ AsyncMeasuresService asyncMeasuresService = new AsyncMeasuresService(getSession());
+ Snapshot snapshot = getSession().getEntityManager().find(Snapshot.class, 2);
+ asyncMeasuresService.refresh(snapshot);
+
+ checkTables("assignNewMeasuresToLastSnapshot", "async_measure_snapshots");
+ }
+
+ @Test
+ public void assignMeasuresWhenNoPreviousSnapshot() {
+ setupData("sharedFixture", "assignMeasuresWhenNoPreviousSnapshot");
+
+ AsyncMeasuresService asyncMeasuresService = new AsyncMeasuresService(getSession());
+ Snapshot snapshot = getSession().getEntityManager().find(Snapshot.class, 1);
+ asyncMeasuresService.refresh(snapshot);
+
+ checkTables("assignMeasuresWhenNoPreviousSnapshot", "async_measure_snapshots");
+ }
+
+ @Test
+ public void assignLatestMeasuresWhenNoPreviousSnapshot() {
+ setupData("sharedFixture", "assignLatestMeasuresWhenNoPreviousSnapshot");
+
+ AsyncMeasuresService asyncMeasuresService = new AsyncMeasuresService(getSession());
+ Snapshot snapshot = getSession().getEntityManager().find(Snapshot.class, 1);
+ asyncMeasuresService.refresh(snapshot);
+
+ checkTables("assignLatestMeasuresWhenNoPreviousSnapshot", "async_measure_snapshots");
+ }
+
+ @Test
+ public void assignPastMeasuresToPastSnapshot() {
+ setupData("sharedFixture", "assignPastMeasuresToPastSnapshot");
+
+ AsyncMeasuresService asyncMeasuresService = new AsyncMeasuresService(getSession());
+ Snapshot snapshot = getSession().getEntityManager().find(Snapshot.class, 3);
+ asyncMeasuresService.refresh(snapshot);
+
+ checkTables("assignPastMeasuresToPastSnapshot", "async_measure_snapshots");
+ }
+
+ @Test
+ public void assignNewMeasureToFutureSnapshots() {
+ setupData("sharedFixture", "assignNewMeasureToFutureSnapshots");
+
+ AsyncMeasuresService asyncMeasuresService = new AsyncMeasuresService(getSession());
+ asyncMeasuresService.registerMeasure(2l);
+
+ checkTables("assignNewMeasureToFutureSnapshots", "async_measure_snapshots");
+ }
+
+ @Test
+ public void assignMeasureToFutureSnapshotsWithDifferentMetric() {
+ setupData("sharedFixture", "assignMeasureToFutureSnapshotsWithDifferentMetric");
+
+ AsyncMeasuresService asyncMeasureService = new AsyncMeasuresService(getSession());
+ asyncMeasureService.registerMeasure(3l);
+
+ checkTables("assignMeasureToFutureSnapshotsWithDifferentMetric", "async_measure_snapshots");
+ }
+
+ @Test
+ public void assignAPastMeasureToNextSnapshotsWithDifferentMetric() {
+ setupData("sharedFixture", "assignAPastMeasureToNextSnapshotsWithDifferentMetric");
+
+ AsyncMeasuresService asyncMeasureService = new AsyncMeasuresService(getSession());
+ asyncMeasureService.registerMeasure(2l);
+
+ checkTables("assignAPastMeasureToNextSnapshotsWithDifferentMetric", "async_measure_snapshots");
+ }
+
+ @Test
+ public void addFutureSnapshot() {
+ setupData("sharedFixture", "addFutureSnapshot");
+
+ AsyncMeasuresService asyncMeasureService = new AsyncMeasuresService(getSession());
+ asyncMeasureService.registerMeasure(2l);
+
+ checkTables("addFutureSnapshot", "async_measure_snapshots");
+ }
+
+ @Test
+ public void addInvisibleMeasure() {
+ setupData("sharedFixture", "addInvisibleMeasure");
+
+ AsyncMeasuresService asyncMeasureService = new AsyncMeasuresService(getSession());
+ asyncMeasureService.registerMeasure(2l);
+
+ checkTables("addInvisibleMeasure", "async_measure_snapshots");
+ }
+
+ @Test
+ public void deleteMeasure() {
+ setupData("sharedFixture", "deleteMeasure");
+
+ AsyncMeasuresService asyncMeasureService = new AsyncMeasuresService(getSession());
+ asyncMeasureService.deleteMeasure(2l);
+
+ checkTables("deleteMeasure", "async_measure_snapshots");
+ }
+
+ @Test
+ public void deleteLastMeasure() {
+ setupData("sharedFixture", "deleteLastMeasure");
+
+ AsyncMeasuresService asyncMeasureService = new AsyncMeasuresService(getSession());
+ asyncMeasureService.deleteMeasure(1l);
+
+ checkTables("deleteLastMeasure", "async_measure_snapshots");
+ }
+
+}
diff --git a/sonar-core/src/test/java/org/sonar/jpa/dao/MeasuresDaoTest.java b/sonar-core/src/test/java/org/sonar/jpa/dao/MeasuresDaoTest.java new file mode 100644 index 00000000000..5502905e5e6 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/jpa/dao/MeasuresDaoTest.java @@ -0,0 +1,107 @@ +/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.jpa.dao;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.database.model.ResourceModel;
+import org.sonar.api.measures.Metric;
+import org.sonar.jpa.test.AbstractDbUnitTestCase;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertThat;
+
+public class MeasuresDaoTest extends AbstractDbUnitTestCase {
+
+ private MeasuresDao service;
+ private ResourceModel project;
+
+ @Before
+ public void before() throws Exception {
+ service = new MeasuresDao(getSession());
+ project = new ResourceModel(ResourceModel.SCOPE_PROJECT, "foo:bar", ResourceModel.QUALIFIER_PROJECT_TRUNK, null, "Foo");
+ project.setName("project name");
+ getSession().save(project);
+ }
+
+ @Test
+ public void shouldReturnUserDefinedMetrics() {
+ for (Metric metric : createMetrics()) {
+ getSession().save(metric);
+ }
+
+ Collection<Metric> metrics = service.getUserDefinedMetrics();
+ assertThat(metrics.size(), is(2));
+ for (Metric metric : metrics) {
+ assertThat(metric.getOrigin(), not(Metric.Origin.JAV));
+ }
+ }
+
+ @Test
+ public void shouldRegisterMetrics() {
+ Collection<Metric> newMetrics = createMetrics();
+ service.registerMetrics(newMetrics);
+
+ Collection<Metric> metrics = service.getEnabledMetrics();
+ assertThat(metrics.size(), is(newMetrics.size()));
+ }
+
+ @Test
+ public void shouldDisabledMetrics() {
+ Collection<Metric> newMetrics = createMetrics();
+
+ service.disabledMetrics(newMetrics);
+
+ Collection<Metric> allMetrics = service.getMetrics();
+ assertThat(allMetrics.size(), is(newMetrics.size()));
+
+ Collection<Metric> disabledMetrics = service.getEnabledMetrics();
+ assertThat(disabledMetrics.size(), is(0));
+ }
+
+
+ private Collection<Metric> createMetrics() {
+ Metric m1 = new Metric("metric1");
+ m1.setEnabled(false);
+ m1.setOrigin(Metric.Origin.JAV);
+
+ Metric m2 = new Metric("metric2");
+ m2.setEnabled(true);
+ m2.setOrigin(Metric.Origin.JAV);
+
+ Metric m3 = new Metric("metric3");
+ m3.setEnabled(false);
+ m3.setOrigin(Metric.Origin.GUI);
+
+ Metric m4 = new Metric("metric4");
+ m4.setEnabled(true);
+ m4.setOrigin(Metric.Origin.GUI);
+
+ Metric m5 = new Metric("metric5");
+ m5.setEnabled(true);
+ m5.setOrigin(Metric.Origin.WS);
+
+ return Arrays.asList(m1, m2, m3, m4, m5);
+ }
+}
diff --git a/sonar-core/src/test/java/org/sonar/jpa/dao/ProfilesDaoTest.java b/sonar-core/src/test/java/org/sonar/jpa/dao/ProfilesDaoTest.java new file mode 100644 index 00000000000..796435c5dab --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/jpa/dao/ProfilesDaoTest.java @@ -0,0 +1,68 @@ +/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.jpa.dao;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.database.model.ResourceModel;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.jpa.test.AbstractDbUnitTestCase;
+
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.*;
+
+public class ProfilesDaoTest extends AbstractDbUnitTestCase {
+
+ private ProfilesDao profilesDao;
+
+ @Before
+ public void setup() {
+ profilesDao = new ProfilesDao(getSession());
+ }
+
+ @Test
+ public void shouldGetProfiles() {
+ setupData("shouldGetProfiles");
+
+ List<RulesProfile> profiles = profilesDao.getProfiles("java");
+
+ assertThat(profiles.size(), is(2));
+ }
+
+ @Test
+ public void testGetActiveProfile() {
+ RulesProfile testDefaultProfile = new RulesProfile("default", "java", true, true);
+ RulesProfile testProfile = new RulesProfile("not default", "java", false, false);
+ getSession().save(testDefaultProfile, testProfile);
+
+ ResourceModel testResourceWithProfile = new ResourceModel(ResourceModel.SCOPE_PROJECT, "withProfile", "qual", null, "test");
+ testResourceWithProfile.setRulesProfile(testProfile);
+ ResourceModel testResourceWithNoProfile = new ResourceModel(ResourceModel.SCOPE_PROJECT, "withoutProfile", "qual", null, "test");
+ getSession().save(testResourceWithProfile, testResourceWithNoProfile);
+
+ assertNull(profilesDao.getActiveProfile("wrongLanguage", "withoutProfile"));
+ assertEquals(testDefaultProfile.getId(), profilesDao.getActiveProfile("java", "wrongKey").getId());
+ assertEquals(testDefaultProfile.getId(), profilesDao.getActiveProfile("java", "withoutProfile").getId());
+ assertEquals(testProfile.getId(), profilesDao.getActiveProfile("java", "withProfile").getId());
+ }
+
+}
diff --git a/sonar-core/src/test/java/org/sonar/jpa/dao/RulesDaoTest.java b/sonar-core/src/test/java/org/sonar/jpa/dao/RulesDaoTest.java new file mode 100644 index 00000000000..30dc9fc0602 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/jpa/dao/RulesDaoTest.java @@ -0,0 +1,131 @@ +/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.jpa.dao;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.rules.*;
+import org.sonar.jpa.test.AbstractDbUnitTestCase;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+public class RulesDaoTest extends AbstractDbUnitTestCase {
+
+ private RulesDao rulesDao;
+
+ @Before
+ public void setup() {
+ rulesDao = new RulesDao(getSession());
+ }
+
+ @Test
+ public void shouldGetRules() {
+ setupData("shouldGetRules");
+
+ List<Rule> rules = rulesDao.getRules();
+ assertThat(rules, notNullValue());
+ assertThat(rules.size(), is(2));
+
+ assertEquals("rule_one", rules.get(0).getKey());
+ assertEquals(1, rules.get(0).getParams().size());
+ assertEquals("category one", rules.get(0).getRulesCategory().getName());
+ }
+
+ @Test
+ public void shouldGetRuleWithRuleKeyAndPluginKey() {
+ setupData("shouldGetRuleWithRuleKeyAndPluginKey");
+
+ Rule rule = rulesDao.getRuleByKey("plugin", "checkstyle.rule1");
+ assertThat(rule, notNullValue());
+ assertThat(rule.getId(), notNullValue());
+
+ Rule rule2 = rulesDao.getRuleByKey("plugin", "key not found");
+ assertThat(rule2, nullValue());
+ }
+
+ @Test
+ public void shouldCountNumberOfRulesOfACategoryForGivenPlugins() {
+ setupData("shouldCountNumberOfRulesOfACategoryForGivenPlugins");
+
+ Long result = rulesDao.countRules(Arrays.asList("plugin1", "plugin2"), "category one");
+ assertThat(result, is(3L));
+
+ result = rulesDao.countRules(Arrays.asList("plugin1", "plugin2"), "category two");
+ assertThat(result, is(1L));
+ }
+
+ @Test
+ public void shouldGetRuleParams() {
+ setupData("shouldGetRuleParams");
+
+ List<RuleParam> ruleParams = rulesDao.getRuleParams();
+
+ assertThat(ruleParams.size(), is(3));
+ }
+
+ @Test
+ public void shouldSynchronizeRuleOfActiveRule() {
+ setupData("shouldSynchronizeRuleOfActiveRule");
+ Rule rule = new Rule(null, "other key", (String) null, null, null);
+ RuleParam ruleParam = new RuleParam(null, "rule1_param1", null, null);
+ rule.setParams(Arrays.asList(ruleParam));
+ ActiveRule activeRule = new ActiveRule(null, rule, null);
+ ActiveRuleParam activeRuleParam = new ActiveRuleParam(activeRule, ruleParam, null);
+ activeRule.setActiveRuleParams(Arrays.asList(activeRuleParam));
+
+ rulesDao.synchronizeRuleOfActiveRule(activeRule, "plugin");
+
+ assertThat(activeRule.getRule().getId(), notNullValue());
+ assertThat(activeRule.getActiveRuleParams().size(), is(1));
+ }
+
+ @Test
+ public void shouldGetRulesProfileById() {
+ RulesProfile rulesProfile = new RulesProfile("profil", "java", true, true);
+ getSession().save(rulesProfile);
+
+ RulesProfile rulesProfileExpected = rulesDao.getProfileById(rulesProfile.getId());
+
+ assertThat(rulesProfileExpected, is(rulesProfile));
+ }
+
+ @Test
+ public void shouldAddActiveRulesToProfile() {
+ setupData("shouldAddActiveRulesToProfile");
+
+ Rule rule = new Rule("rule1", "key1", "config1", new RulesCategory("test"), null);
+ RuleParam ruleParam = new RuleParam(null, "param1", null, null);
+ rule.setParams(Arrays.asList(ruleParam));
+
+ ActiveRule activeRule = new ActiveRule(null, rule, RulePriority.MAJOR);
+ ActiveRuleParam activeRuleParam = new ActiveRuleParam(activeRule, ruleParam, "20");
+ activeRule.setActiveRuleParams(Arrays.asList(activeRuleParam));
+ rulesDao.addActiveRulesToProfile(Arrays.asList(activeRule), 1, "plugin");
+
+ checkTables("shouldAddActiveRulesToProfile", "rules", "active_rules", "rules_profiles");
+ }
+
+}
diff --git a/sonar-core/src/test/java/org/sonar/jpa/dialect/DerbyTest.java b/sonar-core/src/test/java/org/sonar/jpa/dialect/DerbyTest.java new file mode 100644 index 00000000000..298f4775765 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/jpa/dialect/DerbyTest.java @@ -0,0 +1,32 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.dialect; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import org.junit.Test; + +public class DerbyTest { + @Test + public void matchesJdbcURL() { + assertThat(new Derby().matchesJdbcURL("jdbc:derby:foo"), is(true)); + assertThat(new Derby().matchesJdbcURL("jdbc:hsql:foo"), is(false)); + } +} diff --git a/sonar-core/src/test/java/org/sonar/jpa/dialect/DialectRepositoryTest.java b/sonar-core/src/test/java/org/sonar/jpa/dialect/DialectRepositoryTest.java new file mode 100644 index 00000000000..0f7db36bd7a --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/jpa/dialect/DialectRepositoryTest.java @@ -0,0 +1,70 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.dialect; + +import org.junit.Test; +import static org.junit.Assert.*; +import org.sonar.api.database.DatabaseProperties; +import org.sonar.api.utils.SonarException; + +public class DialectRepositoryTest { + + @Test + public void testFindById() { + Dialect d = DialectRepository.find(DatabaseProperties.DIALECT_MYSQL, null); + assertEquals(MySql.class, d.getClass()); + } + + @Test + public void testFindByJdbcUrl() { + Dialect d = DialectRepository.find(null, "jdbc:mysql:foo:bar"); + assertEquals(MySql.class, d.getClass()); + } + + @Test + public void testFindClassName() { + Dialect d = DialectRepository.find(TestDialect.class.getName(), null); + assertEquals(TestDialect.class, d.getClass()); + } + + @Test(expected=SonarException.class) + public void testFindNoMatch() { + DialectRepository.find("foo", "bar"); + } + + public static class TestDialect implements Dialect { + public boolean matchesJdbcURL(String jdbcConnectionURL) { + return false; + } + + public String getId() { + return "testDialect"; + } + + public Class<? extends org.hibernate.dialect.Dialect> getHibernateDialectClass() { + return null; + } + + public String getActiveRecordDialectCode() { + return null; + } + } + +} diff --git a/sonar-core/src/test/java/org/sonar/jpa/dialect/HsqlDbTest.java b/sonar-core/src/test/java/org/sonar/jpa/dialect/HsqlDbTest.java new file mode 100644 index 00000000000..20cebfd9eb7 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/jpa/dialect/HsqlDbTest.java @@ -0,0 +1,32 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.dialect; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import org.junit.Test; + +public class HsqlDbTest { + @Test + public void matchesJdbcURL() { + assertThat(new HsqlDb().matchesJdbcURL("jdbc:hsqldb:hsql:foo"), is(true)); + assertThat(new HsqlDb().matchesJdbcURL("jdbc:hsql:foo"), is(false)); + } +} diff --git a/sonar-core/src/test/java/org/sonar/jpa/dialect/MsSqlTest.java b/sonar-core/src/test/java/org/sonar/jpa/dialect/MsSqlTest.java new file mode 100644 index 00000000000..5d2a9a53043 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/jpa/dialect/MsSqlTest.java @@ -0,0 +1,37 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.dialect; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import org.junit.Test; + +public class MsSqlTest { + + @Test + public void matchesJdbcURL() { + assertThat(new MsSql().matchesJdbcURL("jdbc:jtds:sqlserver://localhost;databaseName=SONAR;SelectMethod=Cursor"), is(true)); + assertThat(new MsSql().matchesJdbcURL("jdbc:microsoft:sqlserver://localhost:1433;databasename=sonar"), is(true)); + + assertThat(new MsSql().matchesJdbcURL("jdbc:hsql:foo"), is(false)); + assertThat(new MsSql().matchesJdbcURL("jdbc:mysql:foo"), is(false)); + } + +} diff --git a/sonar-core/src/test/java/org/sonar/jpa/dialect/MySqlTest.java b/sonar-core/src/test/java/org/sonar/jpa/dialect/MySqlTest.java new file mode 100644 index 00000000000..ad60fa7e0a1 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/jpa/dialect/MySqlTest.java @@ -0,0 +1,37 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.dialect; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import org.junit.Test; + +public class MySqlTest { + + @Test + public void matchesJdbcURL() { + assertThat(new MySql().matchesJdbcURL("jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8"), is(true)); + assertThat(new MySql().matchesJdbcURL("JDBC:MYSQL://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8"), is(true)); + + assertThat(new MySql().matchesJdbcURL("jdbc:hsql:foo"), is(false)); + assertThat(new MySql().matchesJdbcURL("jdbc:oracle:foo"), is(false)); + } + +} diff --git a/sonar-core/src/test/java/org/sonar/jpa/dialect/OracleSequenceGeneratorTest.java b/sonar-core/src/test/java/org/sonar/jpa/dialect/OracleSequenceGeneratorTest.java new file mode 100644 index 00000000000..ba15aa47854 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/jpa/dialect/OracleSequenceGeneratorTest.java @@ -0,0 +1,43 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.dialect; + +import org.hibernate.id.PersistentIdentifierGenerator; +import org.junit.Test; + +import java.util.Properties; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class OracleSequenceGeneratorTest { + + @Test + public void sequenceNameShouldFollowRailsConventions() { + Properties props = new Properties(); + props.setProperty(PersistentIdentifierGenerator.TABLE, "my_table"); + props.setProperty(PersistentIdentifierGenerator.PK, "id"); + + OracleSequenceGenerator generator = new OracleSequenceGenerator(); + generator.configure(null, props, new Oracle.Oracle10gWithDecimalDialect()); + assertThat(generator.getSequenceName(), is("MY_TABLE_SEQ")); + } + +} diff --git a/sonar-core/src/test/java/org/sonar/jpa/dialect/OracleTest.java b/sonar-core/src/test/java/org/sonar/jpa/dialect/OracleTest.java new file mode 100644 index 00000000000..89145bf7305 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/jpa/dialect/OracleTest.java @@ -0,0 +1,32 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.dialect; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import org.junit.Test; + +public class OracleTest { + @Test + public void matchesJdbcURL() { + assertThat(new Oracle().matchesJdbcURL("jdbc:oracle:thin:@localhost/XE"), is(true)); + assertThat(new Oracle().matchesJdbcURL("jdbc:hsql:foo"), is(false)); + } +} diff --git a/sonar-core/src/test/java/org/sonar/jpa/dialect/PostgreSQLSequenceGeneratorTest.java b/sonar-core/src/test/java/org/sonar/jpa/dialect/PostgreSQLSequenceGeneratorTest.java new file mode 100644 index 00000000000..3738d30f56c --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/jpa/dialect/PostgreSQLSequenceGeneratorTest.java @@ -0,0 +1,43 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.dialect; + +import org.hibernate.id.PersistentIdentifierGenerator; +import org.junit.Test; + +import java.util.Properties; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class PostgreSQLSequenceGeneratorTest { + + @Test + public void sequenceNameShouldFollowRailsConventions() { + Properties props = new Properties(); + props.setProperty(PersistentIdentifierGenerator.TABLE, "my_table"); + props.setProperty(PersistentIdentifierGenerator.PK, "id"); + + PostgreSQLSequenceGenerator generator = new PostgreSQLSequenceGenerator(); + generator.configure(null, props, new PostgreSql.PostgreSQLWithDecimalDialect()); + assertThat(generator.getSequenceName(), is("my_table_id_seq")); + } + +} diff --git a/sonar-core/src/test/java/org/sonar/jpa/dialect/PostgreSqlTest.java b/sonar-core/src/test/java/org/sonar/jpa/dialect/PostgreSqlTest.java new file mode 100644 index 00000000000..b16d92c5e4d --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/jpa/dialect/PostgreSqlTest.java @@ -0,0 +1,33 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.dialect; + +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class PostgreSqlTest { + @Test + public void matchesJdbcURL() { + assertThat(new PostgreSql().matchesJdbcURL("jdbc:postgresql://localhost/sonar"), is(true)); + assertThat(new PostgreSql().matchesJdbcURL("jdbc:hsql:foo"), is(false)); + } +} diff --git a/sonar-core/src/test/java/org/sonar/jpa/entity/PropertyTest.java b/sonar-core/src/test/java/org/sonar/jpa/entity/PropertyTest.java new file mode 100644 index 00000000000..c948023d82a --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/jpa/entity/PropertyTest.java @@ -0,0 +1,39 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.entity; + +import org.junit.Test; +import org.sonar.api.database.configuration.Property; + +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; + +public class PropertyTest { + + @Test + public void encodeBlob() { + Property prop = new Property("key1", "value1"); + assertThat(prop.getValue(), is("value1")); + + prop.setValue(null); + assertThat(prop.getValue(), nullValue()); + } +} diff --git a/sonar-core/src/test/java/org/sonar/jpa/entity/SchemaMigrationTest.java b/sonar-core/src/test/java/org/sonar/jpa/entity/SchemaMigrationTest.java new file mode 100644 index 00000000000..8be589fb5b2 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/jpa/entity/SchemaMigrationTest.java @@ -0,0 +1,65 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.entity; + +import org.junit.Test; +import org.mockito.Mockito; +import org.sonar.jpa.session.MemoryDatabaseConnector; + +import java.sql.Connection; + +import static org.junit.Assert.assertEquals; + + +public class SchemaMigrationTest { + + @Test + public void currentVersionShouldBeUnknownWhenSchemaIsEmpty() throws Exception { + MemoryDatabaseConnector connector = new MemoryDatabaseConnector(SchemaMigration.VERSION_UNKNOWN); + connector.start(); + + Connection connection = Mockito.mock(Connection.class); + try { + connection = connector.getConnection(); + assertEquals(SchemaMigration.VERSION_UNKNOWN, SchemaMigration.getCurrentVersion(connection)); + } finally { + if (connection != null) { + connection.close(); + } + } + } + + @Test + public void versionShouldBeLoadedFromSchemaMigrationsTable() throws Exception { + MemoryDatabaseConnector connector = new MemoryDatabaseConnector(30); + connector.start(); + + Connection connection = null; + try { + connection = connector.getConnection(); + assertEquals(30, SchemaMigration.getCurrentVersion(connection)); + + } finally { + if (connection != null) { + connection.close(); + } + } + } +} diff --git a/sonar-core/src/test/java/org/sonar/jpa/session/AbstractDatabaseConnectorTest.java b/sonar-core/src/test/java/org/sonar/jpa/session/AbstractDatabaseConnectorTest.java new file mode 100644 index 00000000000..5d5cc9cfc83 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/jpa/session/AbstractDatabaseConnectorTest.java @@ -0,0 +1,114 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.session; + +import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.hamcrest.Matchers; +import org.junit.Test; +import org.mockito.Mockito; +import org.sonar.api.database.DatabaseProperties; +import org.sonar.jpa.dialect.HsqlDb; +import org.sonar.jpa.dialect.Oracle; + +import javax.persistence.EntityManagerFactory; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; +import java.util.Properties; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +public class AbstractDatabaseConnectorTest { + + @Test + public void autodetectDialectWhenNotExcplicitlyDefined() { + MemoryDatabaseConnector connector = new MemoryDatabaseConnector(); + connector.start(); + assertEquals(HsqlDb.class, connector.getDialect().getClass()); + connector.stop(); + } + + @Test + public void useConfiguredDialectByDefault() { + Configuration conf = MemoryDatabaseConnector.getInMemoryConfiguration(false); + conf.setProperty(DatabaseProperties.PROP_DIALECT, DatabaseProperties.DIALECT_ORACLE); + + TestDatabaseConnector connector = new TestDatabaseConnector(conf); + connector.start(); + assertEquals(Oracle.class, connector.getDialect().getClass()); + connector.stop(); + } + + @Test + public void getHibernateProperties() { + PropertiesConfiguration conf = new PropertiesConfiguration(); + conf.setProperty("sonar.foo", "foo value"); + + // all properties prefixed by sonar.hibernate are propagated to hibernate configuration (the prefix "sonar." is removed) + conf.setProperty("sonar.hibernate.foo", "hibernate.foo value"); + + // hardcoded property. Should be replaced by sonar.hibernate.hbm2ddl.auto + conf.setProperty("sonar.jdbc.hibernate.hbm2ddl", "hibernate.hbm2ddl value"); + + // the dialect is mandatory if the JDBC url is not set + conf.setProperty("sonar.jdbc.dialect", DatabaseProperties.DIALECT_ORACLE); + + AbstractDatabaseConnector connector = new TestDatabaseConnector(conf); + connector.start(); + + Properties hibernateProps = connector.getHibernateProperties(); + assertThat(hibernateProps.getProperty("sonar.foo"), Matchers.nullValue()); // not an hibernate property + assertThat(hibernateProps.getProperty("hibernate.foo"), Matchers.is("hibernate.foo value")); + assertThat(hibernateProps.getProperty("hibernate.hbm2ddl.auto"), Matchers.is("hibernate.hbm2ddl value")); + assertThat(hibernateProps.getProperty("hibernate.dialect"), Matchers.is(Oracle.Oracle10gWithDecimalDialect.class.getName())); + } + + private class TestDatabaseConnector extends AbstractDatabaseConnector { + + public TestDatabaseConnector(Configuration configuration) { + super(configuration, false); + } + + @Override + public void setupEntityManagerFactory(Properties factoryProps) { + } + + @Override + protected boolean upToDateSchemaVersion() { + return true; + } + + @Override + public EntityManagerFactory createEntityManagerFactory() { + return null; + } + + public Connection getConnection() throws SQLException { + Connection c = Mockito.mock(Connection.class); + DatabaseMetaData m = Mockito.mock(DatabaseMetaData.class); + Mockito.when(c.getMetaData()).thenReturn(m); + return c; + } + } + + +} diff --git a/sonar-core/src/test/java/org/sonar/jpa/session/DatabaseSessionTest.java b/sonar-core/src/test/java/org/sonar/jpa/session/DatabaseSessionTest.java new file mode 100644 index 00000000000..6cc891f6cf8 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/jpa/session/DatabaseSessionTest.java @@ -0,0 +1,120 @@ +/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.jpa.session;
+
+import org.hamcrest.Matchers;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.internal.matchers.IsCollectionContaining;
+import org.sonar.api.database.model.MeasureModel;
+import org.sonar.api.database.model.ResourceModel;
+import org.sonar.api.database.model.Snapshot;
+import org.sonar.api.measures.Metric;
+import org.sonar.jpa.dao.MeasuresDao;
+import org.sonar.jpa.test.AbstractDbUnitTestCase;
+
+import javax.persistence.NonUniqueResultException;
+import java.sql.Date;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+public class DatabaseSessionTest extends AbstractDbUnitTestCase {
+ private static final Long NB_INSERTS = 20000l;
+
+ private ResourceModel project1;
+ private ResourceModel project2;
+
+ @Before
+ public void setup() {
+ project1 = new ResourceModel(ResourceModel.SCOPE_PROJECT, "mygroup:myartifact", "JAV", null, "my name");
+ project2 = new ResourceModel(ResourceModel.SCOPE_PROJECT, "mygroup:myartifact1", "JAV", null, "my name 2");
+ }
+
+ @Test
+ public void performaceTestOnBatchInserts() throws Exception {
+
+ Snapshot snapshot = new Snapshot(project1, true, "", new Date(1));
+ getSession().save(project1, snapshot);
+ getSession().commit();
+
+ Metric metric = new MeasuresDao(getSession()).getMetric("classes_count");
+ for (int i = 0; i < NB_INSERTS; i++) {
+ MeasureModel pm = new MeasureModel(metric, 1.0).setSnapshotId(snapshot.getId());
+ getSession().save(pm);
+ }
+
+ getSession().commit();
+ assertEquals(NB_INSERTS, getHQLCount(MeasureModel.class));
+
+ }
+
+ @Test
+ public void testGetSingleResultWithNoResults() {
+ assertNull(getSession().getSingleResult(ResourceModel.class, "name", "test"));
+ }
+
+ @Test
+ public void testGetSingleResultWithNoCriterias() {
+ try {
+ assertNull(getSession().getSingleResult(ResourceModel.class, (Object[]) null));
+ fail("No IllegalStateException raised");
+ } catch (IllegalStateException ex) {
+ // error raised correctly
+ }
+ }
+
+ @Test
+ public void testGetSingleResultWithOneResult() {
+ getSession().save(project1);
+ ResourceModel hit = getSession().getSingleResult(ResourceModel.class, "name", "my name");
+ assertNotNull(hit);
+ assertEquals(project1, hit);
+ }
+
+ @Test
+ public void testGetSingleResultWithTwoResults() {
+ getSession().save(project1, project2);
+ try {
+ getSession().getSingleResult(ResourceModel.class, "qualifier", "JAV");
+ fail("No NonUniqueResultException raised");
+ } catch (NonUniqueResultException ex) {
+ // error raised correctly
+ }
+ }
+
+ @Test
+ public void testGetResultsWithNoResults() {
+ List<ResourceModel> hits = getSession().getResults(ResourceModel.class, "name", "foo");
+ assertTrue(hits.isEmpty());
+ }
+
+ @Test
+ public void testGetResultsWithMultipleResults() {
+ ResourceModel project3 = new ResourceModel(ResourceModel.SCOPE_PROJECT, "mygroup:myartifact3", "TEST", null, "my name 3");
+ getSession().save(project1, project2, project3);
+
+ List<ResourceModel> hits = getSession().getResults(ResourceModel.class, "qualifier", "JAV");
+ assertFalse(hits.isEmpty());
+ assertThat(hits, IsCollectionContaining.hasItems(project1, project2));
+ assertThat(hits, Matchers.not(IsCollectionContaining.hasItem(project3)));
+ }
+
+}
diff --git a/sonar-core/src/test/java/org/sonar/jpa/session/DriverDatabaseConnectorTest.java b/sonar-core/src/test/java/org/sonar/jpa/session/DriverDatabaseConnectorTest.java new file mode 100644 index 00000000000..f133296d10f --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/jpa/session/DriverDatabaseConnectorTest.java @@ -0,0 +1,92 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.session; + +import org.apache.commons.configuration.PropertiesConfiguration; +import org.hamcrest.Matchers; +import org.junit.After; +import org.junit.Test; +import org.sonar.api.database.DatabaseProperties; + +import java.sql.SQLException; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.*; + +public class DriverDatabaseConnectorTest { + + private DriverDatabaseConnector connector = null; + + @After + public void stop() { + if (connector != null) { + connector.stop(); + } + } + + @Test(expected = DatabaseException.class) + public void failsIfUnvalidConfiguration() throws SQLException { + PropertiesConfiguration conf = new PropertiesConfiguration(); + conf.setProperty(DatabaseProperties.PROP_URL, "jdbc:foo:bar//xxx"); + conf.setProperty(DatabaseProperties.PROP_DRIVER, MemoryDatabaseConnector.DRIVER); + conf.setProperty(DatabaseProperties.PROP_USER, "sa"); + conf.setProperty(DatabaseProperties.PROP_PASSWORD, null); + connector = new DriverDatabaseConnector(conf); + try { + connector.start(); + } finally { + assertFalse(connector.isStarted()); + assertFalse(connector.isOperational()); + } + } + + @Test(expected = DatabaseException.class) + public void failsIfSchemaIsNotCreated() { + connector = new DriverDatabaseConnector(MemoryDatabaseConnector.getInMemoryConfiguration(false)); + try { + connector.start(); + } finally { + assertTrue(connector.isStarted()); + assertFalse(connector.isOperational()); + } + } + + @Test(expected = DatabaseException.class) + public void failsIfUpToDateSchema() { + connector = new DriverDatabaseConnector(MemoryDatabaseConnector.getInMemoryConfiguration(true)); + try { + connector.start(); + } finally { + assertTrue(connector.isStarted()); + assertFalse(connector.isOperational()); + } + } + + @Test + public void deprecatedParametersAreStillValid() { + PropertiesConfiguration conf = new PropertiesConfiguration(); + conf.setProperty(DatabaseProperties.PROP_DRIVER_DEPRECATED, MemoryDatabaseConnector.DRIVER); + conf.setProperty(DatabaseProperties.PROP_USER_DEPRECATED, "freddy"); + connector = new DriverDatabaseConnector(conf); + + assertThat(connector.getDriver(), is(MemoryDatabaseConnector.DRIVER)); + assertThat(connector.getUsername(), Matchers.is("freddy")); + } +} diff --git a/sonar-core/src/test/java/org/sonar/jpa/session/ThreadLocalDatabaseSessionFactoryTest.java b/sonar-core/src/test/java/org/sonar/jpa/session/ThreadLocalDatabaseSessionFactoryTest.java new file mode 100644 index 00000000000..7f1c2eb5c3b --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/jpa/session/ThreadLocalDatabaseSessionFactoryTest.java @@ -0,0 +1,49 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.session; + +import org.junit.Test; +import org.sonar.api.database.DatabaseSession; + +import static org.junit.Assert.assertTrue; + +public class ThreadLocalDatabaseSessionFactoryTest { + + + @Test + public void shouldCreateOneSessionPerThread() { + final MemoryDatabaseConnector connector = new MemoryDatabaseConnector(); + connector.start(); + final DatabaseSessionFactory factory = new ThreadLocalDatabaseSessionFactory(connector); + + final DatabaseSession junitThreadSession = factory.getSession(); + assertTrue(junitThreadSession == factory.getSession()); + + new Thread() { + @Override + public void run() { + DatabaseSession threadSession = factory.getSession(); + assertTrue(threadSession != junitThreadSession); + } + + }.start(); + } + +} diff --git a/sonar-core/src/test/java/org/sonar/jpa/test/AbstractDbUnitTestCase.java b/sonar-core/src/test/java/org/sonar/jpa/test/AbstractDbUnitTestCase.java new file mode 100644 index 00000000000..0f4eb82793d --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/jpa/test/AbstractDbUnitTestCase.java @@ -0,0 +1,247 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.jpa.test; + +import org.apache.commons.io.IOUtils; +import org.dbunit.Assertion; +import org.dbunit.DatabaseUnitException; +import org.dbunit.IDatabaseTester; +import org.dbunit.JdbcDatabaseTester; +import org.dbunit.database.DatabaseConfig; +import org.dbunit.database.IDatabaseConnection; +import org.dbunit.dataset.CompositeDataSet; +import org.dbunit.dataset.DataSetException; +import org.dbunit.dataset.IDataSet; +import org.dbunit.dataset.ReplacementDataSet; +import org.dbunit.dataset.xml.FlatXmlDataSet; +import org.dbunit.ext.hsqldb.HsqldbDataTypeFactory; +import org.dbunit.operation.DatabaseOperation; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.sonar.api.database.DatabaseSession; +import org.sonar.jpa.session.DatabaseSessionFactory; +import org.sonar.jpa.dao.*; +import org.sonar.jpa.session.JpaDatabaseSession; +import org.sonar.jpa.session.MemoryDatabaseConnector; + +import java.io.InputStream; +import java.io.StringWriter; +import java.sql.SQLException; + +import static org.junit.Assert.fail; + +public abstract class AbstractDbUnitTestCase { + + private MemoryDatabaseConnector dbConnector; + private JpaDatabaseSession session; + private DaoFacade dao; + protected IDatabaseTester databaseTester; + protected IDatabaseConnection connection; + + @Before + public final void startDatabase() throws Exception { + if (dbConnector == null) { + dbConnector = new MemoryDatabaseConnector(); + dbConnector.start(); + session = new JpaDatabaseSession(dbConnector); + session.start(); + } + + databaseTester = new JdbcDatabaseTester(MemoryDatabaseConnector.DRIVER, MemoryDatabaseConnector.URL, MemoryDatabaseConnector.USER, + MemoryDatabaseConnector.PASSWORD); + databaseTester.onTearDown(); + } + + @After + public final void stopDatabase() { + if (dbConnector != null) { + dbConnector.stop(); + session.stop(); + } + } + + public DaoFacade getDao() { + if (dao == null) { + dao = new DaoFacade(new ProfilesDao(session), new RulesDao(session), new MeasuresDao(session), new AsyncMeasuresDao(session)); + } + return dao; + } + + public DatabaseSession getSession() { + return session; + } + + public DatabaseSessionFactory getSessionFactory() { + return new DatabaseSessionFactory() { + + public DatabaseSession getSession() { + return session; + } + + public void clear() { + } + }; + } + + protected final void setupData(String... testNames) { + InputStream[] streams = new InputStream[testNames.length]; + try { + for (int i = 0; i < testNames.length; i++) { + String className = getClass().getName(); + className = String.format("/%s/%s.xml", className.replace(".", "/"), testNames[i]); + streams[i] = getClass().getResourceAsStream(className); + if (streams[i] == null) { + throw new RuntimeException("Test not found :" + className); + } + } + + setupData(streams); + + } finally { + for (InputStream stream : streams) { + IOUtils.closeQuietly(stream); + } + } + } + + protected final void setupData(InputStream... dataSetStream) { + try { + IDataSet[] dataSets = new IDataSet[dataSetStream.length]; + for (int i = 0; i < dataSetStream.length; i++) { + ReplacementDataSet dataSet = new ReplacementDataSet(new FlatXmlDataSet(dataSetStream[i])); + dataSet.addReplacementObject("[null]", null); + dataSets[i] = dataSet; + } + CompositeDataSet compositeDataSet = new CompositeDataSet(dataSets); + + databaseTester.setDataSet(compositeDataSet); + connection = databaseTester.getConnection(); + connection.getConnection().prepareStatement("set referential_integrity FALSE").execute(); // HSQL DB + DatabaseConfig config = connection.getConfig(); + config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new HsqldbDataTypeFactory()); + + DatabaseOperation.CLEAN_INSERT.execute(connection, databaseTester.getDataSet()); + + connection.getConnection().prepareStatement("set referential_integrity TRUE").execute(); // HSQL DB + } catch (Exception e) { + throw translateException("Could not setup DBUnit data", e); + } + } + + protected final void checkTables(String testName, String... tables) { + getSession().commit(); + try { + IDataSet dataSet = getCurrentDataSet(); + IDataSet expectedDataSet = getExpectedData(testName); + for (String table : tables) { + Assertion.assertEquals(expectedDataSet.getTable(table), dataSet.getTable(table)); + } + } catch (DataSetException e) { + throw translateException("Error while checking results", e); + } catch (DatabaseUnitException e) { + fail(e.getMessage()); + } + } + + protected final void assertEmptyTables(String... emptyTables) { + for (String table : emptyTables) { + try { + Assert.assertEquals(0, getCurrentDataSet().getTable(table).getRowCount()); + } catch (DataSetException e) { + throw translateException("Error while checking results", e); + } + } + } + + protected final IDataSet getExpectedData(String testName) { + String className = getClass().getName(); + className = String.format("/%s/%s-result.xml", className.replace(".", "/"), testName); + + InputStream in = getClass().getResourceAsStream(className); + try { + return getData(in); + } finally { + IOUtils.closeQuietly(in); + } + } + + protected final IDataSet getData(InputStream stream) { + try { + ReplacementDataSet dataSet = new ReplacementDataSet(new FlatXmlDataSet(stream)); + dataSet.addReplacementObject("[null]", null); + return dataSet; + } catch (Exception e) { + throw translateException("Could not read the dataset stream", e); + } + } + + protected final IDataSet getCurrentDataSet() { + try { + return connection.createDataSet(); + } catch (SQLException e) { + throw translateException("Could not create the current dataset", e); + } + } + + protected String getCurrentDataSetAsXML() { + return getDataSetAsXML(getCurrentDataSet()); + } + + protected String getDataSetAsXML(IDataSet dataset) { + try { + StringWriter writer = new StringWriter(); + FlatXmlDataSet.write(dataset, writer); + return writer.getBuffer().toString(); + } catch (Exception e) { + throw translateException("Could not build XML from dataset", e); + } + } + + private static RuntimeException translateException(String msg, Exception cause) { + RuntimeException runtimeException = new RuntimeException(String.format("%s: [%s] %s", msg, cause.getClass().getName(), cause.getMessage())); + runtimeException.setStackTrace(cause.getStackTrace()); + return runtimeException; + } + + /*public static class HsqlDataTypeFactory extends DefaultDataTypeFactory { + + public DataType createDataType(int sqlType, String sqlTypeName) throws DataTypeException { + if (sqlType == Types.BOOLEAN) { + return DataType.BOOLEAN; + } + return super.createDataType(sqlType, sqlTypeName); + } + }*/ + + protected Long getHQLCount(final Class<?> hqlClass) { + String hqlCount = "SELECT count(o) from " + hqlClass.getSimpleName() + " o"; + return (Long) getSession().createQuery(hqlCount).getSingleResult(); + } + + protected IDatabaseConnection getConnection() { + return connection; + } + + protected IDatabaseTester getDatabaseTester() { + return databaseTester; + } + +} diff --git a/sonar-core/src/test/resources/logback-test.xml b/sonar-core/src/test/resources/logback-test.xml new file mode 100644 index 00000000000..d42db6a18b6 --- /dev/null +++ b/sonar-core/src/test/resources/logback-test.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<configuration> + + <appender name="STDOUT" + class="ch.qos.logback.core.ConsoleAppender"> + <layout class="ch.qos.logback.classic.PatternLayout"> + <pattern> + %d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n + </pattern> + </layout> + </appender> + + <!-- logger name="org.sonar.DBSTATISTICS"> + <level value="INFO"/> + </logger> +--> + <!--<logger name="org.hibernate.SQL">--> + <!--<level value="INFO"/>--> + <!--</logger>--> + + <root> + <level value="WARN"/> + <appender-ref ref="STDOUT"/> + </root> + +</configuration>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/api/database/configuration/DatabaseConfigurationTest/some-properties.xml b/sonar-core/src/test/resources/org/sonar/api/database/configuration/DatabaseConfigurationTest/some-properties.xml new file mode 100644 index 00000000000..64c38fb55ea --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/api/database/configuration/DatabaseConfigurationTest/some-properties.xml @@ -0,0 +1,6 @@ +<dataset> + + <properties prop_key="key1" resource_id="[null]" text_value="value1" user_id="[null]"/> + <properties prop_key="key2" resource_id="[null]" text_value="value2" user_id="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/api/database/configuration/ResourceDatabaseConfigurationTest/shouldNotLoadGlobalProperties.xml b/sonar-core/src/test/resources/org/sonar/api/database/configuration/ResourceDatabaseConfigurationTest/shouldNotLoadGlobalProperties.xml new file mode 100644 index 00000000000..5e53464e6e4 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/api/database/configuration/ResourceDatabaseConfigurationTest/shouldNotLoadGlobalProperties.xml @@ -0,0 +1,16 @@ +<dataset> + + <projects long_name="[null]" id="100" scope="PRJ" qualifier="TRK" kee="myproject" name="[null]" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- global properties --> + <properties prop_key="key1" resource_id="[null]" text_value="value1" user_id="[null]"/> + <properties prop_key="key2" resource_id="[null]" text_value="value2" user_id="[null]"/> + + <!-- specific properties --> + <properties prop_key="key1" resource_id="100" text_value="project_value1" user_id="[null]"/> + <properties prop_key="key3" resource_id="100" text_value="project_value3" user_id="[null]"/> + + +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/api/database/configuration/ResourceDatabaseConfigurationTest/shouldOverrideGlobalPropertiesBySpecificResourceProperties.xml b/sonar-core/src/test/resources/org/sonar/api/database/configuration/ResourceDatabaseConfigurationTest/shouldOverrideGlobalPropertiesBySpecificResourceProperties.xml new file mode 100644 index 00000000000..3f29bfb26bb --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/api/database/configuration/ResourceDatabaseConfigurationTest/shouldOverrideGlobalPropertiesBySpecificResourceProperties.xml @@ -0,0 +1,16 @@ +<dataset> + + <projects long_name="[null]" id="100" scope="PRJ" qualifier="TRK" kee="myproject" name="[null]" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- global properties --> + <properties prop_key="key1" resource_id="[null]" text_value="value1" user_id="[null]"/> + <properties prop_key="key2" resource_id="[null]" text_value="value2" user_id="[null]"/> + + <!-- specific properties --> + <properties prop_key="key1" resource_id="100" text_value="overriden value1" user_id="[null]"/> + <properties prop_key="key3" resource_id="100" text_value="value3" user_id="[null]"/> + + +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/core/plugin/JpaPluginDaoTest/removePreviousFilesWhenRegisteringPlugin-result.xml b/sonar-core/src/test/resources/org/sonar/core/plugin/JpaPluginDaoTest/removePreviousFilesWhenRegisteringPlugin-result.xml new file mode 100644 index 00000000000..e7f3523119d --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/plugin/JpaPluginDaoTest/removePreviousFilesWhenRegisteringPlugin-result.xml @@ -0,0 +1,6 @@ +<dataset> + <plugins id="1" name="Checkstyle" plugin_key="checkstyle" organization="[null]" organization_url="[null]" license="[null]" homepage="[null]" + description="[null]" installation_date="[null]" plugin_class="[null]" core="true" version="2.2" /> + + <plugin_files id="3" plugin_id="1" filename="newfile.jar"/> +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/core/plugin/JpaPluginDaoTest/saveDeprecatedPlugin-result.xml b/sonar-core/src/test/resources/org/sonar/core/plugin/JpaPluginDaoTest/saveDeprecatedPlugin-result.xml new file mode 100644 index 00000000000..aa6e51ec2cd --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/plugin/JpaPluginDaoTest/saveDeprecatedPlugin-result.xml @@ -0,0 +1,12 @@ +<dataset> + <plugins id="1" name="Checkstyle" plugin_key="checkstyle" organization="[null]" organization_url="[null]" license="[null]" homepage="[null]" + description="[null]" installation_date="[null]" plugin_class="[null]" core="true" version="2.2"/> + + <plugins id="2" name="PMD" plugin_key="pmd" organization="[null]" organization_url="[null]" license="[null]" homepage="[null]" + description="[null]" installation_date="[null]" plugin_class="org.sonar.pmd.Main" core="false" version="[null]" /> + + <plugin_files id="1" plugin_id="1" filename="checkstyle.jar"/> + <plugin_files id="2" plugin_id="1" filename="checkstyle-extension.jar"/> + + <plugin_files id="3" plugin_id="2" filename="sonar-pmd-plugin-2.2.jar"/> +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/core/plugin/JpaPluginDaoTest/savePluginAndFiles-result.xml b/sonar-core/src/test/resources/org/sonar/core/plugin/JpaPluginDaoTest/savePluginAndFiles-result.xml new file mode 100644 index 00000000000..6c215921357 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/plugin/JpaPluginDaoTest/savePluginAndFiles-result.xml @@ -0,0 +1,15 @@ +<dataset> + <plugins id="1" name="Checkstyle" plugin_key="checkstyle" organization="[null]" organization_url="[null]" license="[null]" homepage="[null]" + description="[null]" installation_date="[null]" plugin_class="[null]" core="true" version="2.2"/> + + <plugins id="2" name="PMD" plugin_key="pmd" organization="[null]" organization_url="[null]" license="[null]" homepage="[null]" + description="[null]" installation_date="[null]" plugin_class="org.sonar.pmd.Main" core="false" version="2.2" /> + + <plugin_files id="1" plugin_id="1" filename="checkstyle.jar"/> + <plugin_files id="2" plugin_id="1" filename="checkstyle-extension.jar"/> + + <plugin_files id="3" plugin_id="2" filename="sonar-pmd-plugin-2.2.jar"/> + <plugin_files id="4" plugin_id="2" filename="pmd-extension.jar"/> + <plugin_files id="5" plugin_id="2" filename="pmd-extension2.jar"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/core/plugin/JpaPluginDaoTest/shared.xml b/sonar-core/src/test/resources/org/sonar/core/plugin/JpaPluginDaoTest/shared.xml new file mode 100644 index 00000000000..00861080067 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/plugin/JpaPluginDaoTest/shared.xml @@ -0,0 +1,7 @@ +<dataset> + <plugins id="1" name="Checkstyle" plugin_key="checkstyle" organization="[null]" organization_url="[null]" license="[null]" homepage="[null]" + description="[null]" installation_date="[null]" plugin_class="[null]" core="true" version="2.2" /> + + <plugin_files id="1" plugin_id="1" filename="checkstyle.jar"/> + <plugin_files id="2" plugin_id="1" filename="checkstyle-extension.jar"/> +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/AbstractPurgeTest/purgeSnapshots-result.xml b/sonar-core/src/test/resources/org/sonar/core/purge/AbstractPurgeTest/purgeSnapshots-result.xml new file mode 100644 index 00000000000..3f4962d5509 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/purge/AbstractPurgeTest/purgeSnapshots-result.xml @@ -0,0 +1,111 @@ +<dataset> + <rules_categories id="1" name="category one" description="[null]"/> + <rules id="1" name="foo" rules_category_id="1" plugin_config_key="checker/foo" plugin_rule_key="checkstyle.rule1" + plugin_name="maven-checkstyle-plugin" description="description" cardinality="SINGLE" parent_id="[null]" /> + + <metrics id="1" name="ncloc" val_type="INT" description="[null]" domain="[null]" + short_name="" qualitative="false" user_managed="false" enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <!-- project --> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- package --> + <projects long_name="[null]" id="2" scope="DIR" qualifier="PAC" kee="mygroup:myartifact:my.package" name="package" + root_id="1" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- files --> + <projects long_name="[null]" id="3" scope="FIL" qualifier="CLA" kee="mygroup:myartifact:my.package.Class1" + name="class" root_id="1" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <projects long_name="[null]" id="4" scope="FIL" qualifier="CLA" kee="mygroup:myartifact:my.package.Class2" + name="class" root_id="1" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + + <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="2" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + + <!--<snapshots depth="[null]" id="3" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]"--> + <!--project_id="3"--> + <!--parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false"--> + <!--path="[null]"/>--> + + <!--<snapshots depth="[null]" id="4" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]"--> + <!--project_id="4"--> + <!--parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false"--> + <!--path="[null]"/>--> + + + <SNAPSHOT_SOURCES ID="1" SNAPSHOT_ID="30" DATA="some sources"/> + <!--<SNAPSHOT_SOURCES ID="2" SNAPSHOT_ID="4" DATA="some sources"/>--> + + + <RULE_FAILURES ID="1" SNAPSHOT_ID="1" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg1" LINE="[null]"/> + <RULE_FAILURES ID="2" SNAPSHOT_ID="2" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg2" LINE="[null]"/> + <!--<RULE_FAILURES ID="3" SNAPSHOT_ID="3" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg3" LINE="[null]"/>--> + <!--<RULE_FAILURES ID="4" SNAPSHOT_ID="4" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg4" LINE="[null]"/>--> + + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="1" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="2" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="2" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"--> + <!--rule_priority="[null]"--> + <!--alert_text="[null]" ID="3" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="1"--> + <!--RULE_ID="1"--> + <!--text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"--> + <!--alert_status="[null]" description="[null]"/>--> + + <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"--> + <!--rule_priority="[null]"--> + <!--alert_text="[null]" ID="4" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="4" RULES_CATEGORY_ID="1"--> + <!--RULE_ID="1"--> + <!--text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"--> + <!--alert_status="[null]" description="[null]"/>--> + + + <measure_data id="1" measure_id="1" snapshot_id="1" data="[null]"/> + <measure_data id="2" measure_id="2" snapshot_id="2" data="[null]"/> + <!--<measure_data id="3" measure_id="3" snapshot_id="3" data="[null]"/>--> + <!--<measure_data id="4" measure_id="4" snapshot_id="4" data="[null]"/>--> + + <dependencies id="1" from_resource_id="1" from_snapshot_id="1" to_resource_id="30" to_snapshot_id="30" + parent_dependency_id="[null]" project_snapshot_id="1" + dep_usage="USES" dep_weight="1" from_scope="PRJ" to_scope="LIB"/> + + <!--<dependencies id="2" from_resource_id="3" from_snapshot_id="3" to_resource_id="40" to_snapshot_id="40"--> + <!--parent_dependency_id="[null]" project_snapshot_id="1"--> + <!--dep_usage="INHERITS" dep_weight="1" from_scope="FIL" to_scope="FIL"/>--> + + <!--<dependencies id="3" from_resource_id="50" from_snapshot_id="50" to_resource_id="3" to_snapshot_id="3"--> + <!--parent_dependency_id="[null]" project_snapshot_id="1"--> + <!--dep_usage="INHERITS" dep_weight="1" from_scope="FIL" to_scope="FIL"/>--> + +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/core/purge/AbstractPurgeTest/purgeSnapshots.xml b/sonar-core/src/test/resources/org/sonar/core/purge/AbstractPurgeTest/purgeSnapshots.xml new file mode 100644 index 00000000000..e6bc3164e30 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/purge/AbstractPurgeTest/purgeSnapshots.xml @@ -0,0 +1,111 @@ +<dataset> + <rules_categories id="1" name="category one" description="[null]"/> + <rules id="1" name="foo" rules_category_id="1" plugin_config_key="checker/foo" plugin_rule_key="checkstyle.rule1" + plugin_name="maven-checkstyle-plugin" description="description" cardinality="SINGLE" parent_id="[null]"/> + + <metrics id="1" name="ncloc" val_type="INT" description="[null]" domain="[null]" + short_name="" qualitative="false" user_managed="false" enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <!-- project --> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- package --> + <projects long_name="[null]" id="2" scope="DIR" qualifier="PAC" kee="mygroup:myartifact:my.package" name="package" + root_id="1" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- files --> + <projects long_name="[null]" id="3" scope="FIL" qualifier="CLA" kee="mygroup:myartifact:my.package.Class1" + name="class" root_id="1" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <projects long_name="[null]" id="4" scope="FIL" qualifier="CLA" kee="mygroup:myartifact:my.package.Class2" + name="class" root_id="1" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + + <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="2" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + + <snapshots depth="[null]" id="3" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="4" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + + <SNAPSHOT_SOURCES ID="1" SNAPSHOT_ID="30" DATA="some sources"/> + <SNAPSHOT_SOURCES ID="2" SNAPSHOT_ID="4" DATA="some sources"/> + + + <RULE_FAILURES ID="1" SNAPSHOT_ID="1" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg1" LINE="[null]"/> + <RULE_FAILURES ID="2" SNAPSHOT_ID="2" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg2" LINE="[null]"/> + <RULE_FAILURES ID="3" SNAPSHOT_ID="3" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg3" LINE="[null]"/> + <RULE_FAILURES ID="4" SNAPSHOT_ID="4" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg4" LINE="[null]"/> + + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="1" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="2" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="2" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="3" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="4" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="4" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + + <measure_data id="1" measure_id="1" snapshot_id="1" data="[null]"/> + <measure_data id="2" measure_id="2" snapshot_id="2" data="[null]"/> + <measure_data id="3" measure_id="3" snapshot_id="3" data="[null]"/> + <measure_data id="4" measure_id="4" snapshot_id="4" data="[null]"/> + + <dependencies id="1" from_resource_id="1" from_snapshot_id="1" to_resource_id="30" to_snapshot_id="30" + parent_dependency_id="[null]" project_snapshot_id="1" + dep_usage="USES" dep_weight="1" from_scope="PRJ" to_scope="LIB"/> + + <dependencies id="2" from_resource_id="3" from_snapshot_id="3" to_resource_id="40" to_snapshot_id="40" + parent_dependency_id="[null]" project_snapshot_id="1" + dep_usage="INHERITS" dep_weight="1" from_scope="FIL" to_scope="FIL"/> + + <dependencies id="3" from_resource_id="50" from_snapshot_id="50" to_resource_id="3" to_snapshot_id="3" + parent_dependency_id="[null]" project_snapshot_id="1" + dep_usage="INHERITS" dep_weight="1" from_scope="FIL" to_scope="FIL" /> + +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/core/qualitymodel/DefaultModelProviderTest/noDefinitionsToRegister-result.xml b/sonar-core/src/test/resources/org/sonar/core/qualitymodel/DefaultModelProviderTest/noDefinitionsToRegister-result.xml new file mode 100644 index 00000000000..7635d06bd99 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/qualitymodel/DefaultModelProviderTest/noDefinitionsToRegister-result.xml @@ -0,0 +1,10 @@ +<dataset> + <quality_models id="1" name="M1" /> + <quality_models id="2" name="M2" /> + + <characteristics id="1" kee="M1C1" name="M1C1" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="1" /> + <characteristics id="2" kee="M1C2" name="M1C2" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="2" /> + <characteristics id="3" kee="M2C1" name="M2C1" quality_model_id="2" rule_id="[null]" characteristic_order="1" depth="1"/> + + <characteristic_edges child_id="2" parent_id="1"/> +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/core/qualitymodel/DefaultModelProviderTest/registerOnlyNewDefinitions-result.xml b/sonar-core/src/test/resources/org/sonar/core/qualitymodel/DefaultModelProviderTest/registerOnlyNewDefinitions-result.xml new file mode 100644 index 00000000000..0477a531971 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/qualitymodel/DefaultModelProviderTest/registerOnlyNewDefinitions-result.xml @@ -0,0 +1,13 @@ +<dataset> + <quality_models id="1" name="M1" /> + <quality_models id="2" name="M2" /> + + <!-- NEW MODEL --> + <quality_models id="3" name="NEWMODEL" /> + + <characteristics id="1" kee="M1C1" name="M1C1" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="1" /> + <characteristics id="2" kee="M1C2" name="M1C2" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="2" /> + <characteristics id="3" kee="M2C1" name="M2C1" quality_model_id="2" rule_id="[null]" characteristic_order="1" depth="1"/> + + <characteristic_edges child_id="2" parent_id="1"/> +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/core/qualitymodel/DefaultModelProviderTest/reset-result.xml b/sonar-core/src/test/resources/org/sonar/core/qualitymodel/DefaultModelProviderTest/reset-result.xml new file mode 100644 index 00000000000..91c5773b8ff --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/qualitymodel/DefaultModelProviderTest/reset-result.xml @@ -0,0 +1,15 @@ +<dataset> + <!--<quality_models id="1" name="M1" />--> + <quality_models id="2" name="M2" /> + <quality_models id="3" name="M1" /> + + <!--<characteristics id="1" kee="M1C1" name="M1C1" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="1" />--> + <!--<characteristics id="2" kee="M1C2" name="M1C2" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="2" />--> + <characteristics id="3" kee="M2C1" name="M2C1" quality_model_id="2" rule_id="[null]" characteristic_order="1" depth="1" /> + <characteristics id="4" kee="NEWM1C1A" name="NEWM1C1A" quality_model_id="3" rule_id="[null]" characteristic_order="1" depth="2"/> + <characteristics id="5" kee="NEWM1C1" name="NEWM1C1" quality_model_id="3" rule_id="[null]" characteristic_order="1" depth="1"/> + <characteristics id="6" kee="NEWM1C2" name="NEWM1C2" quality_model_id="3" rule_id="[null]" characteristic_order="2" depth="1"/> + + <!--<characteristic_edges child_id="2" parent_id="1"/>--> + <characteristic_edges child_id="4" parent_id="5"/> +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/core/qualitymodel/DefaultModelProviderTest/shared.xml b/sonar-core/src/test/resources/org/sonar/core/qualitymodel/DefaultModelProviderTest/shared.xml new file mode 100644 index 00000000000..7635d06bd99 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/qualitymodel/DefaultModelProviderTest/shared.xml @@ -0,0 +1,10 @@ +<dataset> + <quality_models id="1" name="M1" /> + <quality_models id="2" name="M2" /> + + <characteristics id="1" kee="M1C1" name="M1C1" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="1" /> + <characteristics id="2" kee="M1C2" name="M1C2" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="2" /> + <characteristics id="3" kee="M2C1" name="M2C1" quality_model_id="2" rule_id="[null]" characteristic_order="1" depth="1"/> + + <characteristic_edges child_id="2" parent_id="1"/> +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/core/qualitymodel/ModelTest/saveModelAndCharacteristics.xml b/sonar-core/src/test/resources/org/sonar/core/qualitymodel/ModelTest/saveModelAndCharacteristics.xml new file mode 100644 index 00000000000..693d4448b8d --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/qualitymodel/ModelTest/saveModelAndCharacteristics.xml @@ -0,0 +1,4 @@ +<dataset> + <quality_models id="1" name="initial" /> + <characteristics id="1" kee="FAKE" name="fake" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="1" /> +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/core/qualitymodel/ModelTest/testGraphOfCharacteristics.xml b/sonar-core/src/test/resources/org/sonar/core/qualitymodel/ModelTest/testGraphOfCharacteristics.xml new file mode 100644 index 00000000000..70a69a6a1ba --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/qualitymodel/ModelTest/testGraphOfCharacteristics.xml @@ -0,0 +1,8 @@ +<dataset> + <quality_models id="1" name="initial" /> + + <characteristics id="1" kee="FAKE1" name="fake1" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="1"/> + <characteristics id="2" kee="FAKE2" name="fake2" quality_model_id="1" rule_id="[null]" characteristic_order="2" depth="1" /> + + <characteristic_edges child_id="2" parent_id="1"/> +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/core/qualitymodel/ModelTest/testTreeOfCharacteristics.xml b/sonar-core/src/test/resources/org/sonar/core/qualitymodel/ModelTest/testTreeOfCharacteristics.xml new file mode 100644 index 00000000000..6dcd2a78d63 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/qualitymodel/ModelTest/testTreeOfCharacteristics.xml @@ -0,0 +1,5 @@ +<dataset> + <quality_models id="1" name="initial" /> + <characteristics id="1" kee="FAKE" name="fake" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="1" /> + <characteristic_edges child_id="1" parent_id="1"/> +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/core/rule/DefaultRuleProviderTest/shared.xml b/sonar-core/src/test/resources/org/sonar/core/rule/DefaultRuleProviderTest/shared.xml new file mode 100644 index 00000000000..f6adafee0da --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/rule/DefaultRuleProviderTest/shared.xml @@ -0,0 +1,20 @@ +<dataset> + <rules_categories id="6" name="Efficiency" description="[null]" /> + + <!-- CHECKSTYLE --> + + <rules id="1" name="Check Header" rules_category_id="6" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck" + plugin_config_key="Checker/Treewalker/HeaderCheck" plugin_name="checkstyle" description="[null]" priority="4" enabled="true" cardinality="SINGLE" parent_id="[null]"/> + + <!-- disabled rule --> + <rules id="2" name="Disabled checked" rules_category_id="6" plugin_rule_key="DisabledCheck" + plugin_config_key="Checker/Treewalker/DisabledCheck" plugin_name="checkstyle" description="[null]" priority="4" enabled="false" cardinality="SINGLE" parent_id="[null]" /> + + <rules id="3" name="Check Annotation" rules_category_id="6" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck" + plugin_config_key="Checker/Treewalker/AnnotationUseStyleCheck" plugin_name="checkstyle" description="[null]" priority="4" enabled="true" cardinality="SINGLE" parent_id="[null]" /> + + + <!-- PMD --> + <rules id="4" name="Call Super First" rules_category_id="6" plugin_rule_key="CallSuperFirst" + plugin_config_key="rulesets/android.xml/CallSuperFirst" plugin_name="pmd" description="[null]" priority="2" enabled="true" cardinality="SINGLE" parent_id="[null]" /> +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/sharedFixture.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/sharedFixture.xml new file mode 100644 index 00000000000..4fbd9f7d094 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/sharedFixture.xml @@ -0,0 +1,23 @@ +<dataset>
+
+ <metrics id="1" name="foo" val_type="INT" description="[null]" domain="[null]"
+ short_name="" qualitative="false" user_managed="false"
+ enabled="false" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/>
+ <metrics id="2" name="bar" val_type="INT" description="[null]" domain="[null]"
+ short_name="" qualitative="false" user_managed="false"
+ enabled="false" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/>
+ <metrics id="3" name="boo" val_type="INT" description="[null]" domain="[null]"
+ short_name="" qualitative="false" user_managed="false"
+ enabled="false" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/>
+
+ <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="[null]"
+ root_id="[null]"
+ description="[null]"
+ enabled="true" language="java" copy_resource_id="[null]"/>
+
+ <projects long_name="[null]" id="2" scope="PRJ" qualifier="TRK" kee="mygroup2:myartifact" name="[null]"
+ root_id="[null]"
+ description="[null]"
+ enabled="true" language="java" copy_resource_id="[null]"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testDeleteAsyncMeasure-result.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testDeleteAsyncMeasure-result.xml new file mode 100644 index 00000000000..4af92259aaa --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testDeleteAsyncMeasure-result.xml @@ -0,0 +1,22 @@ +<dataset>
+
+ <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" rule_priority="[null]" alert_text="[null]" id="1" project_id="1" metric_id="1" value="1" measure_date="2008-12-03 08:00:00.00" rule_id="[null]"-->
+ <!--snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>-->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="5"
+ measure_date="2008-12-06 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"
+ alert_status="[null]" description="[null]"/>
+
+
+ <!--<async_measure_snapshots id="1" project_measure_id="1" snapshot_id="1" measure_date="2008-12-03 08:00:00.00"-->
+ <!--snapshot_date="2008-12-03 12:00:00.00" metric_id="1" project_id="1"/>-->
+ <!--<async_measure_snapshots id="2" project_measure_id="1" snapshot_id="2" measure_date="2008-12-03 08:00:00.00"-->
+ <!--snapshot_date="2008-12-04 12:00:00.00" metric_id="1" project_id="1"/>-->
+ <!--<async_measure_snapshots id="3" project_measure_id="1" snapshot_id="3" measure_date="2008-12-03 08:00:00.00"-->
+ <!--snapshot_date="2008-12-05 12:00:00.00" metric_id="1" project_id="1"/>-->
+ <async_measure_snapshots id="4" project_measure_id="2" snapshot_id="4" measure_date="2008-12-06 08:00:00.00"
+ snapshot_date="2008-12-06 12:00:00.00" metric_id="1" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testDeleteAsyncMeasure.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testDeleteAsyncMeasure.xml new file mode 100644 index 00000000000..f48a0da88bc --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testDeleteAsyncMeasure.xml @@ -0,0 +1,26 @@ +<dataset>
+
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="1"
+ measure_date="2008-12-03 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"
+ alert_status="[null]" description="[null]"/>
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="5"
+ measure_date="2008-12-06 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"
+ alert_status="[null]" description="[null]"/>
+
+
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="1" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="2" project_measure_id="1" snapshot_id="2" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="3" project_measure_id="1" snapshot_id="3" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="2008-12-05 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="4" project_measure_id="2" snapshot_id="4" measure_date="2008-12-06 08:00:00.00"
+ snapshot_date="2008-12-06 12:00:00.00" metric_id="1" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testDeleteAsyncMeasureSnapshots-result.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testDeleteAsyncMeasureSnapshots-result.xml new file mode 100644 index 00000000000..ae9389c25b2 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testDeleteAsyncMeasureSnapshots-result.xml @@ -0,0 +1,11 @@ +<dataset>
+
+ <!--<async_measure_snapshots id="1" project_measure_id="1" snapshot_id="[null]" measure_date="2008-12-03 08:00:00.00"-->
+ <!--snapshot_date="[null]" metric_id="1" project_id="1"/>-->
+ <!--<async_measure_snapshots id="2" project_measure_id="1" snapshot_id="2" measure_date="2008-12-03 08:00:00.00"-->
+ <!--snapshot_date="[null]" metric_id="1" project_id="1"/>-->
+ <!--<async_measure_snapshots id="3" project_measure_id="1" snapshot_id="[null]" measure_date="2008-12-03 08:00:00.00"-->
+ <!--snapshot_date="[null]" metric_id="1" project_id="1"/>-->
+ <async_measure_snapshots id="4" project_measure_id="2" snapshot_id="[null]" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="[null]" metric_id="2" project_id="1"/>
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testDeleteAsyncMeasureSnapshots.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testDeleteAsyncMeasureSnapshots.xml new file mode 100644 index 00000000000..55b7e7ecc0f --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testDeleteAsyncMeasureSnapshots.xml @@ -0,0 +1,11 @@ +<dataset>
+
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="[null]" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="[null]" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="2" project_measure_id="1" snapshot_id="2" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="[null]" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="3" project_measure_id="1" snapshot_id="[null]" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="[null]" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="4" project_measure_id="2" snapshot_id="[null]" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="[null]" metric_id="2" project_id="1"/>
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testGetAsyncMeasureSnapshotsFromSnapshotId.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testGetAsyncMeasureSnapshotsFromSnapshotId.xml new file mode 100644 index 00000000000..75fdf0a8bcb --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testGetAsyncMeasureSnapshotsFromSnapshotId.xml @@ -0,0 +1,26 @@ +<dataset>
+
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="1"
+ measure_date="2008-12-03 18:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"
+ description="[null]"/>
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="2" value="2"
+ measure_date="2008-12-04 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"
+ description="[null]"/>
+
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="1" measure_date="2008-12-03 18:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="2" project_measure_id="2" snapshot_id="1" measure_date="2008-12-04 08:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="2" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testGetLastAsyncMeasureSnapshot.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testGetLastAsyncMeasureSnapshot.xml new file mode 100644 index 00000000000..7adc403b439 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testGetLastAsyncMeasureSnapshot.xml @@ -0,0 +1,12 @@ +<dataset>
+
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="1" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="2" project_measure_id="1" snapshot_id="2" measure_date="2008-12-04 08:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="3" project_measure_id="1" snapshot_id="3" measure_date="2008-12-05 08:00:00.00"
+ snapshot_date="2008-12-05 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="4" project_measure_id="2" snapshot_id="4" measure_date="2008-12-06 08:00:00.00"
+ snapshot_date="2008-12-06 12:00:00.00" metric_id="1" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testGetNextAsyncMeasureSnapshot.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testGetNextAsyncMeasureSnapshot.xml new file mode 100644 index 00000000000..705cebd5ef7 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testGetNextAsyncMeasureSnapshot.xml @@ -0,0 +1,11 @@ +<dataset>
+
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="1" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="2" project_measure_id="1" snapshot_id="2" measure_date="2008-12-04 08:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="3" project_measure_id="1" snapshot_id="3" measure_date="2008-12-05 08:00:00.00"
+ snapshot_date="2008-12-05 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="4" project_measure_id="2" snapshot_id="4" measure_date="2008-12-06 08:00:00.00"
+ snapshot_date="2008-12-06 12:00:00.00" metric_id="1" project_id="1"/>
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testGetNextAsyncMeasureSnapshotsUntilDate.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testGetNextAsyncMeasureSnapshotsUntilDate.xml new file mode 100644 index 00000000000..a7f814154d8 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testGetNextAsyncMeasureSnapshotsUntilDate.xml @@ -0,0 +1,50 @@ +<dataset>
+
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="2" scope="PRJ" qualifier="TRK" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="3" scope="PRJ" qualifier="TRK" created_at="2008-12-05 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="4" scope="PRJ" qualifier="TRK" created_at="2008-12-06 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="1"
+ measure_date="2008-12-03 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"
+ description="[null]"/>
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="5"
+ measure_date="2008-12-06 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"
+ description="[null]"/>
+ <!-- measure inserted on snapshot 2 -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="3" project_id="1" metric_id="1" value="2"
+ measure_date="2008-12-04 12:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"
+ description="[null]"/>
+
+
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="1" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="2" project_measure_id="1" snapshot_id="2" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="3" project_measure_id="1" snapshot_id="3" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="2008-12-05 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="4" project_measure_id="2" snapshot_id="4" measure_date="2008-12-06 08:00:00.00"
+ snapshot_date="2008-12-06 12:00:00.00" metric_id="1" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testGetNextSnapshotsUntilDate.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testGetNextSnapshotsUntilDate.xml new file mode 100644 index 00000000000..bbd2c20759f --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testGetNextSnapshotsUntilDate.xml @@ -0,0 +1,35 @@ +<dataset>
+
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="2" scope="PRJ" qualifier="TRK" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="3" scope="FIL" qualifier="CLA" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="3" root_project_id="[null]" root_snapshot_id="3" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="4" scope="PRJ" qualifier="TRK" created_at="2008-12-05 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="5" scope="FIL" qualifier="CLA" created_at="2008-12-05 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="4" root_project_id="[null]" root_snapshot_id="4" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="6" scope="PRJ" qualifier="TRK" created_at="2008-12-06 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="1"
+ measure_date="2008-12-04 12:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"
+ description="[null]"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testGetPreviousAsyncMeasureSnapshots.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testGetPreviousAsyncMeasureSnapshots.xml new file mode 100644 index 00000000000..b5a5b9dc96d --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testGetPreviousAsyncMeasureSnapshots.xml @@ -0,0 +1,18 @@ +<dataset>
+
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="1" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="2" project_id="1"/>
+ <async_measure_snapshots id="2" project_measure_id="2" snapshot_id="2" measure_date="2008-12-04 08:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="2" project_id="1"/>
+ <async_measure_snapshots id="3" project_measure_id="3" snapshot_id="3" measure_date="2008-12-05 08:00:00.00"
+ snapshot_date="2008-12-05 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="4" project_measure_id="4" snapshot_id="4" measure_date="2008-12-06 08:00:00.00"
+ snapshot_date="2008-12-06 12:00:00.00" metric_id="1" project_id="1"/>
+
+ <async_measure_snapshots id="5" project_measure_id="5" snapshot_id="[null]" measure_date="2008-12-07 08:00:00.00"
+ snapshot_date="[null]" metric_id="2" project_id="1"/>
+ <async_measure_snapshots id="6" project_measure_id="6" snapshot_id="[null]" measure_date="2008-12-08 08:00:00.00"
+ snapshot_date="[null]" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="7" project_measure_id="7" snapshot_id="[null]" measure_date="2008-12-09 08:00:00.00"
+ snapshot_date="[null]" metric_id="1" project_id="1"/>
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testGetPreviousSnapshot.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testGetPreviousSnapshot.xml new file mode 100644 index 00000000000..21fa947d845 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresDaoTest/testGetPreviousSnapshot.xml @@ -0,0 +1,24 @@ +<dataset>
+
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="2" scope="DIR" qualifier="PAC" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="1" root_project_id="[null]" root_snapshot_id="1" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="3" scope="PRJ" qualifier="TRK" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="4" scope="PRJ" qualifier="TRK" created_at="2008-12-05 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="5" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="2"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/addFutureSnapshot-result.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/addFutureSnapshot-result.xml new file mode 100644 index 00000000000..2f9fd27ff54 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/addFutureSnapshot-result.xml @@ -0,0 +1,28 @@ +<dataset>
+
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <!-- Assigned to first sanspshot -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="1"
+ measure_date="2008-12-02 12:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <!-- New measure, after last snapshot -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="5"
+ measure_date="2008-12-04 12:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="1" measure_date="2008-12-02 12:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="1" project_id="1"/>
+
+ <!-- No snapshot attached -->
+ <async_measure_snapshots id="2" project_measure_id="2" snapshot_id="[null]" measure_date="2008-12-04 12:00:00.00"
+ snapshot_date="[null]" metric_id="1" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/addFutureSnapshot.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/addFutureSnapshot.xml new file mode 100644 index 00000000000..a89dcda8aa6 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/addFutureSnapshot.xml @@ -0,0 +1,24 @@ +<dataset>
+
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <!-- Assigned to first sanspshot -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="1"
+ measure_date="2008-12-02 12:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <!-- New measure, after last snapshot -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="5"
+ measure_date="2008-12-04 12:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="1" measure_date="2008-12-02 12:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="1" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/addInvisibleMeasure-result.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/addInvisibleMeasure-result.xml new file mode 100644 index 00000000000..758305c84ed --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/addInvisibleMeasure-result.xml @@ -0,0 +1,28 @@ +<dataset>
+
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <!-- Assigned to first sanspshot -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="1"
+ measure_date="2008-12-02 12:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <!-- New measure, just before first measure -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="50"
+ measure_date="2008-12-02 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="1" measure_date="2008-12-02 12:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="1" project_id="1"/>
+
+ <!-- No snapshot attached -->
+ <async_measure_snapshots id="2" project_measure_id="2" snapshot_id="[null]" measure_date="2008-12-02 08:00:00.00"
+ snapshot_date="[null]" metric_id="1" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/addInvisibleMeasure.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/addInvisibleMeasure.xml new file mode 100644 index 00000000000..9cb2a52dc62 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/addInvisibleMeasure.xml @@ -0,0 +1,24 @@ +<dataset>
+
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <!-- Assigned to first sanspshot -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="1"
+ measure_date="2008-12-02 12:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <!-- New measure, just before first measure -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="50"
+ measure_date="2008-12-02 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="1" measure_date="2008-12-02 12:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="1" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignAPastMeasureToNextSnapshotsWithDifferentMetric-result.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignAPastMeasureToNextSnapshotsWithDifferentMetric-result.xml new file mode 100644 index 00000000000..a56e5efb96b --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignAPastMeasureToNextSnapshotsWithDifferentMetric-result.xml @@ -0,0 +1,37 @@ +<dataset>
+
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="2" scope="PRJ" qualifier="TRK" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="3" scope="PRJ" qualifier="TRK" created_at="2008-12-05 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <!-- Assigned to snapshot 3 -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="1"
+ measure_date="2008-12-05 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <!-- Past measure inserted, have to be assigned only to snapshot 1 and 2 -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="8"
+ measure_date="2008-12-03 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="3" measure_date="2008-12-05 08:00:00.00"
+ snapshot_date="2008-12-05 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="2" project_measure_id="2" snapshot_id="1" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="3" project_measure_id="2" snapshot_id="2" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="1" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignAPastMeasureToNextSnapshotsWithDifferentMetric.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignAPastMeasureToNextSnapshotsWithDifferentMetric.xml new file mode 100644 index 00000000000..6b1e191cddd --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignAPastMeasureToNextSnapshotsWithDifferentMetric.xml @@ -0,0 +1,33 @@ +<dataset>
+
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="2" scope="PRJ" qualifier="TRK" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="3" scope="PRJ" qualifier="TRK" created_at="2008-12-05 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <!-- Assigned to snapshot 3 -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="1"
+ measure_date="2008-12-05 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <!-- Past measure inserted, have to be assigned only to snapshot 1 and 2 -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="8"
+ measure_date="2008-12-03 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="3" measure_date="2008-12-05 08:00:00.00"
+ snapshot_date="2008-12-05 12:00:00.00" metric_id="1" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignLatestMeasuresToLastSnapshot-result.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignLatestMeasuresToLastSnapshot-result.xml new file mode 100644 index 00000000000..6e32c3a4b49 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignLatestMeasuresToLastSnapshot-result.xml @@ -0,0 +1,42 @@ +<dataset>
+
+ <!-- Previous snapshot -->
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <!-- New snapshot -->
+ <snapshots depth="[null]" id="2" scope="PRJ" qualifier="TRK" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="1"
+ measure_date="2008-12-02 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="2"
+ measure_date="2008-12-02 10:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="3" project_id="1" metric_id="2" value="5"
+ measure_date="2008-12-03 10:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+ <!-- Previous async_measure_snapshots, attached to first snapshot -->
+ <async_measure_snapshots id="1" project_measure_id="2" snapshot_id="1" measure_date="2008-12-02 10:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="2" project_measure_id="3" snapshot_id="1" measure_date="2008-12-03 10:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="2" project_id="1"/>
+
+ <!--async_measure_snapshots from previous snapshot created for last snapshot -->
+ <async_measure_snapshots id="3" project_measure_id="2" snapshot_id="2" measure_date="2008-12-02 10:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="4" project_measure_id="3" snapshot_id="2" measure_date="2008-12-03 10:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="2" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignLatestMeasuresToLastSnapshot.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignLatestMeasuresToLastSnapshot.xml new file mode 100644 index 00000000000..b9d192b0f8c --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignLatestMeasuresToLastSnapshot.xml @@ -0,0 +1,36 @@ +<dataset>
+
+ <!-- Previous snapshot -->
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <!-- New snapshot -->
+ <snapshots depth="[null]" id="2" scope="PRJ" qualifier="TRK" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="1"
+ measure_date="2008-12-02 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="2"
+ measure_date="2008-12-02 10:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="3" project_id="1" metric_id="2" value="5"
+ measure_date="2008-12-03 10:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+ <!-- Previous async_measure_snapshots, attached to first snapshot -->
+ <async_measure_snapshots id="1" project_measure_id="2" snapshot_id="1" measure_date="2008-12-02 10:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="2" project_measure_id="3" snapshot_id="1" measure_date="2008-12-03 10:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="2" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignLatestMeasuresWhenNoPreviousSnapshot-result.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignLatestMeasuresWhenNoPreviousSnapshot-result.xml new file mode 100644 index 00000000000..311388ad4d9 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignLatestMeasuresWhenNoPreviousSnapshot-result.xml @@ -0,0 +1,45 @@ +<dataset>
+
+ <!-- new snapshot -->
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="2"
+ measure_date="2008-12-02 12:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <!--latest-->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="5"
+ measure_date="2008-12-03 12:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="3" project_id="1" metric_id="2" value="6"
+ measure_date="2008-12-02 12:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <!--latest-->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="4" project_id="1" metric_id="2" value="7"
+ measure_date="2008-12-03 12:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="[null]" measure_date="2008-12-02 12:00:00.00"
+ snapshot_date="[null]" metric_id="1" project_id="1"/>
+ <!-- attached -->
+ <async_measure_snapshots id="2" project_measure_id="2" snapshot_id="1" measure_date="2008-12-03 12:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="3" project_measure_id="3" snapshot_id="[null]" measure_date="2008-12-02 12:00:00.00"
+ snapshot_date="[null]" metric_id="2" project_id="1"/>
+ <!-- attached -->
+ <async_measure_snapshots id="4" project_measure_id="4" snapshot_id="1" measure_date="2008-12-03 12:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="2" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignLatestMeasuresWhenNoPreviousSnapshot.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignLatestMeasuresWhenNoPreviousSnapshot.xml new file mode 100644 index 00000000000..6d721271a79 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignLatestMeasuresWhenNoPreviousSnapshot.xml @@ -0,0 +1,43 @@ +<dataset>
+
+ <!-- new snapshot -->
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="2"
+ measure_date="2008-12-02 12:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <!--latest-->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="5"
+ measure_date="2008-12-03 12:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="3" project_id="1" metric_id="2" value="6"
+ measure_date="2008-12-02 12:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <!--latest-->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="4" project_id="1" metric_id="2" value="7"
+ measure_date="2008-12-03 12:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="[null]" measure_date="2008-12-02 12:00:00.00"
+ snapshot_date="[null]" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="2" project_measure_id="2" snapshot_id="[null]" measure_date="2008-12-03 12:00:00.00"
+ snapshot_date="[null]" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="3" project_measure_id="3" snapshot_id="[null]" measure_date="2008-12-02 12:00:00.00"
+ snapshot_date="[null]" metric_id="2" project_id="1"/>
+ <async_measure_snapshots id="4" project_measure_id="4" snapshot_id="[null]" measure_date="2008-12-03 12:00:00.00"
+ snapshot_date="[null]" metric_id="2" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignMeasureToFutureSnapshotsWithDifferentMetric-result.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignMeasureToFutureSnapshotsWithDifferentMetric-result.xml new file mode 100644 index 00000000000..c6c5e2df71f --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignMeasureToFutureSnapshotsWithDifferentMetric-result.xml @@ -0,0 +1,59 @@ +<dataset>
+
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="2" scope="PRJ" qualifier="TRK" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="3" scope="PRJ" qualifier="TRK" created_at="2008-12-05 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="4" scope="PRJ" qualifier="TRK" created_at="2008-12-06 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <!-- Assigned to snapshot 1, 2 and 3 -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="1"
+ measure_date="2008-12-03 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <!-- Assigned to snapshot 4 -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="8"
+ measure_date="2008-12-06 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <!-- To be assigned only to snapshot 2 and 3 -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="3" project_id="1" metric_id="1" value="8"
+ measure_date="2008-12-04 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="1" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="1" project_id="1"/>
+ <!-- Now assigned to no snapshot -->
+ <async_measure_snapshots id="2" project_measure_id="1" snapshot_id="[null]" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="[null]" metric_id="1" project_id="1"/>
+ <!-- Now assigned to no snapshot -->
+ <async_measure_snapshots id="3" project_measure_id="1" snapshot_id="[null]" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="[null]" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="4" project_measure_id="2" snapshot_id="4" measure_date="2008-12-06 08:00:00.00"
+ snapshot_date="2008-12-06 12:00:00.00" metric_id="1" project_id="1"/>
+
+ <!-- Now assigned to review 3 -->
+ <async_measure_snapshots id="5" project_measure_id="3" snapshot_id="2" measure_date="2008-12-04 08:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="1" project_id="1"/>
+ <!-- Now assigned to review 3 -->
+ <async_measure_snapshots id="6" project_measure_id="3" snapshot_id="3" measure_date="2008-12-04 08:00:00.00"
+ snapshot_date="2008-12-05 12:00:00.00" metric_id="1" project_id="1"/>
+
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignMeasureToFutureSnapshotsWithDifferentMetric.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignMeasureToFutureSnapshotsWithDifferentMetric.xml new file mode 100644 index 00000000000..a883add73f4 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignMeasureToFutureSnapshotsWithDifferentMetric.xml @@ -0,0 +1,49 @@ +<dataset>
+
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="2" scope="PRJ" qualifier="TRK" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="3" scope="PRJ" qualifier="TRK" created_at="2008-12-05 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="4" scope="PRJ" qualifier="TRK" created_at="2008-12-06 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <!-- Assigned to snapshot 1, 2 and 3 -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="1"
+ measure_date="2008-12-03 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <!-- Assigned to snapshot 4 -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="8"
+ measure_date="2008-12-06 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <!-- To be assigned only to snapshot 2 and 3 -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="3" project_id="1" metric_id="1" value="8"
+ measure_date="2008-12-04 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="1" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="2" project_measure_id="1" snapshot_id="2" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="3" project_measure_id="1" snapshot_id="3" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="2008-12-05 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="4" project_measure_id="2" snapshot_id="4" measure_date="2008-12-06 08:00:00.00"
+ snapshot_date="2008-12-06 12:00:00.00" metric_id="1" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignMeasuresWhenNoPreviousSnapshot-result.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignMeasuresWhenNoPreviousSnapshot-result.xml new file mode 100644 index 00000000000..70469bf5308 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignMeasuresWhenNoPreviousSnapshot-result.xml @@ -0,0 +1,24 @@ +<dataset>
+
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="2"
+ measure_date="2008-12-03 14:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="2" value="5"
+ measure_date="2008-12-03 15:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="1" measure_date="2008-12-03 14:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="2" project_measure_id="2" snapshot_id="1" measure_date="2008-12-03 15:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="2" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignMeasuresWhenNoPreviousSnapshot.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignMeasuresWhenNoPreviousSnapshot.xml new file mode 100644 index 00000000000..a5aeb9f7731 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignMeasuresWhenNoPreviousSnapshot.xml @@ -0,0 +1,24 @@ +<dataset>
+
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="2"
+ measure_date="2008-12-03 14:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="2" value="5"
+ measure_date="2008-12-03 15:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="[null]" measure_date="2008-12-03 14:00:00.00"
+ snapshot_date="[null]" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="2" project_measure_id="2" snapshot_id="[null]" measure_date="2008-12-03 15:00:00.00"
+ snapshot_date="[null]" metric_id="2" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignNewMeasureToFutureSnapshots-result.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignNewMeasureToFutureSnapshots-result.xml new file mode 100644 index 00000000000..98a68c44271 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignNewMeasureToFutureSnapshots-result.xml @@ -0,0 +1,44 @@ +<dataset>
+
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="2" scope="PRJ" qualifier="TRK" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="3" scope="PRJ" qualifier="TRK" created_at="2008-12-05 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="10"
+ measure_date="2008-12-03 8:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <!-- New measure -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="8"
+ measure_date="2008-12-04 8:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="1" measure_date="2008-12-03 8:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="1" project_id="1"/>
+
+ <!-- Now assigned to no snapshot -->
+ <async_measure_snapshots id="2" project_measure_id="2" snapshot_id="[null]" measure_date="2008-12-03 8:00:00.00"
+ snapshot_date="[null]" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="3" project_measure_id="3" snapshot_id="[null]" measure_date="2008-12-03 8:00:00.00"
+ snapshot_date="[null]" metric_id="1" project_id="1"/>
+
+ <!-- Now assigned to snapshot 2 and 3 -->
+ <async_measure_snapshots id="4" project_measure_id="2" snapshot_id="2" measure_date="2008-12-04 8:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="5" project_measure_id="2" snapshot_id="3" measure_date="2008-12-04 8:00:00.00"
+ snapshot_date="2008-12-05 12:00:00.00" metric_id="1" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignNewMeasureToFutureSnapshots.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignNewMeasureToFutureSnapshots.xml new file mode 100644 index 00000000000..1fc5a2d0295 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignNewMeasureToFutureSnapshots.xml @@ -0,0 +1,36 @@ +<dataset>
+
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="2" scope="PRJ" qualifier="TRK" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="3" scope="PRJ" qualifier="TRK" created_at="2008-12-05 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="10"
+ measure_date="2008-12-03 8:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <!-- New measure -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="8"
+ measure_date="2008-12-04 8:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="1" measure_date="2008-12-03 8:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="2" project_measure_id="2" snapshot_id="2" measure_date="2008-12-03 8:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="3" project_measure_id="3" snapshot_id="3" measure_date="2008-12-03 8:00:00.00"
+ snapshot_date="2008-12-05 12:00:00.00" metric_id="1" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignNewMeasuresToLastSnapshot-result.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignNewMeasuresToLastSnapshot-result.xml new file mode 100644 index 00000000000..87a13cbde66 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignNewMeasuresToLastSnapshot-result.xml @@ -0,0 +1,43 @@ +<dataset>
+
+ <!-- Previous snapshot -->
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <!-- New snapshot -->
+ <snapshots depth="[null]" id="2" scope="PRJ" qualifier="TRK" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <!-- Assigned to first sanspshot -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="1"
+ measure_date="2008-12-02 12:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+ <!-- Assigmed to no snapshot, because its new reviews -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="2"
+ measure_date="2008-12-03 18:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="3" project_id="1" metric_id="2" value="5"
+ measure_date="2008-12-04 10:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+ <!-- async_measure_snapshots attached to first snapshot -->
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="1" measure_date="2008-12-02 12:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="1" project_id="1"/>
+
+ <!-- async_measure_snapshots now attached to last snapshot -->
+ <async_measure_snapshots id="2" project_measure_id="2" snapshot_id="2" measure_date="2008-12-03 18:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="3" project_measure_id="3" snapshot_id="2" measure_date="2008-12-04 10:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="2" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignNewMeasuresToLastSnapshot.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignNewMeasuresToLastSnapshot.xml new file mode 100644 index 00000000000..4bbfcb29c27 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignNewMeasuresToLastSnapshot.xml @@ -0,0 +1,42 @@ +<dataset>
+
+ <!-- Previous snapshot -->
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <!-- New snapshot -->
+ <snapshots depth="[null]" id="2" scope="PRJ" qualifier="TRK" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"/>
+
+ <!-- Assigned to first sanspshot -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="1"
+ measure_date="2008-12-02 12:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+ <!-- Assigmed to no snapshot, because its new reviews -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="2"
+ measure_date="2008-12-03 18:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="3" project_id="1" metric_id="2" value="5"
+ measure_date="2008-12-04 10:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+ <!-- async_measure_snapshots attached to first snapshot -->
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="1" measure_date="2008-12-02 12:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="1" project_id="1"/>
+
+ <!-- async_measure_snapshots attached to no snapshot -->
+ <async_measure_snapshots id="2" project_measure_id="2" snapshot_id="[null]" measure_date="2008-12-03 18:00:00.00"
+ snapshot_date="[null]" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="3" project_measure_id="3" snapshot_id="[null]" measure_date="2008-12-04 10:00:00.00"
+ snapshot_date="[null]" metric_id="2" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignPastMeasuresToPastSnapshot-result.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignPastMeasuresToPastSnapshot-result.xml new file mode 100644 index 00000000000..49a10949faa --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignPastMeasuresToPastSnapshot-result.xml @@ -0,0 +1,47 @@ +<dataset>
+
+ <!-- First snapshot -->
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <!-- Last snapshot -->
+ <snapshots depth="[null]" id="2" scope="PRJ" qualifier="TRK" created_at="2008-12-05 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <!-- New snapshot, inserted between last two -->
+ <snapshots depth="[null]" id="3" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+
+ <!-- reviews attached to first snapshot -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="1"
+ measure_date="2008-12-01 12:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <!-- reviews attached to last snapshot -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="5"
+ measure_date="2008-12-04 12:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+
+ <!-- async_measure_snapshots attached to first snapshot -->
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="1" measure_date="2008-12-01 12:00:00.00"
+ snapshot_date="2008-12-02 12:00:00.00" metric_id="1" project_id="1"/>
+ <!-- async_measure_snapshots attached to last snapshot -->
+ <async_measure_snapshots id="2" project_measure_id="2" snapshot_id="2" measure_date="2008-12-04 12:00:00.00"
+ snapshot_date="2008-12-05 12:00:00.00" metric_id="1" project_id="1"/>
+
+
+ <!-- async_measure_snapshots created for the new snapshot -->
+ <async_measure_snapshots id="3" project_measure_id="1" snapshot_id="3" measure_date="2008-12-01 12:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="1" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignPastMeasuresToPastSnapshot.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignPastMeasuresToPastSnapshot.xml new file mode 100644 index 00000000000..e55b0965ae8 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/assignPastMeasuresToPastSnapshot.xml @@ -0,0 +1,42 @@ +<dataset>
+
+ <!-- First snapshot -->
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <!-- Last snapshot -->
+ <snapshots depth="[null]" id="2" scope="PRJ" qualifier="TRK" created_at="2008-12-05 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <!-- New snapshot, inserted between last two -->
+ <snapshots depth="[null]" id="3" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+
+ <!-- reviews attached to first snapshot -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="1"
+ measure_date="2008-12-01 12:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <!-- reviews attached to last snapshot -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="5"
+ measure_date="2008-12-04 12:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+
+ <!-- async_measure_snapshots attached to first snapshot -->
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="1" measure_date="2008-12-01 12:00:00.00"
+ snapshot_date="2008-12-02 12:00:00.00" metric_id="1" project_id="1"/>
+ <!-- async_measure_snapshots attached to last snapshot -->
+ <async_measure_snapshots id="2" project_measure_id="2" snapshot_id="2" measure_date="2008-12-04 12:00:00.00"
+ snapshot_date="2008-12-05 12:00:00.00" metric_id="1" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/deleteLastMeasure-result.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/deleteLastMeasure-result.xml new file mode 100644 index 00000000000..9f297f684fb --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/deleteLastMeasure-result.xml @@ -0,0 +1,30 @@ +<dataset>
+
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="2" scope="PRJ" qualifier="TRK" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="3" scope="PRJ" qualifier="TRK" created_at="2008-12-05 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" rule_priority="[null]" alert_text="[null]" id="1" project_id="1" metric_id="1" value="12" measure_date="2008-12-03 10:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>-->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="8"
+ measure_date="2008-12-04 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+
+ <!--<async_measure_snapshots id="1" project_measure_id="1" snapshot_id="2" measure_date="2008-12-03 10:00:00.00"-->
+ <!--snapshot_date="2008-12-04 12:00:00.00" metric_id="1" project_id="1"/>-->
+ <async_measure_snapshots id="2" project_measure_id="2" snapshot_id="3" measure_date="2008-12-04 08:00:00.00"
+ snapshot_date="2008-12-05 12:00:00.00" metric_id="1" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/deleteLastMeasure.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/deleteLastMeasure.xml new file mode 100644 index 00000000000..9c2e690dbde --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/deleteLastMeasure.xml @@ -0,0 +1,32 @@ +<dataset>
+
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="2" scope="PRJ" qualifier="TRK" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="3" scope="PRJ" qualifier="TRK" created_at="2008-12-05 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="12"
+ measure_date="2008-12-03 10:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="8"
+ measure_date="2008-12-04 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="2" measure_date="2008-12-03 10:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="2" project_measure_id="2" snapshot_id="3" measure_date="2008-12-04 08:00:00.00"
+ snapshot_date="2008-12-05 12:00:00.00" metric_id="1" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/deleteMeasure-result.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/deleteMeasure-result.xml new file mode 100644 index 00000000000..bbb77395adc --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/deleteMeasure-result.xml @@ -0,0 +1,41 @@ +<dataset>
+
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"/>
+ <snapshots depth="[null]" id="2" scope="PRJ" qualifier="TRK" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"/>
+ <snapshots depth="[null]" id="3" scope="PRJ" qualifier="TRK" created_at="2008-12-05 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="1"
+ measure_date="2008-12-03 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <!-- async measure to be deleted -->
+ <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" rule_priority="[null]" alert_text="[null]" id="2" project_id="1" metric_id="1" value="2" measure_date="2008-12-05 08:00:00.00" rule_id="[null]"-->
+ <!--snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>-->
+
+ <!-- old async measure snapshots -->
+ <!--<async_measure_snapshots id="1" project_measure_id="1" snapshot_id="[null]" measure_date="2008-12-03 08:00:00.00"-->
+ <!--snapshot_date="[null]" metric_id="1" project_id="1" />-->
+
+ <!--<async_measure_snapshots id="2" project_measure_id="1" snapshot_id="1" measure_date="2008-12-03 08:00:00.00"-->
+ <!--snapshot_date="2008-12-03 12:00:00.00" metric_id="1" project_id="1" />-->
+ <!--<async_measure_snapshots id="3" project_measure_id="1" snapshot_id="2" measure_date="2008-12-03 08:00:00.00"-->
+ <!--snapshot_date="2008-12-04 12:00:00.00" metric_id="1" project_id="1" />-->
+ <!--<async_measure_snapshots id="4" project_measure_id="2" snapshot_id="3" measure_date="2008-12-05 08:00:00.00"-->
+ <!--snapshot_date="2008-12-05 12:00:00.00" metric_id="1" project_id="1" />-->
+
+ <async_measure_snapshots id="5" project_measure_id="1" snapshot_id="1" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="6" project_measure_id="1" snapshot_id="2" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="7" project_measure_id="1" snapshot_id="3" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="2008-12-05 12:00:00.00" metric_id="1" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/deleteMeasure.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/deleteMeasure.xml new file mode 100644 index 00000000000..1a86562878e --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/deleteMeasure.xml @@ -0,0 +1,39 @@ +<dataset>
+
+ <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-03 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="2" scope="PRJ" qualifier="TRK" created_at="2008-12-04 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+ <snapshots depth="[null]" id="3" scope="PRJ" qualifier="TRK" created_at="2008-12-05 12:00:00.00" version="[null]"
+ project_id="1"
+ parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true"
+ path="[null]"/>
+
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="1" project_id="1" metric_id="1" value="1"
+ measure_date="2008-12-03 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+ <!-- async measure to be deleted -->
+ <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"
+ rule_priority="[null]"
+ alert_text="[null]" id="2" project_id="1" metric_id="1" value="2"
+ measure_date="2008-12-05 08:00:00.00" rule_id="[null]"
+ snapshot_id="[null]" rules_category_id="[null]" text_value="[null]" tendency="[null]"/>
+
+ <!-- old async measure snapshots -->
+ <async_measure_snapshots id="1" project_measure_id="1" snapshot_id="[null]" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="[null]" metric_id="1" project_id="1"/>
+
+ <async_measure_snapshots id="2" project_measure_id="1" snapshot_id="1" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="2008-12-03 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="3" project_measure_id="1" snapshot_id="2" measure_date="2008-12-03 08:00:00.00"
+ snapshot_date="2008-12-04 12:00:00.00" metric_id="1" project_id="1"/>
+ <async_measure_snapshots id="4" project_measure_id="2" snapshot_id="3" measure_date="2008-12-05 08:00:00.00"
+ snapshot_date="2008-12-05 12:00:00.00" metric_id="1" project_id="1"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/sharedFixture.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/sharedFixture.xml new file mode 100644 index 00000000000..d1a6b09be2f --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/AsyncMeasuresServiceTest/sharedFixture.xml @@ -0,0 +1,13 @@ +<dataset> + + <metrics id="1" name="foo" val_type="INT" description="[null]" domain="[null]" + short_name="" qualitative="false" user_managed="false" enabled="false" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + <metrics id="2" name="bar" val_type="INT" description="[null]" domain="[null]" + short_name="" qualitative="false" user_managed="false" enabled="false" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="[null]" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/ExtensionDaoTest/shared.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/ExtensionDaoTest/shared.xml new file mode 100644 index 00000000000..a369c467f68 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/ExtensionDaoTest/shared.xml @@ -0,0 +1,18 @@ +<dataset> + + <!-- plugins --> + <extensions id="1" plugin_key="checkstyle" extension_type="PLUGIN" version="1.0" + name="Checkstyle" filename="sonar-checkstyle-plugin.jar" plugin_class="[null]" + description="Checkstyle Plugin" organization="SonarSource" organization_url="[null]" license="LGPL" installation_date="[null]" + core="true" /> + + <extensions id="2" plugin_key="pmd" extension_type="PLUGIN" version="1.1" + name="PMD" filename="sonar-pmd-plugin.jar" installation_date="[null]" plugin_class="[null]" + description="PMD Plugin" organization="SonarSource" organization_url="[null]" license="LGPL" + core="true" /> + + <!-- plugin extensions --> + <extensions id="3" plugin_key="checkstyle" extension_type="PLUGIN_EXTENSION" version="[null]" + name="my_checkstyle_rules.jar" filename="my_checkstyle_rules.jar" installation_date="[null]" plugin_class="[null]" + description="[null]" organization="[null]" organization_url="[null]" license="[null]" core="[null]" /> +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/ProfilesDaoTest/shouldGetProfiles.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/ProfilesDaoTest/shouldGetProfiles.xml new file mode 100644 index 00000000000..f1e87d6dcb5 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/ProfilesDaoTest/shouldGetProfiles.xml @@ -0,0 +1,7 @@ +<dataset>
+
+ <rules_profiles id="1" provided="true" name="profile one" default_profile="0" language="java"/>
+ <rules_profiles id="2" provided="true" name="profile two" default_profile="0" language="java"/>
+ <rules_profiles id="3" provided="true" name="profile three" default_profile="0" language="plsql"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldAddActiveRulesToProfile-result.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldAddActiveRulesToProfile-result.xml new file mode 100644 index 00000000000..c7059375406 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldAddActiveRulesToProfile-result.xml @@ -0,0 +1,19 @@ +<dataset> + + <rules_profiles id="1" provided="true" name="profile" default_profile="1" language="java"/> + + <rules_categories id="1" name="category one" description="[null]"/> + + <rules id="1" name="rule1" rules_category_id="1" description="desc" plugin_config_key="config1" + plugin_rule_key="key1" plugin_name="plugin" priority="1" enabled="true" cardinality="SINGLE" parent_id="[null]"/> + + <rules_parameters id="1" rule_id="1" name="param1" description="foo" param_type="r"/> + + <!-- Active rule created --> + <active_rules id="1" profile_id="1" rule_id="1" failure_level="2"/> + + <!-- Active rule param created --> + <active_rule_parameters id="1" active_rule_id="1" rules_parameter_id="1" value="20"/> + + +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldAddActiveRulesToProfile.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldAddActiveRulesToProfile.xml new file mode 100644 index 00000000000..f30fb8d64d9 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldAddActiveRulesToProfile.xml @@ -0,0 +1,13 @@ +<dataset> + + <rules_profiles id="1" provided="true" name="profile" default_profile="1" language="java"/> + + <rules_categories id="1" name="category one" description="[null]"/> + + <rules id="1" name="rule1" rules_category_id="1" description="desc" plugin_config_key="config1" + plugin_rule_key="key1" plugin_name="plugin" priority="1" enabled="true" cardinality="SINGLE" parent_id="[null]"/> + + <rules_parameters id="1" rule_id="1" name="param1" description="foo" param_type="r"/> + + +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldCountNumberOfRulesOfACategoryForGivenPlugins.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldCountNumberOfRulesOfACategoryForGivenPlugins.xml new file mode 100644 index 00000000000..edb6c8d9271 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldCountNumberOfRulesOfACategoryForGivenPlugins.xml @@ -0,0 +1,17 @@ +<dataset> + + <rules_categories id="1" name="category one" description="[null]"/> + <rules_categories id="2" name="category two" description="[null]"/> + + <rules id="1" name="rule one" rules_category_id="1" description="desc" plugin_config_key="config" + plugin_rule_key="rule_one" plugin_name="plugin1" enabled="true" cardinality="SINGLE" parent_id="[null]"/> + + <rules id="2" name="rule two" rules_category_id="1" description="desc" plugin_config_key="config" + plugin_rule_key="rule_two" plugin_name="plugin2" enabled="true" cardinality="SINGLE" parent_id="[null]"/> + <rules id="3" name="rule three" rules_category_id="1" description="desc" plugin_config_key="config" + plugin_rule_key="rule_three" plugin_name="plugin2" enabled="true" cardinality="SINGLE" parent_id="[null]"/> + + <rules id="4" name="rule 4" rules_category_id="2" description="desc" plugin_config_key="config" + plugin_rule_key="rule_4" plugin_name="plugin2" enabled="true" cardinality="SINGLE" parent_id="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldDeleteActiveRuleParametersFromARuleParameter-result.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldDeleteActiveRuleParametersFromARuleParameter-result.xml new file mode 100644 index 00000000000..71c8345bb80 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldDeleteActiveRuleParametersFromARuleParameter-result.xml @@ -0,0 +1,22 @@ +<dataset> + + <rules_categories id="1" name="category one" description="[null]"/> + + <rules id="1" name="rule1" rules_category_id="1" description="desc" plugin_config_key="config" + plugin_rule_key="key1" plugin_name="plugin" enabled="true" cardinality="SINGLE" parent_id="[null]"/> + + <rules_parameters id="1" rule_id="1" name="param1" description="[null]" param_type="r"/> + <rules_parameters id="2" rule_id="1" name="param2" description="[null]" param_type="r"/> + + <rules_profiles id="1" provided="true" name="profile1" default_profile="1" language="java"/> + <rules_profiles id="2" provided="true" name="profile2" default_profile="1" language="OTHER"/> + + <active_rules id="1" profile_id="1" rule_id="1" failure_level="2"/> + <active_rules id="2" profile_id="2" rule_id="1" failure_level="2"/> + + <!-- deleted --> + <!--<active_rule_parameters id="1" active_rule_id="1" rules_parameter_id="1" value="20"/>--> + <!--<active_rule_parameters id="2" active_rule_id="2" rules_parameter_id="1" value="15"/>--> + <active_rule_parameters id="3" active_rule_id="2" rules_parameter_id="2" value="15"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldDeleteActiveRuleParametersFromARuleParameter.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldDeleteActiveRuleParametersFromARuleParameter.xml new file mode 100644 index 00000000000..90456d43522 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldDeleteActiveRuleParametersFromARuleParameter.xml @@ -0,0 +1,21 @@ +<dataset> + + <rules_categories id="1" name="category one" description="[null]"/> + + <rules id="1" name="rule1" rules_category_id="1" description="desc" plugin_config_key="config" + plugin_rule_key="key1" plugin_name="plugin" enabled="true" cardinality="SINGLE" parent_id="[null]"/> + + <rules_parameters id="1" rule_id="1" name="param1" description="foo" param_type="r"/> + <rules_parameters id="2" rule_id="1" name="param2" description="foo" param_type="r"/> + + <rules_profiles id="1" provided="true" name="profile1" default_profile="1" language="java"/> + <rules_profiles id="2" provided="true" name="profile2" default_profile="1" language="OTHER"/> + + <active_rules id="1" profile_id="1" rule_id="1" failure_level="2"/> + <active_rules id="2" profile_id="2" rule_id="1" failure_level="2"/> + + <active_rule_parameters id="1" active_rule_id="1" rules_parameter_id="1" value="20"/> + <active_rule_parameters id="2" active_rule_id="2" rules_parameter_id="1" value="15"/> + <active_rule_parameters id="3" active_rule_id="2" rules_parameter_id="2" value="15"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldDeleteActiveRules-result.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldDeleteActiveRules-result.xml new file mode 100644 index 00000000000..58dc223fc1f --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldDeleteActiveRules-result.xml @@ -0,0 +1,19 @@ +<dataset>
+
+ <rules_categories id="1" name="category one" description="[null]"/>
+
+ <rules_profiles id="1" provided="true" name="profile one" default_profile="1" language="java"/>
+ <rules_profiles id="2" provided="true" name="profile two" default_profile="0" language="java"/>
+
+ <rules id="1" name="foo" rules_category_id="1" description="test" plugin_config_key="checker/foo"
+ plugin_rule_key="checkstyle.rule1" plugin_name="plugin" enabled="true" cardinality="SINGLE" parent_id="[null]"/>
+ <rules id="2" name="bar" rules_category_id="1" description="test" plugin_config_key="checker/bar"
+ plugin_rule_key="checkstyle.rule2" plugin_name="plugin" enabled="true" cardinality="SINGLE" parent_id="[null]"/>
+ <rules id="3" name="baz" rules_category_id="1" description="test" plugin_config_key="checker/baz"
+ plugin_rule_key="checkstyle.rule3" plugin_name="plugin" enabled="true" cardinality="SINGLE" parent_id="[null]"/>
+
+ <active_rules id="1" profile_id="1" rule_id="1" failure_level="2"/>
+ <active_rules id="2" profile_id="1" rule_id="2" failure_level="2"/>
+ <active_rules id="3" profile_id="1" rule_id="3" failure_level="2"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldDeleteActiveRules.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldDeleteActiveRules.xml new file mode 100644 index 00000000000..ffd0336d51f --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldDeleteActiveRules.xml @@ -0,0 +1,23 @@ +<dataset>
+
+ <rules_categories id="1" name="category one" description="[null]"/>
+
+ <rules_profiles id="1" provided="true" name="profile one" default_profile="1" language="java"/>
+ <rules_profiles id="2" provided="true" name="profile two" default_profile="0" language="java"/>
+
+ <rules id="1" name="foo" rules_category_id="1" description="test" plugin_config_key="checker/foo"
+ plugin_rule_key="checkstyle.rule1" plugin_name="plugin" enabled="true" cardinality="SINGLE" parent_id="[null]"/>
+ <rules id="2" name="bar" rules_category_id="1" description="test" plugin_config_key="checker/bar"
+ plugin_rule_key="checkstyle.rule2" plugin_name="plugin" enabled="true" cardinality="SINGLE" parent_id="[null]"/>
+ <rules id="3" name="baz" rules_category_id="1" description="test" plugin_config_key="checker/baz"
+ plugin_rule_key="checkstyle.rule3" plugin_name="plugin" enabled="true" cardinality="SINGLE" parent_id="[null]"/>
+
+ <active_rules id="1" profile_id="1" rule_id="1" failure_level="2"/>
+ <active_rules id="2" profile_id="1" rule_id="2" failure_level="2"/>
+ <active_rules id="3" profile_id="1" rule_id="3" failure_level="2"/>
+
+ <active_rules id="4" profile_id="2" rule_id="1" failure_level="2"/>
+ <active_rules id="5" profile_id="2" rule_id="2" failure_level="2"/>
+ <active_rules id="6" profile_id="2" rule_id="3" failure_level="2"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldGetActiveRules.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldGetActiveRules.xml new file mode 100644 index 00000000000..58dc223fc1f --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldGetActiveRules.xml @@ -0,0 +1,19 @@ +<dataset>
+
+ <rules_categories id="1" name="category one" description="[null]"/>
+
+ <rules_profiles id="1" provided="true" name="profile one" default_profile="1" language="java"/>
+ <rules_profiles id="2" provided="true" name="profile two" default_profile="0" language="java"/>
+
+ <rules id="1" name="foo" rules_category_id="1" description="test" plugin_config_key="checker/foo"
+ plugin_rule_key="checkstyle.rule1" plugin_name="plugin" enabled="true" cardinality="SINGLE" parent_id="[null]"/>
+ <rules id="2" name="bar" rules_category_id="1" description="test" plugin_config_key="checker/bar"
+ plugin_rule_key="checkstyle.rule2" plugin_name="plugin" enabled="true" cardinality="SINGLE" parent_id="[null]"/>
+ <rules id="3" name="baz" rules_category_id="1" description="test" plugin_config_key="checker/baz"
+ plugin_rule_key="checkstyle.rule3" plugin_name="plugin" enabled="true" cardinality="SINGLE" parent_id="[null]"/>
+
+ <active_rules id="1" profile_id="1" rule_id="1" failure_level="2"/>
+ <active_rules id="2" profile_id="1" rule_id="2" failure_level="2"/>
+ <active_rules id="3" profile_id="1" rule_id="3" failure_level="2"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldGetRuleParams.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldGetRuleParams.xml new file mode 100644 index 00000000000..2eded82f21f --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldGetRuleParams.xml @@ -0,0 +1,19 @@ +<dataset>
+
+ <rules_categories id="1" name="category one" description="[null]"/>
+
+ <!-- Rules -->
+ <rules id="1" name="new1" rules_category_id="1" description="test1" plugin_config_key="checker/new1"
+ plugin_rule_key="checkstyle.new1" plugin_name="PLUGIN_KEY" enabled="true" cardinality="SINGLE" parent_id="[null]"/>
+ <rules id="2" name="new2" rules_category_id="1" description="test2" plugin_config_key="checker/new2"
+ plugin_rule_key="checkstyle.new2" plugin_name="PLUGIN_KEY" enabled="true" cardinality="SINGLE" parent_id="[null]"/>
+
+ <!-- Rules parameters -->
+ <rules_parameters id="1" rule_id="1" name="rule1_param1" description="rule1_desc1" param_type="r"
+ />
+ <rules_parameters id="2" rule_id="1" name="rule1_param2" description="rule1_desc2" param_type="r"
+ />
+ <rules_parameters id="3" rule_id="2" name="rule2_param1" description="rule2_desc1" param_type="r"
+ />
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldGetRuleWithRuleKeyAndPluginKey.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldGetRuleWithRuleKeyAndPluginKey.xml new file mode 100644 index 00000000000..00de02226cf --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldGetRuleWithRuleKeyAndPluginKey.xml @@ -0,0 +1,8 @@ +<dataset>
+
+ <rules_categories id="1" name="category one" description="[null]"/>
+
+ <rules id="1" name="foo" rules_category_id="1" description="test" plugin_config_key="checker/foo"
+ plugin_rule_key="checkstyle.rule1" plugin_name="plugin" enabled="true" cardinality="SINGLE" parent_id="[null]"/>
+
+</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldGetRules.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldGetRules.xml new file mode 100644 index 00000000000..9190f5bcdab --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldGetRules.xml @@ -0,0 +1,15 @@ +<dataset> + + <rules_categories id="1" name="category one" description="[null]"/> + + <rules id="1" name="rule one" rules_category_id="1" description="desc" plugin_config_key="other config" + plugin_rule_key="rule_one" plugin_name="plugin" enabled="true" cardinality="SINGLE" parent_id="[null]"/> + <rules id="2" name="rule two" rules_category_id="1" description="desc" plugin_config_key="config" + plugin_rule_key="rule_two" plugin_name="other plugin" enabled="true" cardinality="SINGLE" parent_id="[null]"/> + + <rules_parameters id="1" rule_id="1" name="rule1_param1" description="rule1_desc1" param_type="r" + /> + <rules_parameters id="2" rule_id="2" name="rule2_param1" description="rule2_desc1" param_type="r" + /> + +</dataset>
\ No newline at end of file diff --git a/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldSynchronizeRuleOfActiveRule.xml b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldSynchronizeRuleOfActiveRule.xml new file mode 100644 index 00000000000..3de538103e6 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/jpa/dao/RulesDaoTest/shouldSynchronizeRuleOfActiveRule.xml @@ -0,0 +1,13 @@ +<dataset> + + <rules_categories id="1" name="category one" description="[null]"/> + + <rules id="1" name="other rule" rules_category_id="1" description="desc" plugin_config_key="other config" + plugin_rule_key="other key" plugin_name="plugin" enabled="true" cardinality="SINGLE" parent_id="[null]"/> + <rules id="2" name="rule" rules_category_id="1" description="desc" plugin_config_key="config" + plugin_rule_key="key" plugin_name="other plugin" enabled="true" cardinality="SINGLE" parent_id="[null]"/> + + <rules_parameters id="1" rule_id="1" name="rule1_param1" description="rule1_desc1" param_type="r" /> + <rules_parameters id="2" rule_id="2" name="rule2_param1" description="rule2_desc1" param_type="r" /> + +</dataset>
\ No newline at end of file |