view src/nabble/model/DailyNumber.java @ 47:72765b66e2c3

remove mailing list code
author Franklin Schmidt <fschmidt@gmail.com>
date Fri, 18 Jun 2021 17:44:24 -0600
parents 7ecd1a4ef557
children
line wrap: on
line source

package nabble.model;

import fschmidt.db.Listener;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;


public final class DailyNumber {
	private static final long updateFreq = 1000L*60;
	private static long lastUpdate = System.currentTimeMillis();
	private static final Object lock = new Object();
	private static final List<DailyNumber> dailyNumbers = new ArrayList<DailyNumber>();
	private static boolean hasChanged = false;

	private final String field;
	private int inc = 0;

	private DailyNumber(String field) {
		this.field = field;
		synchronized(lock) {
			dailyNumbers.add(this);
		}
	}

	public void inc() {
		synchronized(lock) {
			hasChanged = true;
			inc++;
			if( System.currentTimeMillis() - lastUpdate >= updateFreq )
				doSave();
		}
	}

	public void dec() {
		synchronized(lock) {
			hasChanged = true;
			inc--;
			if( System.currentTimeMillis() - lastUpdate >= updateFreq )
				doSave();
		}
	}

	static void shutdown() {
		synchronized(lock) {
			doSave();
		}
	}

	private static void doSave() {
		if( !hasChanged )
			return;
		hasChanged = false;
		try {
			Connection con = Db.dbGlobal().getConnection();
			try {
				boolean hasInc = false;
				StringBuilder buf = new StringBuilder();
				buf.append( "update daily_numbers" );
				for( DailyNumber dn : dailyNumbers ) {
					if( dn.inc == 0 )
						continue;
					if( !hasInc ) {
						buf.append( " set " );
						hasInc = true;
					} else {
						buf.append( ", " );
					}
					buf.append( dn.field ).append( "=" )
						.append( dn.field ).append( "+" ).append( dn.inc );
					dn.inc = 0;
				}
				if( !hasInc )
					return;
				java.sql.Date day = new java.sql.Date(lastUpdate);
				buf.append( " where day=cast(" ).append( Db.dbGlobal().arcana().quote(day) ).append(" as date)");
				Statement stmt = con.createStatement();
				int n = stmt.executeUpdate( buf.toString() );
				if( n == 0 ) {
					stmt.executeUpdate(
						"insert into daily_numbers (day) values (" + Db.dbGlobal().arcana().quote(day) + ")"
					);
					if( stmt.executeUpdate(buf.toString()) != 1 )
						throw new RuntimeException();
				}
				stmt.close();
			} finally {
				con.close();
			}
		} catch(SQLException e) {
			throw new RuntimeException(e);
		} finally {
			lastUpdate = System.currentTimeMillis();
		}
	}

	private static ThreadLocal<java.sql.Date> tlDay = new ThreadLocal<java.sql.Date>();
	private static ThreadLocal<Map<DailyNumber,Integer>> tlMap = new ThreadLocal<Map<DailyNumber,Integer>>();

	public int get(Date date) {
		java.sql.Date day = new java.sql.Date(date.getTime());
		if( !day.equals(tlDay.get()) ) {
			Map<DailyNumber,Integer> map = new HashMap<DailyNumber,Integer>();
			try {
				Connection con = Db.dbGlobal().getConnection();
				PreparedStatement stmt = con.prepareStatement(
					"select * from daily_numbers where day=?"
				);
				stmt.setDate(1,day);
				ResultSet rs = stmt.executeQuery();
				boolean hasNumbers = rs.next();
				for( Iterator i=dailyNumbers.iterator(); i.hasNext(); ) {
					DailyNumber dn = (DailyNumber)i.next();
					map.put( dn, new Integer(hasNumbers?rs.getInt(dn.field):0) );
				}
				stmt.close();
				con.close();
			} catch(SQLException e) {
				throw new RuntimeException(e);
			}
			tlDay.set(day);
			tlMap.set(map);
		}
		Map<DailyNumber,Integer> map = tlMap.get();
		return map.get(this);
	}

	public static final DailyNumber totalVisits = new DailyNumber("total_visits");
	public static final DailyNumber directVisits = new DailyNumber("direct_visits");
	public static final DailyNumber searchEngineVisits = new DailyNumber("se_visits");
	public static final DailyNumber externalVisits = new DailyNumber("ext_visits");
	public static final DailyNumber adVisits = new DailyNumber("ad_visits");
	public static final DailyNumber registrations = new DailyNumber("registrations");
	public static final DailyNumber logins = new DailyNumber("logins");
	public static final DailyNumber externalPosts = new DailyNumber("external_posts");
	public static final DailyNumber internalPosts = new DailyNumber("internal_posts");
	public static final DailyNumber replies = new DailyNumber("replies");
	public static final DailyNumber localForumPosts = new DailyNumber("local_forum_posts");

	public static final DailyNumber forumsStarted = new DailyNumber("forums_started");
	public static final DailyNumber galleriesStarted = new DailyNumber("galleries_started");
	public static final DailyNumber newspapersStarted = new DailyNumber("newspapers_started");
	public static final DailyNumber blogsStarted = new DailyNumber("blogs_started");

	public static final DailyNumber firstForumPosts = new DailyNumber("first_forum_posts");
	public static final DailyNumber firstGalleryPosts = new DailyNumber("first_gallery_posts");
	public static final DailyNumber firstBlogPosts = new DailyNumber("first_blog_posts");
	public static final DailyNumber firstNewspaperPosts = new DailyNumber("first_newspaper_posts");

	public static final DailyNumber blockedSpams = new DailyNumber("blocked_spams");
	public static final DailyNumber tweaks = new DailyNumber("tweaks");


	static {
		NodeImpl.addPostInsertListener(new Listener<NodeImpl>(){
			public void event(final NodeImpl n) {
				if( ModelHome.insideImportProcedure.get() )
					return;
				Db.dbGlobal().runAfterCommit(new Runnable(){public void run(){
					NodeImpl node = (NodeImpl)n.getGoodCopy();
					if( node.getKind()==Node.Kind.APP ) {
						Node parent = node.getParent();
						if( parent==null || !parent.getOwner().equals(node.getOwner()) ) {
							String type = node.getType();
							if (type.equals(Node.Type.GALLERY))
								DailyNumber.galleriesStarted.inc();
							else if (type.equals(Node.Type.NEWS))
								DailyNumber.newspapersStarted.inc();
							else if (type.equals(Node.Type.BLOG))
								DailyNumber.blogsStarted.inc();
							else
								DailyNumber.forumsStarted.inc();
						}
						return;
					}
					NodeImpl post = node;
					DailyNumber.internalPosts.inc();
					DailyNumber.localForumPosts.inc();
					NodeImpl parent = post.getParentImpl();
					if( parent != null && parent.getKind()==Node.Kind.POST )
						DailyNumber.replies.inc();

					boolean isFirstPost = parent != null && parent.getKind()==Node.Kind.APP && parent.getDescendantCount() == 1;
					if (isFirstPost) {
						String type = parent.getType();
						if (type.equals(Node.Type.GALLERY))
							DailyNumber.firstGalleryPosts.inc();
						else if (type.equals(Node.Type.NEWS))
							DailyNumber.firstNewspaperPosts.inc();
						else if (type.equals(Node.Type.BLOG))
							DailyNumber.firstBlogPosts.inc();
						else
							DailyNumber.firstForumPosts.inc();
					}
				}});
			}
		});
	}

	static void nop() {}

	static {
		Init.dailyNumberStarted = true;
	}
}