SVN: toys/cvsstats/web: LICENSE README build.xml src src/cvsstats.properties src/pl src/pl/org src/p...

pawelz pawelz at pld-linux.org
Mon Apr 5 02:51:22 CEST 2010


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 <pawelz at pld-linux.org>
+
+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&amp;useUnicode=true&amp;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+"]");
+	}
+
+}


More information about the pld-cvs-commit mailing list