Author: pawelz Date: Mon Apr 5 02:51:22 2010 New Revision: 11301 Added: toys/cvsstats/web/LICENSE (contents, props changed) toys/cvsstats/web/README (contents, props changed) toys/cvsstats/web/build.xml (contents, props changed) toys/cvsstats/web/src/ toys/cvsstats/web/src/cvsstats.properties (contents, props changed) toys/cvsstats/web/src/pl/ toys/cvsstats/web/src/pl/org/ toys/cvsstats/web/src/pl/org/pld/ toys/cvsstats/web/src/pl/org/pld/cvsstats/ toys/cvsstats/web/src/pl/org/pld/cvsstats/Configuration.java (contents, props changed) toys/cvsstats/web/src/pl/org/pld/cvsstats/Database.java (contents, props changed) toys/cvsstats/web/src/pl/org/pld/cvsstats/MySQLDateTime.java (contents, props changed) toys/cvsstats/web/src/pl/org/pld/cvsstats/ResultsTable.java (contents, props changed) toys/cvsstats/web/src/pl/org/pld/cvsstats/Stats.java (contents, props changed) toys/cvsstats/web/src/pl/org/pld/cvsstats/StatsException.java (contents, props changed) toys/cvsstats/web/src/version.properties (contents, props changed) toys/cvsstats/web/tests/ toys/cvsstats/web/tests/pl/ toys/cvsstats/web/tests/pl/org/ toys/cvsstats/web/tests/pl/org/pld/ toys/cvsstats/web/tests/pl/org/pld/cvsstats/ toys/cvsstats/web/tests/pl/org/pld/cvsstats/MySQLDateTimeTest.java (contents, props changed) toys/cvsstats/web/tests/pl/org/pld/cvsstats/StatsTest.java (contents, props changed) Log: - initial. Basic queries work.
Added: toys/cvsstats/web/LICENSE ============================================================================== --- (empty file) +++ toys/cvsstats/web/LICENSE Mon Apr 5 02:51:22 2010 @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2010 Paweł Zuzelski <[email protected]> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. Added: toys/cvsstats/web/README ============================================================================== --- (empty file) +++ toys/cvsstats/web/README Mon Apr 5 02:51:22 2010 @@ -0,0 +1,22 @@ +1. Installation + + - Create JNDI jdbc data source in your servlet container + - set JNDI name in qsurvey/WEB-INF/classes/cvsstats.properties file + + Unlike most web application, cvsstats does not come with all dependencies. + Depending on your java webserver you may need to install joda-time.jar and + mysql-connector-java.jar manually. Just symlink them to WEB-INF/lib + directory. + +2. Tomcat configuration + + Example servlet descripton file for tomcat 6: + + <?xml version="1.0" encoding="UTF-8"?> + <Context path="/cvsstats" docBase="/usr/local/share/cvsstats" allowLinking="true"> + <Resource name="jdbc/cvsstats" auth="Container" type="javax.sql.DataSource" + username="pldstats" password="pldstats" + driverClassName="com.mysql.jdbc.Driver" + url="jdbc:mysql://localhost/pldstats?autoReconnect=true&useUnicode=true&characterEncoding=UTF8" + maxActive="20" validationQuery="select 1" /> + </Context> Added: toys/cvsstats/web/build.xml ============================================================================== --- (empty file) +++ toys/cvsstats/web/build.xml Mon Apr 5 02:51:22 2010 @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<project name="cvsstats" default="war" basedir="."> + + <property name="appname" value="cvsstats" /> + <property name="build.classes.dir" value="build" /> + <property name="src.dir" value="src" /> + + <property name="servlet.jar" value="/usr/share/java/servlet-api.jar" /> + <property name="joda-time.jar" value="/usr/share/java/joda-time.jar" /> + + <path id="build.path"> + <pathelement location="${servlet.jar}" /> + <pathelement location="${joda-time.jar}" /> + </path> + + <property name="war" value="${appname}.war" /> + + <target name="war" depends="compile"> + <war warfile="${war}" webxml="WebContent/WEB-INF/web.xml"> + <classes dir="${build.classes.dir}" /> + <classes dir="${src.dir}"> + <include name="version.properties" /> + <include name="cvsstats.properties" /> + </classes> + <fileset dir="WebContent"/> + <fileset dir="."> + <include name="README"/> + <include name="LICENSE"/> + </fileset> + </war> + </target> + + <target name="compile" depends="clean"> + <mkdir dir="${build.classes.dir}" /> + <javac srcdir="${src.dir}" destdir="${build.classes.dir}" debug="on" + deprecation="on" classpathref="build.path" optimize="off" includes="**" /> + </target> + + <target name="clean"> + <delete dir="${build.classes.dir}" /> + <delete file="${war}" /> + </target> + +</project> Added: toys/cvsstats/web/src/cvsstats.properties ============================================================================== --- (empty file) +++ toys/cvsstats/web/src/cvsstats.properties Mon Apr 5 02:51:22 2010 @@ -0,0 +1,2 @@ +database.jndi=java:comp/env/jdbc/cvsstats +# data.dir=/var/lib/qsurvey Added: toys/cvsstats/web/src/pl/org/pld/cvsstats/Configuration.java ============================================================================== --- (empty file) +++ toys/cvsstats/web/src/pl/org/pld/cvsstats/Configuration.java Mon Apr 5 02:51:22 2010 @@ -0,0 +1,51 @@ +package pl.org.pld.cvsstats; + +import java.io.IOException; +import java.util.Properties; + +public class Configuration { + private static String version = null; + private static String dataDir = null; + private static String dbJNDI = null; + + public static String getVersion() { + if (version == null) version = initializeVersion(); + return version; + } + + public static String getDbJNDI() { + if (dbJNDI == null) initializeConfig(); + return dbJNDI; + } + + public static String getDataDir() { + if (dataDir == null) initializeConfig(); + return dataDir; + } + + private static String initializeVersion() { + try { + Properties v = new Properties(); + v.load(Configuration.class.getResourceAsStream("/version.properties")); + return v.getProperty("version.major") + "." + v.getProperty("version.minor") + "." + v.getProperty("version.release"); + } + catch(IOException e) + { + e.printStackTrace(); + return null; + } + } + + private static void initializeConfig() { + try { + Properties v = new Properties(); + v.load(Configuration.class.getResourceAsStream("/cvsstats.properties")); + dbJNDI = v.getProperty("database.jndi"); + } + catch(IOException e) + { + e.printStackTrace(); + return; + } + } +} \ No newline at end of file Added: toys/cvsstats/web/src/pl/org/pld/cvsstats/Database.java ============================================================================== --- (empty file) +++ toys/cvsstats/web/src/pl/org/pld/cvsstats/Database.java Mon Apr 5 02:51:22 2010 @@ -0,0 +1,54 @@ +package pl.org.pld.cvsstats; + +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.sql.DataSource; + +public class Database { + private static DataSource _ds; + + public static DataSource getDs() { + if (_ds == null) _ds = initializeDs(); + return _ds; + } + + private static DataSource initializeDs() { + try { + Context initContext = new InitialContext(); + return (DataSource)initContext.lookup(Configuration.getDbJNDI()); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public static void setEncoding(Connection conn) { + try { + String Encoding = "UTF8"; + Statement st = conn.createStatement(); + String query0 = ("SET NAMES "+Encoding); + String query1 = ("SET character_set_client = "+Encoding); + String query2 = ("SET character_set_connection = "+Encoding); + String query3 = ("SET character_set_database = "+Encoding); + String query4 = ("SET character_set_results = "+Encoding); + String query5 = ("SET character_set_server = "+Encoding); + String query6 = ("SET character_set_system = "+Encoding); + + st.executeQuery(query0); + st.executeQuery(query1); + st.executeQuery(query2); + st.executeQuery(query3); + st.executeQuery(query4); + st.executeQuery(query5); + //st.executeQuery(query6); + } + + catch (SQLException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file Added: toys/cvsstats/web/src/pl/org/pld/cvsstats/MySQLDateTime.java ============================================================================== --- (empty file) +++ toys/cvsstats/web/src/pl/org/pld/cvsstats/MySQLDateTime.java Mon Apr 5 02:51:22 2010 @@ -0,0 +1,47 @@ +package pl.org.pld.cvsstats; + +import org.joda.time.DateTime; +import org.joda.time.MutableDateTime; + +public class MySQLDateTime extends MutableDateTime { + + /** + * + */ + private static final long serialVersionUID = -2073723650912930904L; + + public MySQLDateTime(int y, int m, int d, int H, int M, int S) { + super(y, m, d, H, M, S, 0); + } + + public MySQLDateTime(MutableDateTime t) { + super(t); + } + + public MySQLDateTime(DateTime t) { + super(t); + } + + /** + * @return DateTime in mysql datetime format + */ + public String getTimeStamp() { + int y = this.year().get(); + int m = this.monthOfYear().get(); + int d = this.dayOfMonth().get(); + int H = this.hourOfDay().get(); + int M = this.minuteOfHour().get(); + int S = this.secondOfMinute().get(); + + return "" + y + "-" + xx(m) + "-" + xx(d) + " " + + xx(H) + ":" + xx(M) + ":" + xx(S); + } + + /** + * @param d positive integer < 100 + * @return d as two byte string (prepended with 0 if needed) + */ + private String xx(int d) { + return (d<10?"0":"")+d; + } +} Added: toys/cvsstats/web/src/pl/org/pld/cvsstats/ResultsTable.java ============================================================================== --- (empty file) +++ toys/cvsstats/web/src/pl/org/pld/cvsstats/ResultsTable.java Mon Apr 5 02:51:22 2010 @@ -0,0 +1,38 @@ +package pl.org.pld.cvsstats; + +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.util.ArrayList; + +public class ResultsTable { + ArrayList<String[]> rows; + int columnCount; + + public ResultsTable(ResultSet rs, ResultSetMetaData md) throws SQLException { + columnCount = md.getColumnCount(); + rows = new ArrayList<String[]>(); + while (rs.next()) { + String[] row = new String[columnCount]; + int i; + for (i = 0; i < columnCount; i++) row[i] = rs.getString(i+1); + rows.add(row); + } + } + + public int getColumnCount() { + return columnCount; + } + + public int getRowCount() { + return rows.size(); + } + + public String[] getRow(int r) { + return rows.get(r); + } + + public String getCell(int r, int c) { + return rows.get(r)[c]; + } +} \ No newline at end of file Added: toys/cvsstats/web/src/pl/org/pld/cvsstats/Stats.java ============================================================================== --- (empty file) +++ toys/cvsstats/web/src/pl/org/pld/cvsstats/Stats.java Mon Apr 5 02:51:22 2010 @@ -0,0 +1,103 @@ +package pl.org.pld.cvsstats; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.joda.time.Interval; +import org.joda.time.DateTime; +import org.joda.time.Period; + +public class Stats { + String intervalExpression = ""; + + /* CONSTRUCTORS */ + public Stats() { + DateTime now = new DateTime(); + Period month = Period.months(1); + initialize(new Interval(month, now)); + } + + public Stats(Interval p) { + initialize(p); + } + + protected void initialize(Interval p) { + MySQLDateTime start = new MySQLDateTime(p.getStart()); + MySQLDateTime end = new MySQLDateTime(p.getEnd()); + + intervalExpression = "date >= '"+start.getTimeStamp()+"' AND date < '"+end.getTimeStamp()+"'"; + } + + /* QUERY API */ + protected ResultsTable executeQuery(String query) throws SQLException { + Connection conn = null; + conn = Database.getDs().getConnection(); + Database.setEncoding(conn); + query = addCondition(query); + PreparedStatement st = conn.prepareStatement(query); + ResultSet rs = st.executeQuery(); + ResultSetMetaData md = rs.getMetaData(); + ResultsTable rv = new ResultsTable(rs, md); + conn.close(); + return rv; + } + + /** + * Executes query and returns first field of first row as string + * @param query + * @return first field of first row of result + * @throws StatsException + */ + public String simpleQuery(String query) throws StatsException { + ResultsTable rv = null; + try { + rv = executeQuery(query); + if (rv.getRowCount() == 0) { + throw new StatsException("Query returned no data."); + } if (rv.getRowCount() > 1) { + throw new StatsException("Query returned more than one row."); + } if (rv.getColumnCount() == 0) { // XXX Is it possible? + throw new StatsException("Query returned no data."); + } if (rv.getColumnCount() > 1) { + throw new StatsException("Query returned more than one column."); + } + } catch (SQLException e) { + e.printStackTrace(); + throw new StatsException(e.getMessage()); + } + return rv.getCell(0, 0); + } + + /** + * Executes query + * @param query + * @return first field of first row of result + * @throws StatsException + */ + public ResultsTable query(String query) throws StatsException { + ResultsTable rv = null; + try { + rv = executeQuery(query); + } catch (SQLException e) { + e.printStackTrace(); + throw new StatsException("SQL ERROR: " + e.getMessage()); + } + return rv; + } + + /** + * Adds WHERE based on intervalExpression to sql query. + * @param query + * @return query + */ + protected String addCondition(String query) { + Pattern r = Pattern.compile("@WHERE@"); + Matcher m = r.matcher(query); + return m.replaceFirst("WHERE "+intervalExpression); + } +} \ No newline at end of file Added: toys/cvsstats/web/src/pl/org/pld/cvsstats/StatsException.java ============================================================================== --- (empty file) +++ toys/cvsstats/web/src/pl/org/pld/cvsstats/StatsException.java Mon Apr 5 02:51:22 2010 @@ -0,0 +1,14 @@ +package pl.org.pld.cvsstats; + +public class StatsException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 7283457542988916164L; + + public StatsException(String string) { + super(string); + } + +} Added: toys/cvsstats/web/src/version.properties ============================================================================== --- (empty file) +++ toys/cvsstats/web/src/version.properties Mon Apr 5 02:51:22 2010 @@ -0,0 +1,5 @@ +# Do not edit until releasing new version + +version.major = 0 +version.minor = 0 +version.release = 0 Added: toys/cvsstats/web/tests/pl/org/pld/cvsstats/MySQLDateTimeTest.java ============================================================================== --- (empty file) +++ toys/cvsstats/web/tests/pl/org/pld/cvsstats/MySQLDateTimeTest.java Mon Apr 5 02:51:22 2010 @@ -0,0 +1,16 @@ +package pl.org.pld.cvsstats; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class MySQLDateTimeTest { + + @Test + public void testGetTimeStamp() { + MySQLDateTime dt = new MySQLDateTime(2010, 04, 03, 16, 51, 34); + if (dt.getTimeStamp().equals("2010-04-03 16:51:34")) return; + fail("Expected: [2010-04-03 16:51:34], got: ["+dt.getTimeStamp()+"]"); // TODO + } + +} Added: toys/cvsstats/web/tests/pl/org/pld/cvsstats/StatsTest.java ============================================================================== --- (empty file) +++ toys/cvsstats/web/tests/pl/org/pld/cvsstats/StatsTest.java Mon Apr 5 02:51:22 2010 @@ -0,0 +1,23 @@ +package pl.org.pld.cvsstats; + +import static org.junit.Assert.*; + +import org.joda.time.DateTime; +import org.joda.time.Interval; +import org.junit.Test; + +public class StatsTest { + + @Test + public void testAddCondition() { + DateTime beg = new DateTime(2009, 01, 13, 12, 58, 33, 0); + DateTime end = new DateTime(2009, 04, 11, 6, 33, 2, 0); + Stats s = new Stats(new Interval(beg, end)); + String query = s.addCondition("SELECT COUNT(*) FROM commits @WHERE@"); + + if (query.equals("SELECT COUNT(*) FROM commits WHERE date >= '2009-01-13 12:58:33' AND date < '2009-04-11 06:33:02'")) + return; + fail("Expected: [SELECT COUNT(*) FROM commits WHERE date >= '2009-01-13 12:58:33' AND date < '2009-04-11 06:33:02'], got: ["+query+"]"); + } + +} _______________________________________________ pld-cvs-commit mailing list [email protected] http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit
