src/org/sonews/storage/impl/DrupalDatabase.java
author František Kučera <franta-hg@frantovo.cz>
Tue Oct 11 01:17:30 2011 +0200 (2011-10-11)
changeset 69 b51612c18a54
parent 68 6e16e3bee1ca
child 70 2177f9b14688
permissions -rw-r--r--
Drupal: správné kódování češtiny.
franta-hg@63
     1
/*
franta-hg@63
     2
 *   SONEWS News Server
franta-hg@63
     3
 *   see AUTHORS for the list of contributors
franta-hg@63
     4
 *
franta-hg@63
     5
 *   This program is free software: you can redistribute it and/or modify
franta-hg@63
     6
 *   it under the terms of the GNU General Public License as published by
franta-hg@63
     7
 *   the Free Software Foundation, either version 3 of the License, or
franta-hg@63
     8
 *   (at your option) any later version.
franta-hg@63
     9
 *
franta-hg@63
    10
 *   This program is distributed in the hope that it will be useful,
franta-hg@63
    11
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
franta-hg@63
    12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
franta-hg@63
    13
 *   GNU General Public License for more details.
franta-hg@63
    14
 *
franta-hg@63
    15
 *   You should have received a copy of the GNU General Public License
franta-hg@63
    16
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
franta-hg@63
    17
 */
franta-hg@63
    18
package org.sonews.storage.impl;
franta-hg@63
    19
franta-hg@68
    20
import java.io.UnsupportedEncodingException;
franta-hg@68
    21
import java.sql.Connection;
franta-hg@68
    22
import java.sql.DriverManager;
franta-hg@68
    23
import java.sql.PreparedStatement;
franta-hg@68
    24
import java.sql.ResultSet;
franta-hg@64
    25
import java.sql.SQLException;
franta-hg@68
    26
import java.sql.Statement;
franta-hg@68
    27
import java.util.ArrayList;
franta-hg@65
    28
import java.util.Collections;
franta-hg@64
    29
import java.util.List;
franta-hg@65
    30
import java.util.logging.Level;
franta-hg@66
    31
import java.util.logging.Logger;
franta-hg@68
    32
import javax.mail.internet.MimeUtility;
franta-hg@69
    33
import org.apache.commons.codec.net.QuotedPrintableCodec;
franta-hg@68
    34
import org.sonews.config.Config;
franta-hg@64
    35
import org.sonews.feed.Subscription;
franta-hg@64
    36
import org.sonews.storage.Article;
franta-hg@64
    37
import org.sonews.storage.ArticleHead;
franta-hg@64
    38
import org.sonews.storage.Group;
franta-hg@64
    39
import org.sonews.storage.Storage;
franta-hg@64
    40
import org.sonews.storage.StorageBackendException;
franta-hg@64
    41
import org.sonews.util.Pair;
franta-hg@64
    42
franta-hg@63
    43
/**
franta-hg@63
    44
 *
franta-hg@63
    45
 * @author František Kučera (frantovo.cz)
franta-hg@63
    46
 */
franta-hg@64
    47
public class DrupalDatabase implements Storage {
franta-hg@67
    48
franta-hg@66
    49
	private static final Logger log = Logger.getLogger(DrupalDatabase.class.getName());
franta-hg@68
    50
	public static final String CRLF = "\r\n";
franta-hg@68
    51
	public static final int MAX_RESTARTS = 2;
franta-hg@68
    52
	/** How many times the database connection was reinitialized */
franta-hg@68
    53
	protected int restarts = 0;
franta-hg@68
    54
	protected Connection conn = null;
franta-hg@69
    55
	private QuotedPrintableCodec qpc = new QuotedPrintableCodec("UTF-8");
franta-hg@68
    56
franta-hg@68
    57
	public DrupalDatabase() throws StorageBackendException {
franta-hg@68
    58
		connectDatabase();
franta-hg@68
    59
	}
franta-hg@68
    60
franta-hg@68
    61
	private void connectDatabase() throws StorageBackendException {
franta-hg@68
    62
		try {
franta-hg@68
    63
			// Load database driver
franta-hg@68
    64
			String driverClass = Config.inst().get(Config.LEVEL_FILE, Config.STORAGE_DBMSDRIVER, "java.lang.Object");
franta-hg@68
    65
			Class.forName(driverClass);
franta-hg@68
    66
franta-hg@68
    67
			// Establish database connection
franta-hg@68
    68
			String url = Config.inst().get(Config.LEVEL_FILE, Config.STORAGE_DATABASE, "<not specified>");
franta-hg@68
    69
			String username = Config.inst().get(Config.LEVEL_FILE, Config.STORAGE_USER, "root");
franta-hg@68
    70
			String password = Config.inst().get(Config.LEVEL_FILE, Config.STORAGE_PASSWORD, "");
franta-hg@68
    71
			conn = DriverManager.getConnection(url, username, password);
franta-hg@68
    72
franta-hg@68
    73
			conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
franta-hg@68
    74
			if (conn.getTransactionIsolation() != Connection.TRANSACTION_SERIALIZABLE) {
franta-hg@68
    75
				log.warning("Database is NOT fully serializable!");
franta-hg@68
    76
			}
franta-hg@68
    77
		} catch (Exception e) {
franta-hg@68
    78
			throw new StorageBackendException(e);
franta-hg@68
    79
		}
franta-hg@68
    80
	}
franta-hg@68
    81
franta-hg@68
    82
	protected static void close(Connection connection, Statement statement, ResultSet resultSet) {
franta-hg@68
    83
		if (resultSet != null) {
franta-hg@68
    84
			try {
franta-hg@68
    85
				resultSet.close();
franta-hg@68
    86
			} catch (Exception e) {
franta-hg@68
    87
			}
franta-hg@68
    88
		}
franta-hg@68
    89
		if (statement != null) {
franta-hg@68
    90
			try {
franta-hg@68
    91
				statement.close();
franta-hg@68
    92
			} catch (Exception e) {
franta-hg@68
    93
			}
franta-hg@68
    94
		}
franta-hg@68
    95
		if (connection != null) {
franta-hg@68
    96
			try {
franta-hg@68
    97
				connection.close();
franta-hg@68
    98
			} catch (Exception e) {
franta-hg@68
    99
			}
franta-hg@68
   100
		}
franta-hg@68
   101
	}
franta-hg@64
   102
franta-hg@64
   103
	/**
franta-hg@68
   104
	 * 
franta-hg@68
   105
	 * @param messageID {0}-{1}-{2}@domain.tld where {0} is nntp_id and {1} is group_id and {2} is group_name
franta-hg@68
   106
	 * @return array where [0] = nntp_id and [1] = group_id and [2] = group_name or returns null if messageID is invalid
franta-hg@64
   107
	 */
franta-hg@68
   108
	private static String[] parseMessageID(String messageID) {
franta-hg@68
   109
		if (messageID.matches("[0-9]+\\-[0-9]+\\-[a-z0-9\\.]+@.+")) {
franta-hg@68
   110
			return messageID.split("@")[0].split("\\-");
franta-hg@68
   111
		} else {
franta-hg@68
   112
			return null;
franta-hg@68
   113
		}
franta-hg@68
   114
	}
franta-hg@68
   115
franta-hg@68
   116
	private static Long parseArticleID(String messageID) {
franta-hg@68
   117
		String[] localPart = parseMessageID(messageID);
franta-hg@68
   118
		if (localPart == null) {
franta-hg@68
   119
			return null;
franta-hg@68
   120
		} else {
franta-hg@68
   121
			return Long.parseLong(localPart[0]);
franta-hg@68
   122
		}
franta-hg@68
   123
	}
franta-hg@68
   124
franta-hg@68
   125
	private static Long parseGroupID(String messageID) {
franta-hg@68
   126
		String[] localPart = parseMessageID(messageID);
franta-hg@68
   127
		if (localPart == null) {
franta-hg@68
   128
			return null;
franta-hg@68
   129
		} else {
franta-hg@68
   130
			return Long.parseLong(localPart[1]);
franta-hg@68
   131
		}
franta-hg@68
   132
	}
franta-hg@68
   133
franta-hg@68
   134
	private static String parseGroupName(String messageID) {
franta-hg@68
   135
		String[] localPart = parseMessageID(messageID);
franta-hg@68
   136
		if (localPart == null) {
franta-hg@68
   137
			return null;
franta-hg@68
   138
		} else {
franta-hg@68
   139
			return localPart[2];
franta-hg@68
   140
		}
franta-hg@68
   141
	}
franta-hg@68
   142
franta-hg@68
   143
	private static String constructHeaders(ResultSet rs) throws SQLException, UnsupportedEncodingException {
franta-hg@68
   144
		StringBuilder sb = new StringBuilder();
franta-hg@69
   145
franta-hg@69
   146
		sb.append("Message-id: <");
franta-hg@68
   147
		sb.append(rs.getInt("id"));
franta-hg@68
   148
		sb.append("-");
franta-hg@68
   149
		sb.append(rs.getInt("group_id"));
franta-hg@68
   150
		sb.append("-");
franta-hg@68
   151
		sb.append(rs.getString("group_name"));
franta-hg@68
   152
		sb.append("@");
franta-hg@69
   153
		sb.append("nntp.kinderporno.cz>");
franta-hg@68
   154
		sb.append(CRLF);
franta-hg@69
   155
franta-hg@68
   156
		sb.append("From: ");
franta-hg@68
   157
		sb.append(MimeUtility.encodeWord(rs.getString("sender_name")));
franta-hg@68
   158
		sb.append(" <>");
franta-hg@68
   159
		sb.append(CRLF);
franta-hg@69
   160
franta-hg@68
   161
		sb.append("Subject: ");
franta-hg@68
   162
		sb.append(MimeUtility.encodeWord(rs.getString("subject")));
franta-hg@68
   163
		sb.append(CRLF);
franta-hg@69
   164
franta-hg@69
   165
franta-hg@69
   166
		sb.append("Content-Type: text/html; charset=UTF-8");
franta-hg@69
   167
		sb.append(CRLF);
franta-hg@69
   168
		sb.append("Content-Transfer-Encoding: quoted-printable");
franta-hg@69
   169
		sb.append(CRLF);
franta-hg@68
   170
franta-hg@68
   171
		return sb.toString();
franta-hg@64
   172
	}
franta-hg@64
   173
franta-hg@64
   174
	@Override
franta-hg@67
   175
	public List<Group> getGroups() throws StorageBackendException {
franta-hg@68
   176
		PreparedStatement ps = null;
franta-hg@68
   177
		ResultSet rs = null;
franta-hg@68
   178
		try {
franta-hg@68
   179
			ps = conn.prepareStatement("SELECT * FROM nntp_group");
franta-hg@68
   180
			rs = ps.executeQuery();
franta-hg@68
   181
			List<Group> skupiny = new ArrayList<Group>();
franta-hg@68
   182
franta-hg@68
   183
			while (rs.next()) {
franta-hg@68
   184
				skupiny.add(new Group(rs.getString("name"), rs.getInt("id"), Group.READONLY));
franta-hg@68
   185
			}
franta-hg@68
   186
franta-hg@68
   187
			return skupiny;
franta-hg@68
   188
		} catch (Exception e) {
franta-hg@68
   189
			throw new StorageBackendException(e);
franta-hg@68
   190
		} finally {
franta-hg@68
   191
			close(null, ps, rs);
franta-hg@68
   192
		}
franta-hg@64
   193
	}
franta-hg@64
   194
franta-hg@64
   195
	@Override
franta-hg@67
   196
	public Group getGroup(String name) throws StorageBackendException {
franta-hg@68
   197
		PreparedStatement ps = null;
franta-hg@68
   198
		ResultSet rs = null;
franta-hg@68
   199
		try {
franta-hg@68
   200
			ps = conn.prepareStatement("SELECT * FROM nntp_group WHERE name = ?");
franta-hg@68
   201
			ps.setString(1, name);
franta-hg@68
   202
			rs = ps.executeQuery();
franta-hg@68
   203
franta-hg@68
   204
			while (rs.next()) {
franta-hg@68
   205
				return new Group(rs.getString("name"), rs.getInt("id"), Group.READONLY);
franta-hg@68
   206
			}
franta-hg@68
   207
franta-hg@68
   208
			return null;
franta-hg@68
   209
		} catch (Exception e) {
franta-hg@68
   210
			throw new StorageBackendException(e);
franta-hg@68
   211
		} finally {
franta-hg@68
   212
			close(null, ps, rs);
franta-hg@68
   213
		}
franta-hg@64
   214
	}
franta-hg@64
   215
franta-hg@64
   216
	@Override
franta-hg@67
   217
	public boolean isGroupExisting(String groupname) throws StorageBackendException {
franta-hg@68
   218
		return getGroup(groupname) != null;
franta-hg@64
   219
	}
franta-hg@64
   220
franta-hg@64
   221
	@Override
franta-hg@64
   222
	public Article getArticle(String messageID) throws StorageBackendException {
franta-hg@68
   223
		Long articleID = parseArticleID(messageID);
franta-hg@68
   224
		Long groupID = parseGroupID(messageID);
franta-hg@68
   225
franta-hg@68
   226
		if (articleID == null || groupID == null) {
franta-hg@68
   227
			log.log(Level.SEVERE, "Invalid messageID: {0}", new Object[]{messageID});
franta-hg@68
   228
			return null;
franta-hg@68
   229
		} else {
franta-hg@68
   230
			return getArticle(articleID, groupID);
franta-hg@68
   231
		}
franta-hg@64
   232
	}
franta-hg@64
   233
franta-hg@64
   234
	@Override
franta-hg@68
   235
	public Article getArticle(long articleID, long groupID) throws StorageBackendException {
franta-hg@68
   236
		PreparedStatement ps = null;
franta-hg@68
   237
		ResultSet rs = null;
franta-hg@68
   238
		try {
franta-hg@68
   239
			ps = conn.prepareStatement("SELECT * FROM nntp_article WHERE id = ? AND group_id = ?");
franta-hg@68
   240
			ps.setLong(1, articleID);
franta-hg@68
   241
			ps.setLong(2, groupID);
franta-hg@68
   242
			rs = ps.executeQuery();
franta-hg@68
   243
franta-hg@68
   244
			if (rs.next()) {
franta-hg@68
   245
				String headers = constructHeaders(rs);
franta-hg@69
   246
				byte[] body = qpc.encode(rs.getString("text")).getBytes();
franta-hg@69
   247
franta-hg@68
   248
				return new Article(headers, body);
franta-hg@68
   249
			} else {
franta-hg@68
   250
				return null;
franta-hg@68
   251
			}
franta-hg@68
   252
		} catch (Exception e) {
franta-hg@68
   253
			throw new StorageBackendException(e);
franta-hg@68
   254
		} finally {
franta-hg@68
   255
			close(null, ps, rs);
franta-hg@68
   256
		}
franta-hg@64
   257
	}
franta-hg@64
   258
franta-hg@64
   259
	@Override
franta-hg@64
   260
	public List<Pair<Long, ArticleHead>> getArticleHeads(Group group, long first, long last) throws StorageBackendException {
franta-hg@68
   261
		PreparedStatement ps = null;
franta-hg@68
   262
		ResultSet rs = null;
franta-hg@68
   263
		try {
franta-hg@68
   264
			ps = conn.prepareStatement("SELECT * FROM nntp_article WHERE group_id = ? AND id >= ? AND id <= ?");
franta-hg@68
   265
			ps.setLong(1, group.getInternalID());
franta-hg@68
   266
			ps.setLong(2, first);
franta-hg@68
   267
			ps.setLong(3, last);
franta-hg@68
   268
			rs = ps.executeQuery();
franta-hg@68
   269
franta-hg@68
   270
			List<Pair<Long, ArticleHead>> heads = new ArrayList<Pair<Long, ArticleHead>>();
franta-hg@68
   271
franta-hg@68
   272
			while (rs.next()) {
franta-hg@68
   273
				String headers = constructHeaders(rs);
franta-hg@68
   274
				heads.add(new Pair<Long, ArticleHead>(rs.getLong("id"), new ArticleHead(headers)));
franta-hg@68
   275
			}
franta-hg@68
   276
franta-hg@68
   277
			return heads;
franta-hg@68
   278
		} catch (Exception e) {
franta-hg@68
   279
			throw new StorageBackendException(e);
franta-hg@68
   280
		} finally {
franta-hg@68
   281
			close(null, ps, rs);
franta-hg@68
   282
		}
franta-hg@64
   283
	}
franta-hg@64
   284
franta-hg@64
   285
	@Override
franta-hg@64
   286
	public List<Pair<Long, String>> getArticleHeaders(Group group, long start, long end, String header, String pattern) throws StorageBackendException {
franta-hg@66
   287
		log.log(Level.SEVERE, "TODO: getArticleHeaders {0} / {1} / {2} / {3} / {4}", new Object[]{group, start, end, header, pattern});
franta-hg@65
   288
		/** TODO: */
franta-hg@65
   289
		return Collections.emptyList();
franta-hg@64
   290
	}
franta-hg@64
   291
franta-hg@64
   292
	@Override
franta-hg@68
   293
	public long getArticleIndex(Article article, Group group) throws StorageBackendException {
franta-hg@68
   294
		Long id = parseArticleID(article.getMessageID());
franta-hg@68
   295
		if (id == null) {
franta-hg@68
   296
			throw new StorageBackendException("Invalid messageID: " + article.getMessageID());
franta-hg@68
   297
		} else {
franta-hg@68
   298
			return id;
franta-hg@68
   299
		}
franta-hg@64
   300
	}
franta-hg@64
   301
franta-hg@64
   302
	@Override
franta-hg@64
   303
	public List<Long> getArticleNumbers(long groupID) throws StorageBackendException {
franta-hg@68
   304
		PreparedStatement ps = null;
franta-hg@68
   305
		ResultSet rs = null;
franta-hg@68
   306
		try {
franta-hg@68
   307
			ps = conn.prepareStatement("SELECT id FROM nntp_article WHERE group_id = ?");
franta-hg@68
   308
			ps.setLong(1, groupID);
franta-hg@68
   309
			rs = ps.executeQuery();
franta-hg@68
   310
			List<Long> articleNumbers = new ArrayList<Long>();
franta-hg@68
   311
			while (rs.next()) {
franta-hg@68
   312
				articleNumbers.add(rs.getLong(1));
franta-hg@68
   313
			}
franta-hg@68
   314
			return articleNumbers;
franta-hg@68
   315
		} catch (Exception e) {
franta-hg@68
   316
			throw new StorageBackendException(e);
franta-hg@68
   317
		} finally {
franta-hg@68
   318
			close(null, ps, rs);
franta-hg@68
   319
		}
franta-hg@64
   320
	}
franta-hg@64
   321
franta-hg@64
   322
	@Override
franta-hg@67
   323
	public int getFirstArticleNumber(Group group) throws StorageBackendException {
franta-hg@68
   324
		PreparedStatement ps = null;
franta-hg@68
   325
		ResultSet rs = null;
franta-hg@68
   326
		try {
franta-hg@68
   327
			ps = conn.prepareStatement("SELECT min(id) FROM nntp_article WHERE group_id = ?");
franta-hg@68
   328
			ps.setLong(1, group.getInternalID());
franta-hg@68
   329
			rs = ps.executeQuery();
franta-hg@68
   330
			rs.next();
franta-hg@68
   331
			return rs.getInt(1);
franta-hg@68
   332
		} catch (Exception e) {
franta-hg@68
   333
			throw new StorageBackendException(e);
franta-hg@68
   334
		} finally {
franta-hg@68
   335
			close(null, ps, rs);
franta-hg@68
   336
		}
franta-hg@67
   337
	}
franta-hg@67
   338
franta-hg@67
   339
	@Override
franta-hg@67
   340
	public int getLastArticleNumber(Group group) throws StorageBackendException {
franta-hg@68
   341
		PreparedStatement ps = null;
franta-hg@68
   342
		ResultSet rs = null;
franta-hg@68
   343
		try {
franta-hg@68
   344
			ps = conn.prepareStatement("SELECT max(id) FROM nntp_article WHERE group_id = ?");
franta-hg@68
   345
			ps.setLong(1, group.getInternalID());
franta-hg@68
   346
			rs = ps.executeQuery();
franta-hg@68
   347
			rs.next();
franta-hg@68
   348
			return rs.getInt(1);
franta-hg@68
   349
		} catch (Exception e) {
franta-hg@68
   350
			throw new StorageBackendException(e);
franta-hg@68
   351
		} finally {
franta-hg@68
   352
			close(null, ps, rs);
franta-hg@68
   353
		}
franta-hg@67
   354
	}
franta-hg@67
   355
franta-hg@67
   356
	@Override
franta-hg@67
   357
	public boolean isArticleExisting(String messageID) throws StorageBackendException {
franta-hg@68
   358
		Long articleID = parseArticleID(messageID);
franta-hg@68
   359
		Long groupID = parseGroupID(messageID);
franta-hg@68
   360
franta-hg@68
   361
		if (articleID == null || groupID == null) {
franta-hg@68
   362
			return false;
franta-hg@68
   363
		} else {
franta-hg@68
   364
			PreparedStatement ps = null;
franta-hg@68
   365
			ResultSet rs = null;
franta-hg@68
   366
			try {
franta-hg@68
   367
				ps = conn.prepareStatement("SELECT count(*) FROM nntp_article WHERE id = ? AND group_id = ?");
franta-hg@68
   368
				ps.setLong(1, articleID);
franta-hg@68
   369
				ps.setLong(2, groupID);
franta-hg@68
   370
				rs = ps.executeQuery();
franta-hg@68
   371
franta-hg@68
   372
				rs.next();
franta-hg@68
   373
				return rs.getInt(1) == 1;
franta-hg@68
   374
			} catch (Exception e) {
franta-hg@68
   375
				throw new StorageBackendException(e);
franta-hg@68
   376
			} finally {
franta-hg@68
   377
				close(null, ps, rs);
franta-hg@68
   378
			}
franta-hg@68
   379
		}
franta-hg@67
   380
	}
franta-hg@67
   381
franta-hg@67
   382
	//
franta-hg@67
   383
	// --- zatím neimplementovat ---
franta-hg@67
   384
	//
franta-hg@67
   385
	@Override
franta-hg@67
   386
	public void addArticle(Article art) throws StorageBackendException {
franta-hg@67
   387
		log.log(Level.SEVERE, "TODO: addArticle {0}", new Object[]{art});
franta-hg@67
   388
	}
franta-hg@67
   389
franta-hg@67
   390
	@Override
franta-hg@67
   391
	public void addEvent(long timestamp, int type, long groupID) throws StorageBackendException {
franta-hg@67
   392
		log.log(Level.SEVERE, "TODO: addEvent {0} / {1} / {2}", new Object[]{timestamp, type, groupID});
franta-hg@67
   393
	}
franta-hg@67
   394
franta-hg@67
   395
	@Override
franta-hg@67
   396
	public void addGroup(String groupname, int flags) throws StorageBackendException {
franta-hg@67
   397
		log.log(Level.SEVERE, "TODO: addGroup {0} / {1}", new Object[]{groupname, flags});
franta-hg@67
   398
	}
franta-hg@67
   399
franta-hg@67
   400
	@Override
franta-hg@67
   401
	public int countArticles() throws StorageBackendException {
franta-hg@69
   402
		PreparedStatement ps = null;
franta-hg@69
   403
		ResultSet rs = null;
franta-hg@69
   404
		try {
franta-hg@69
   405
			ps = conn.prepareStatement("SELECT count(*) FROM nntp_article");
franta-hg@69
   406
			rs = ps.executeQuery();
franta-hg@69
   407
			rs.next();
franta-hg@69
   408
			return rs.getInt(1);
franta-hg@69
   409
		} catch (Exception e) {
franta-hg@69
   410
			throw new StorageBackendException(e);
franta-hg@69
   411
		} finally {
franta-hg@69
   412
			close(null, ps, rs);
franta-hg@69
   413
		}
franta-hg@67
   414
	}
franta-hg@67
   415
franta-hg@67
   416
	@Override
franta-hg@67
   417
	public int countGroups() throws StorageBackendException {
franta-hg@69
   418
		PreparedStatement ps = null;
franta-hg@69
   419
		ResultSet rs = null;
franta-hg@69
   420
		try {
franta-hg@69
   421
			ps = conn.prepareStatement("SELECT count(*) FROM nntp_group");
franta-hg@69
   422
			rs = ps.executeQuery();
franta-hg@69
   423
			rs.next();
franta-hg@69
   424
			return rs.getInt(1);
franta-hg@69
   425
		} catch (Exception e) {
franta-hg@69
   426
			throw new StorageBackendException(e);
franta-hg@69
   427
		} finally {
franta-hg@69
   428
			close(null, ps, rs);
franta-hg@69
   429
		}
franta-hg@67
   430
	}
franta-hg@67
   431
franta-hg@67
   432
	@Override
franta-hg@67
   433
	public void delete(String messageID) throws StorageBackendException {
franta-hg@67
   434
		log.log(Level.SEVERE, "TODO: delete {0}", new Object[]{messageID});
franta-hg@67
   435
	}
franta-hg@67
   436
franta-hg@67
   437
	@Override
franta-hg@64
   438
	public String getConfigValue(String key) throws StorageBackendException {
franta-hg@69
   439
		//log.log(Level.SEVERE, "TODO: getConfigValue {0}", new Object[]{key});
franta-hg@65
   440
		return null;
franta-hg@64
   441
	}
franta-hg@64
   442
franta-hg@64
   443
	@Override
franta-hg@64
   444
	public int getEventsCount(int eventType, long startTimestamp, long endTimestamp, Group group) throws StorageBackendException {
franta-hg@66
   445
		log.log(Level.SEVERE, "TODO: getEventsCount {0} / {1} / {2} / {3}", new Object[]{eventType, startTimestamp, endTimestamp, group});
franta-hg@65
   446
		return 0;
franta-hg@64
   447
	}
franta-hg@64
   448
franta-hg@64
   449
	@Override
franta-hg@64
   450
	public double getEventsPerHour(int key, long gid) throws StorageBackendException {
franta-hg@66
   451
		log.log(Level.SEVERE, "TODO: getEventsPerHour {0} / {1}", new Object[]{key, gid});
franta-hg@65
   452
		return 0;
franta-hg@64
   453
	}
franta-hg@64
   454
franta-hg@64
   455
	@Override
franta-hg@64
   456
	public List<String> getGroupsForList(String listAddress) throws StorageBackendException {
franta-hg@66
   457
		log.log(Level.SEVERE, "TODO: getGroupsForList {0}", new Object[]{listAddress});
franta-hg@65
   458
		return Collections.emptyList();
franta-hg@64
   459
	}
franta-hg@64
   460
franta-hg@64
   461
	@Override
franta-hg@64
   462
	public List<String> getListsForGroup(String groupname) throws StorageBackendException {
franta-hg@66
   463
		log.log(Level.SEVERE, "TODO: getListsForGroup {0}", new Object[]{groupname});
franta-hg@65
   464
		return Collections.emptyList();
franta-hg@64
   465
	}
franta-hg@64
   466
franta-hg@64
   467
	@Override
franta-hg@64
   468
	public String getOldestArticle() throws StorageBackendException {
franta-hg@66
   469
		log.log(Level.SEVERE, "TODO: getOldestArticle");
franta-hg@65
   470
		return null;
franta-hg@64
   471
	}
franta-hg@64
   472
franta-hg@64
   473
	@Override
franta-hg@64
   474
	public int getPostingsCount(String groupname) throws StorageBackendException {
franta-hg@69
   475
		PreparedStatement ps = null;
franta-hg@69
   476
		ResultSet rs = null;
franta-hg@69
   477
		try {
franta-hg@69
   478
			ps = conn.prepareStatement("SELECT count(*) FROM nntp_article WHERE group_name = ?");
franta-hg@69
   479
			ps.setString(1, groupname);
franta-hg@69
   480
			rs = ps.executeQuery();
franta-hg@69
   481
			rs.next();
franta-hg@69
   482
			return rs.getInt(1);
franta-hg@69
   483
		} catch (Exception e) {
franta-hg@69
   484
			throw new StorageBackendException(e);
franta-hg@69
   485
		} finally {
franta-hg@69
   486
			close(null, ps, rs);
franta-hg@69
   487
		}
franta-hg@64
   488
	}
franta-hg@64
   489
franta-hg@64
   490
	@Override
franta-hg@64
   491
	public List<Subscription> getSubscriptions(int type) throws StorageBackendException {
franta-hg@66
   492
		log.log(Level.SEVERE, "TODO: getSubscriptions {0}", new Object[]{type});
franta-hg@65
   493
		return Collections.emptyList();
franta-hg@64
   494
	}
franta-hg@64
   495
franta-hg@64
   496
	@Override
franta-hg@64
   497
	public void purgeGroup(Group group) throws StorageBackendException {
franta-hg@66
   498
		log.log(Level.SEVERE, "TODO: purgeGroup {0}", new Object[]{group});
franta-hg@64
   499
	}
franta-hg@64
   500
franta-hg@64
   501
	@Override
franta-hg@64
   502
	public void setConfigValue(String key, String value) throws StorageBackendException {
franta-hg@66
   503
		log.log(Level.SEVERE, "TODO: setConfigValue {0} = {1}", new Object[]{key, value});
franta-hg@64
   504
	}
franta-hg@64
   505
franta-hg@64
   506
	@Override
franta-hg@64
   507
	public boolean update(Article article) throws StorageBackendException {
franta-hg@66
   508
		log.log(Level.SEVERE, "TODO: update {0}", new Object[]{article});
franta-hg@65
   509
		throw new StorageBackendException("Not implemented yet.");
franta-hg@64
   510
	}
franta-hg@64
   511
franta-hg@64
   512
	@Override
franta-hg@64
   513
	public boolean update(Group group) throws StorageBackendException {
franta-hg@66
   514
		log.log(Level.SEVERE, "TODO: update {0}", new Object[]{group});
franta-hg@65
   515
		throw new StorageBackendException("Not implemented yet.");
franta-hg@64
   516
	}
franta-hg@63
   517
}