aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-core
diff options
context:
space:
mode:
authorDavid Gageot <david@gageot.net>2012-10-23 20:36:54 +0200
committerDavid Gageot <david@gageot.net>2012-10-23 22:19:10 +0200
commit525b465edfbfe72f0e0959b75112e08d9420983e (patch)
treeffa0f1c673f9fc43838e695d33a1ba1f4d06abe3 /sonar-core
parent7d66c01396a407628fda7ab99f80ede0af8a9dab (diff)
downloadsonarqube-525b465edfbfe72f0e0959b75112e08d9420983e.tar.gz
sonarqube-525b465edfbfe72f0e0959b75112e08d9420983e.zip
SONAR-3895 Better Local mode
Diffstat (limited to 'sonar-core')
-rw-r--r--sonar-core/src/main/java/org/sonar/core/persistence/DbTemplate.java194
-rw-r--r--sonar-core/src/main/java/org/sonar/core/persistence/LocalDatabaseFactory.java90
-rw-r--r--sonar-core/src/test/java/org/sonar/core/persistence/LocalDatabaseFactoryTest.java75
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/persistence/LocalDatabaseFactoryTest/should_create_database.xml6
4 files changed, 365 insertions, 0 deletions
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DbTemplate.java b/sonar-core/src/main/java/org/sonar/core/persistence/DbTemplate.java
new file mode 100644
index 00000000000..ec40ffee5eb
--- /dev/null
+++ b/sonar-core/src/main/java/org/sonar/core/persistence/DbTemplate.java
@@ -0,0 +1,194 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * 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.persistence;
+
+import org.apache.commons.dbcp.BasicDataSource;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.ServerComponent;
+import org.sonar.api.utils.SonarException;
+
+import javax.sql.DataSource;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+public class DbTemplate implements ServerComponent {
+ private static final Logger LOG = LoggerFactory.getLogger(DbTemplate.class);
+
+ public DbTemplate copyTable(DataSource source, DataSource dest, String table, String query) {
+ LOG.info("Copy table " + table);
+
+ int colCount = getColumnCount(source, table);
+
+ truncate(dest, table);
+
+ Connection sourceConnection = null;
+ Statement sourceStatement = null;
+ ResultSet sourceResultSet = null;
+ Connection destConnection = null;
+ ResultSet destResultSet = null;
+ try {
+ sourceConnection = source.getConnection();
+ sourceStatement = sourceConnection.createStatement();
+ sourceResultSet = sourceStatement.executeQuery(query);
+
+ destConnection = dest.getConnection();
+ destConnection.setAutoCommit(false);
+
+ PreparedStatement destStatement = destConnection.prepareStatement("INSERT INTO " + table + " VALUES(" + StringUtils.repeat("?", ",", colCount) + ")");
+ while (sourceResultSet.next()) {
+ for (int col = 1; col <= colCount; col++) {
+ Object value = sourceResultSet.getObject(col);
+ destStatement.setObject(col, value);
+ }
+ destStatement.addBatch();
+ }
+
+ destStatement.executeBatch();
+ destConnection.commit();
+ destStatement.close();
+ } catch (SQLException e) {
+ throw new SonarException("Fail to copy table " + table, e);
+ } finally {
+ closeQuietly(destResultSet);
+ closeQuietly(destConnection);
+ closeQuietly(sourceResultSet);
+ closeQuietly(sourceStatement);
+ closeQuietly(sourceConnection);
+ }
+
+ return this;
+ }
+
+ public int getColumnCount(DataSource dataSource, String table) {
+ Connection connection = null;
+ ResultSet metaData = null;
+ try {
+ connection = dataSource.getConnection();
+ metaData = connection.getMetaData().getColumns(null, null, table, null);
+
+ int nbColumns = 0;
+ while (metaData.next()) {
+ nbColumns++;
+ }
+
+ return nbColumns;
+ } catch (SQLException e) {
+ throw new SonarException("Fail to get column count for table " + table, e);
+ } finally {
+ closeQuietly(metaData);
+ closeQuietly(connection);
+ }
+ }
+
+ public int getRowCount(BasicDataSource dataSource, String table) {
+ Connection connection = null;
+ Statement statement = null;
+ ResultSet resultSet = null;
+ try {
+ connection = dataSource.getConnection();
+ statement = connection.createStatement();
+ resultSet = statement.executeQuery("SELECT count(*) from " + table);
+
+ return resultSet.next() ? resultSet.getInt(1) : 0;
+ } catch (SQLException e) {
+ throw new SonarException("Fail to get row count for table " + table, e);
+ } finally {
+ closeQuietly(resultSet);
+ closeQuietly(statement);
+ closeQuietly(connection);
+ }
+ }
+
+ public DbTemplate truncate(DataSource dataSource, String table) {
+ Connection connection = null;
+ Statement statement = null;
+ try {
+ connection = dataSource.getConnection();
+ statement = connection.createStatement();
+ statement.executeUpdate("TRUNCATE TABLE " + table);
+ } catch (SQLException e) {
+ throw new SonarException("Fail to truncate table " + table, e);
+ } finally {
+ closeQuietly(statement);
+ closeQuietly(connection);
+ }
+
+ return this;
+ }
+
+ public BasicDataSource dataSource(String driver, String user, String password, String url) {
+ BasicDataSource dataSource = new BasicDataSource();
+ dataSource.setDriverClassName(driver);
+ dataSource.setUsername(user);
+ dataSource.setPassword(password);
+ dataSource.setUrl(url);
+ return dataSource;
+ }
+
+ public DbTemplate createSchema(DataSource dataSource, String dialect) {
+ Connection connection = null;
+ try {
+ connection = dataSource.getConnection();
+ DdlUtils.createSchema(connection, dialect);
+ } catch (SQLException e) {
+ throw new SonarException("Fail to createSchema local database schema", e);
+ } finally {
+ closeQuietly(connection);
+ }
+
+ return this;
+ }
+
+ private void closeQuietly(Connection connection) {
+ if (connection != null) {
+ try {
+ connection.close();
+ } catch (SQLException e) {
+ // ignore
+ }
+ }
+ }
+
+ private void closeQuietly(Statement statement) {
+ if (statement != null) {
+ try {
+ statement.close();
+ } catch (SQLException e) {
+ // ignore
+ }
+ }
+ }
+
+ private void closeQuietly(ResultSet resultSet) {
+ if (resultSet != null) {
+ try {
+ resultSet.close();
+ } catch (SQLException e) {
+ // ignore
+ }
+ }
+ }
+}
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/LocalDatabaseFactory.java b/sonar-core/src/main/java/org/sonar/core/persistence/LocalDatabaseFactory.java
new file mode 100644
index 00000000000..94d83bfaf5c
--- /dev/null
+++ b/sonar-core/src/main/java/org/sonar/core/persistence/LocalDatabaseFactory.java
@@ -0,0 +1,90 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * 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.persistence;
+
+import com.google.common.io.Files;
+import org.apache.commons.dbcp.BasicDataSource;
+import org.sonar.api.ServerComponent;
+import org.sonar.api.utils.SonarException;
+
+import javax.sql.DataSource;
+
+import java.io.File;
+import java.io.IOException;
+import java.sql.SQLException;
+
+public class LocalDatabaseFactory implements ServerComponent {
+ private static final String DIALECT = "h2";
+ private static final String DRIVER = "org.h2.Driver";
+ private static final String URL = "jdbc:h2:";
+ private static final String USER = "sonar";
+ private static final String PASSWORD = "sonar";
+
+ private final Database database;
+
+ public LocalDatabaseFactory(Database database) {
+ this.database = database;
+ }
+
+ public byte[] createDatabaseForLocalMode() {
+ String name = System.getenv("java.io") + System.nanoTime(); // TODO
+
+ try {
+ BasicDataSource destination = create(DIALECT, DRIVER, USER, PASSWORD, URL + name);
+ copy(database.getDataSource(), destination);
+ close(destination);
+
+ return dbFileContent(name);
+ } catch (SQLException e) {
+ throw new SonarException("Unable to create database for local mode", e);
+ }
+ }
+
+ private void copy(DataSource source, DataSource dest) {
+ new DbTemplate().copyTable(source, dest, "PROPERTIES", "SELECT * FROM PROPERTIES WHERE (USER_ID IS NULL) AND (RESOURCE_ID IS NULL) AND NOT (PROP_KEY LIKE '%.secured')")
+ .copyTable(source, dest, "RULES_PROFILES", "SELECT * FROM RULES_PROFILES")
+ .copyTable(source, dest, "RULES", "SELECT * FROM RULES")
+ .copyTable(source, dest, "RULES_PARAMETERS", "SELECT * FROM RULES_PARAMETERS")
+ .copyTable(source, dest, "ACTIVE_RULES", "SELECT * FROM ACTIVE_RULES")
+ .copyTable(source, dest, "ACTIVE_RULE_PARAMETERS", "SELECT * FROM ACTIVE_RULE_PARAMETERS")
+ .copyTable(source, dest, "METRICS", "SELECT * FROM METRICS");
+ }
+
+ private BasicDataSource create(String dialect, String driver, String user, String password, String url) {
+ BasicDataSource dataSource = new DbTemplate().dataSource(driver, user, password, url);
+ new DbTemplate().createSchema(dataSource, dialect);
+ return dataSource;
+ }
+
+ private void close(BasicDataSource dest) throws SQLException {
+ dest.close();
+ }
+
+ private byte[] dbFileContent(String name) {
+ try {
+ File dbFile = new File(name + ".h2.db");
+ byte[] content = Files.toByteArray(dbFile);
+ dbFile.delete();
+ return content;
+ } catch (IOException e) {
+ throw new SonarException("Unable to read h2 database file", e);
+ }
+ }
+}
diff --git a/sonar-core/src/test/java/org/sonar/core/persistence/LocalDatabaseFactoryTest.java b/sonar-core/src/test/java/org/sonar/core/persistence/LocalDatabaseFactoryTest.java
new file mode 100644
index 00000000000..37f48eb2110
--- /dev/null
+++ b/sonar-core/src/test/java/org/sonar/core/persistence/LocalDatabaseFactoryTest.java
@@ -0,0 +1,75 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * 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.persistence;
+
+import com.google.common.io.Files;
+import org.apache.commons.dbcp.BasicDataSource;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import java.io.File;
+import java.io.IOException;
+import java.sql.SQLException;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class LocalDatabaseFactoryTest extends AbstractDaoTestCase {
+ private LocalDatabaseFactory localDatabaseFactory;
+ private BasicDataSource dataSource;
+
+ @Rule
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ @Before
+ public void setUp() {
+ localDatabaseFactory = new LocalDatabaseFactory(getDatabase());
+ }
+
+ @After
+ public void closeDatabase() throws SQLException {
+ if (dataSource != null) {
+ dataSource.close();
+ }
+ }
+
+ @Test
+ public void should_create_database() throws IOException {
+ setupData("should_create_database");
+
+ byte[] database = localDatabaseFactory.createDatabaseForLocalMode();
+ dataSource = createDatabase(database);
+
+ assertThat(rowCount("PROPERTIES")).isEqualTo(1);
+ assertThat(rowCount("PROJECTS")).isZero();
+ }
+
+ private BasicDataSource createDatabase(byte[] db) throws IOException {
+ File file = temporaryFolder.newFile("db.h2.db");
+ Files.write(db, file);
+ return new DbTemplate().dataSource("org.h2.Driver", "sonar", "sonar", "jdbc:h2:" + file.getAbsolutePath().replaceAll(".h2.db", ""));
+ }
+
+ private int rowCount(String table) {
+ return new DbTemplate().getRowCount(dataSource, table);
+ }
+}
diff --git a/sonar-core/src/test/resources/org/sonar/core/persistence/LocalDatabaseFactoryTest/should_create_database.xml b/sonar-core/src/test/resources/org/sonar/core/persistence/LocalDatabaseFactoryTest/should_create_database.xml
new file mode 100644
index 00000000000..281958780db
--- /dev/null
+++ b/sonar-core/src/test/resources/org/sonar/core/persistence/LocalDatabaseFactoryTest/should_create_database.xml
@@ -0,0 +1,6 @@
+<dataset>
+ <properties id="1" prop_key="resourceProperty" text_value="value1" resource_id="1" user_id="[null]"/>
+ <properties id="2" prop_key="globalProperty" text_value="value2" resource_id="[null]" user_id="[null]"/>
+ <properties id="3" prop_key="userProperty" text_value="value3" resource_id="[null]" user_id="1"/>
+ <properties id="4" prop_key="property.secured" text_value="value4" resource_id="[null]" user_id="[null]"/>
+</dataset> \ No newline at end of file
rt/48675/stable28'>backport/48675/stable28 Nextcloud server, a safe home for all your data: https://github.com/nextcloud/serverwww-data
summaryrefslogtreecommitdiffstats
path: root/core/l10n/th_TH.js
blob: 8155339113105315ad5829b58b1195ce4cedb5bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
OC.L10N.register(
    "core",
    {
    "Sunday" : "วันอาทิตย์",
    "Monday" : "วันจันทร์",
    "Tuesday" : "วันอังคาร",
    "Wednesday" : "วันพุธ",
    "Thursday" : "วันพฤหัสบดี",
    "Friday" : "วันศุกร์",
    "Saturday" : "วันเสาร์",
    "January" : "มกราคม",
    "February" : "กุมภาพันธ์",
    "March" : "มีนาคม",
    "April" : "เมษายน",
    "May" : "พฤษภาคม",
    "June" : "มิถุนายน",
    "July" : "กรกฏาคม",
    "August" : "สิงหาคม",
    "September" : "กันยายน",
    "October" : "ตุลาคม",
    "November" : "พฤศจิกายน",
    "December" : "ธันวาคม",
    "Settings" : "ตั้งค่า",
    "Saving..." : "กำลังบันทึกข้อมูล...",
    "No" : "ไม่ตกลง",
    "Yes" : "ตกลง",
    "Choose" : "เลือก",
    "Ok" : "ตกลง",
    "New Files" : "ไฟล์ใหม่",
    "Cancel" : "ยกเลิก",
    "Shared" : "แชร์แล้ว",
    "Share" : "แชร์",
    "Error" : "ข้อผิดพลาด",
    "Error while sharing" : "เกิดข้อผิดพลาดในระหว่างการแชร์ข้อมูล",
    "Error while unsharing" : "เกิดข้อผิดพลาดในการยกเลิกการแชร์ข้อมูล",
    "Error while changing permissions" : "เกิดข้อผิดพลาดในการเปลี่ยนสิทธิ์การเข้าใช้งาน",
    "Shared with you and the group {group} by {owner}" : "ได้แชร์ให้กับคุณ และกลุ่ม {group} โดย {owner}",
    "Shared with you by {owner}" : "ถูกแชร์ให้กับคุณโดย {owner}",
    "Password protect" : "ใส่รหัสผ่านไว้",
    "Password" : "รหัสผ่าน",
    "Email link to person" : "ส่งลิงก์ให้ทางอีเมล",
    "Send" : "ส่ง",
    "Set expiration date" : "กำหนดวันที่หมดอายุ",
    "Expiration date" : "วันที่หมดอายุ",
    "group" : "กลุ่มผู้ใช้งาน",
    "Resharing is not allowed" : "ไม่อนุญาตให้แชร์ข้อมูลซ้ำได้",
    "Shared in {item} with {user}" : "ได้แชร์ {item} ให้กับ {user}",
    "Unshare" : "ยกเลิกการแชร์",
    "can share" : "สามารถแชร์ได้",
    "can edit" : "สามารถแก้ไข",
    "access control" : "ระดับควบคุมการเข้าใช้งาน",
    "create" : "สร้าง",
    "delete" : "ลบ",
    "Password protected" : "ใส่รหัสผ่านไว้",
    "Error unsetting expiration date" : "เกิดข้อผิดพลาดในการยกเลิกการตั้งค่าวันที่หมดอายุ",
    "Error setting expiration date" : "เกิดข้อผิดพลาดในการตั้งค่าวันที่หมดอายุ",
    "Sending ..." : "กำลังส่ง...",
    "Email sent" : "ส่งอีเมล์แล้ว",
    "Warning" : "คำเตือน",
    "The object type is not specified." : "ชนิดของวัตถุยังไม่ได้รับการระบุ",
    "Delete" : "ลบ",
    "Add" : "เพิ่ม",
    "The update was successful. Redirecting you to ownCloud now." : "การอัพเดทเสร็จเรียบร้อยแล้ว กำลังเปลี่ยนเส้นทางไปที่ ownCloud อยู่ในขณะนี้",
    "Use the following link to reset your password: {link}" : "ใช้ลิงค์ต่อไปนี้เพื่อเปลี่ยนรหัสผ่านของคุณใหม่: {link}",
    "New password" : "รหัสผ่านใหม่",
    "Reset password" : "เปลี่ยนรหัสผ่าน",
    "Personal" : "ส่วนตัว",
    "Users" : "ผู้ใช้งาน",
    "Apps" : "แอปฯ",
    "Admin" : "ผู้ดูแล",
    "Help" : "ช่วยเหลือ",
    "Access forbidden" : "การเข้าถึงถูกหวงห้าม",
    "Security Warning" : "คำเตือนเกี่ยวกับความปลอดภัย",
    "Create an <strong>admin account</strong>" : "สร้าง <strong>บัญชีผู้ดูแลระบบ</strong>",
    "Username" : "ชื่อผู้ใช้งาน",
    "Data folder" : "โฟลเดอร์เก็บข้อมูล",
    "Configure the database" : "กำหนดค่าฐานข้อมูล",
    "Database user" : "ชื่อผู้ใช้งานฐานข้อมูล",
    "Database password" : "รหัสผ่านฐานข้อมูล",
    "Database name" : "ชื่อฐานข้อมูล",
    "Database tablespace" : "พื้นที่ตารางในฐานข้อมูล",
    "Database host" : "Database host",
    "Finish setup" : "ติดตั้งเรียบร้อยแล้ว",
    "Log out" : "ออกจากระบบ",
    "Search" : "ค้นหา",
    "remember" : "จำรหัสผ่าน",
    "Log in" : "เข้าสู่ระบบ"
},
"nplurals=1; plural=0;");