/* Copyright (c) 2014 Boundless and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/edl-v10.html
*
* Contributors:
* Justin Deoliveira (Boundless) - initial implementation
*/
package org.locationtech.geogig.storage.sqlite;
import static java.lang.String.format;
import static org.locationtech.geogig.storage.sqlite.Xerial.log;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.locationtech.geogig.api.Platform;
import org.locationtech.geogig.storage.ConfigDatabase;
import org.locationtech.geogig.storage.ObjectDatabase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
/**
* Staging database based on Xerial SQLite jdbc driver.
*
* @author Justin Deoliveira, Boundless
*/
public class XerialStagingDatabase extends SQLiteStagingDatabase<DataSource> {
final static Logger LOG = LoggerFactory.getLogger(XerialStagingDatabase.class);
final static String CONFLICTS = "conflicts";
@Inject
public XerialStagingDatabase(ObjectDatabase repoDb, ConfigDatabase configdb, Platform platform) {
super(repoDb, new XerialObjectDatabase(configdb, platform, "stage"), configdb, platform);
}
@Override
protected void init(DataSource ds) {
new DbOp<Void>() {
@Override
protected Void doRun(Connection cx) throws SQLException {
String sql = format("CREATE TABLE IF NOT EXISTS %s (namespace VARCHAR, "
+ "path VARCHAR, conflict VARCHAR, PRIMARY KEY(namespace,path))", CONFLICTS);
LOG.debug(sql);
open(cx.createStatement()).execute(sql);
return null;
}
}.run(ds);
}
@Override
protected int count(final String namespace, DataSource ds) {
Connection cx = Xerial.newConnection(ds);
Integer count = new DbOp<Integer>() {
@Override
protected Integer doRun(Connection cx) throws IOException, SQLException {
String sql = format("SELECT count(*) FROM %s WHERE namespace = ?", CONFLICTS);
PreparedStatement ps = open(cx.prepareStatement(log(sql, LOG, namespace)));
ps.setString(1, namespace);
ResultSet rs = ps.executeQuery();
int count = 0;
while (rs.next()) {
count = rs.getInt(1);
}
rs.close();
return Integer.valueOf(count);
}
}.run(cx);
return count.intValue();
}
@Override
protected Iterable<String> get(final String namespace, final String pathFilter, DataSource ds) {
Connection cx = Xerial.newConnection(ds);
ResultSet rs = new DbOp<ResultSet>() {
@Override
protected ResultSet doRun(Connection cx) throws IOException, SQLException {
String sql = format(
"SELECT conflict FROM %s WHERE namespace = ? AND path LIKE '%%%s%%'",
CONFLICTS, pathFilter);
PreparedStatement ps = open(cx.prepareStatement(log(sql, LOG, namespace)));
ps.setString(1, namespace);
return ps.executeQuery();
}
}.run(cx);
return new StringResultSetIterable(rs, cx);
}
@Override
protected void put(final String namespace, final String path, final String conflict,
DataSource ds) {
new DbOp<Void>() {
@Override
protected Void doRun(Connection cx) throws IOException, SQLException {
String sql = format("INSERT OR REPLACE INTO %s VALUES (?,?,?)", CONFLICTS);
log(sql, LOG, namespace, path, conflict);
PreparedStatement ps = open(cx.prepareStatement(sql));
ps.setString(1, namespace);
ps.setString(2, path);
ps.setString(3, conflict);
ps.executeUpdate();
return null;
}
}.run(ds);
}
@Override
protected void remove(final String namespace, final String path, DataSource ds) {
new DbOp<Void>() {
@Override
protected Void doRun(Connection cx) throws IOException, SQLException {
String sql = format("DELETE FROM %s WHERE namespace = ? AND path = ?", CONFLICTS);
log(sql, LOG, namespace, path);
PreparedStatement ps = open(cx.prepareStatement(sql));
ps.setString(1, namespace);
ps.setString(2, path);
ps.executeUpdate();
return null;
}
}.run(ds);
}
}