mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Implement no_mem git-uploads.
This commit is contained in:
parent
4110dcc2a9
commit
ec13e184b7
37 changed files with 572 additions and 936 deletions
|
@ -14,7 +14,7 @@ import uk.ac.ic.wlgitbridge.git.servlet.WLGitServlet;
|
||||||
import uk.ac.ic.wlgitbridge.util.Util;
|
import uk.ac.ic.wlgitbridge.util.Util;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.WriteLatexAPI;
|
import uk.ac.ic.wlgitbridge.writelatex.WriteLatexAPI;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.base.SnapshotAPIRequest;
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.base.SnapshotAPIRequest;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.WLDataModel;
|
import uk.ac.ic.wlgitbridge.writelatex.model.DataStore;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -87,7 +87,7 @@ public class WLGitBridgeServer {
|
||||||
|
|
||||||
private void configureJettyServer() throws ServletException, InvalidRootDirectoryPathException {
|
private void configureJettyServer() throws ServletException, InvalidRootDirectoryPathException {
|
||||||
HandlerCollection handlers = new HandlerCollection();
|
HandlerCollection handlers = new HandlerCollection();
|
||||||
WriteLatexAPI writeLatexDataSource = new WriteLatexAPI(new WLDataModel(rootGitDirectoryPath));
|
WriteLatexAPI writeLatexDataSource = new WriteLatexAPI(new DataStore(rootGitDirectoryPath));
|
||||||
handlers.setHandlers(new Handler[] {
|
handlers.setHandlers(new Handler[] {
|
||||||
initResourceHandler(writeLatexDataSource),
|
initResourceHandler(writeLatexDataSource),
|
||||||
new SnapshotPushPostbackHandler(writeLatexDataSource),
|
new SnapshotPushPostbackHandler(writeLatexDataSource),
|
||||||
|
|
|
@ -1,11 +1,25 @@
|
||||||
package uk.ac.ic.wlgitbridge.bridge;
|
package uk.ac.ic.wlgitbridge.bridge;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Winston on 16/11/14.
|
* Created by Winston on 16/11/14.
|
||||||
*/
|
*/
|
||||||
public interface RawFile {
|
public abstract class RawFile {
|
||||||
|
|
||||||
public String getPath();
|
public abstract String getPath();
|
||||||
public byte[] getContents();
|
public abstract byte[] getContents();
|
||||||
|
|
||||||
|
public final void writeToDisk(File directory) throws IOException {
|
||||||
|
File file = new File(directory, getPath());
|
||||||
|
file.getParentFile().mkdirs();
|
||||||
|
file.createNewFile();
|
||||||
|
OutputStream out = new FileOutputStream(file);
|
||||||
|
out.write(getContents());
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import org.eclipse.jgit.lib.PersonIdent;
|
||||||
import org.eclipse.jgit.lib.Repository;
|
import org.eclipse.jgit.lib.Repository;
|
||||||
import org.eclipse.jgit.transport.ServiceMayNotContinueException;
|
import org.eclipse.jgit.transport.ServiceMayNotContinueException;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.exception.InvalidProjectException;
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.exception.InvalidProjectException;
|
||||||
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.SnapshotPostException;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.store.WLFileStore;
|
import uk.ac.ic.wlgitbridge.writelatex.filestore.store.WLFileStore;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -47,11 +48,7 @@ public class WLBridgedProject {
|
||||||
private void updateRepositoryFromSnapshots(Repository repository) throws RepositoryNotFoundException, ServiceMayNotContinueException {
|
private void updateRepositoryFromSnapshots(Repository repository) throws RepositoryNotFoundException, ServiceMayNotContinueException {
|
||||||
List<WritableRepositoryContents> writableRepositories;
|
List<WritableRepositoryContents> writableRepositories;
|
||||||
try {
|
try {
|
||||||
writableRepositories = writeLatexDataSource.getWritableRepositories(name);
|
writableRepositories = writeLatexDataSource.getWritableRepositories(name, repository);
|
||||||
} catch (InvalidProjectException e) {
|
|
||||||
throw new RepositoryNotFoundException(name);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
for (WritableRepositoryContents contents : writableRepositories) {
|
for (WritableRepositoryContents contents : writableRepositories) {
|
||||||
contents.write();
|
contents.write();
|
||||||
Git git = new Git(repository);
|
Git git = new Git(repository);
|
||||||
|
@ -64,6 +61,10 @@ public class WLBridgedProject {
|
||||||
.call();
|
.call();
|
||||||
WLFileStore.deleteInDirectoryApartFrom(contents.getDirectory(), ".git");
|
WLFileStore.deleteInDirectoryApartFrom(contents.getDirectory(), ".git");
|
||||||
}
|
}
|
||||||
|
} catch (InvalidProjectException e) {
|
||||||
|
throw new RepositoryNotFoundException(name);
|
||||||
|
} catch (SnapshotPostException e) {
|
||||||
|
throw new RepositoryNotFoundException(name);
|
||||||
} catch (GitAPIException e) {
|
} catch (GitAPIException e) {
|
||||||
throw new ServiceMayNotContinueException(e);
|
throw new ServiceMayNotContinueException(e);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package uk.ac.ic.wlgitbridge.bridge;
|
package uk.ac.ic.wlgitbridge.bridge;
|
||||||
|
|
||||||
|
import org.eclipse.jgit.lib.Repository;
|
||||||
import org.eclipse.jgit.transport.ServiceMayNotContinueException;
|
import org.eclipse.jgit.transport.ServiceMayNotContinueException;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.exception.InvalidProjectException;
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.exception.InvalidProjectException;
|
||||||
|
@ -21,7 +22,7 @@ public interface WriteLatexDataSource {
|
||||||
|
|
||||||
/* Called by request thread. */
|
/* Called by request thread. */
|
||||||
public boolean repositoryExists(String projectName) throws ServiceMayNotContinueException;
|
public boolean repositoryExists(String projectName) throws ServiceMayNotContinueException;
|
||||||
public List<WritableRepositoryContents> getWritableRepositories(String projectName) throws FailedConnectionException, InvalidProjectException;
|
public List<WritableRepositoryContents> getWritableRepositories(String projectName, Repository repository) throws IOException, SnapshotPostException;
|
||||||
public void putDirectoryContentsToProjectWithName(String projectName, RawDirectoryContents directoryContents, String hostname) throws SnapshotPostException, IOException, FailedConnectionException;
|
public void putDirectoryContentsToProjectWithName(String projectName, RawDirectoryContents directoryContents, String hostname) throws SnapshotPostException, IOException, FailedConnectionException;
|
||||||
|
|
||||||
void checkPostbackKey(String projectName, String postbackKey) throws InvalidPostbackKeyException;
|
void checkPostbackKey(String projectName, String postbackKey) throws InvalidPostbackKeyException;
|
||||||
|
|
|
@ -23,6 +23,14 @@ public class RepositoryObjectTreeWalker {
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RepositoryObjectTreeWalker(Repository repository) throws IOException {
|
||||||
|
this(repository, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RepositoryObjectTreeWalker(Repository repository, int fromHead) throws IOException {
|
||||||
|
this(repository, repository.resolve("HEAD~" + fromHead));
|
||||||
|
}
|
||||||
|
|
||||||
public RawDirectoryContents getDirectoryContents() throws IOException {
|
public RawDirectoryContents getDirectoryContents() throws IOException {
|
||||||
return new FileDirectoryContents(walkGitObjectTree());
|
return new FileDirectoryContents(walkGitObjectTree());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,163 +1,76 @@
|
||||||
package uk.ac.ic.wlgitbridge.writelatex;
|
package uk.ac.ic.wlgitbridge.writelatex;
|
||||||
|
|
||||||
import uk.ac.ic.wlgitbridge.util.Util;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.SnapshotGetDocRequest;
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.SnapshotGetDocRequest;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.SnapshotGetDocResult;
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.SnapshotGetDocResult;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.exception.InvalidProjectException;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion.SnapshotData;
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion.SnapshotData;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion.SnapshotGetForVersionRequest;
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion.SnapshotGetForVersionRequest;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion.SnapshotGetForVersionResult;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.getsavedvers.SnapshotGetSavedVersRequest;
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.getsavedvers.SnapshotGetSavedVersRequest;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.getsavedvers.SnapshotInfo;
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.getsavedvers.SnapshotInfo;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.SnapshotPostException;
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.SnapshotPostException;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.Snapshot;
|
import uk.ac.ic.wlgitbridge.writelatex.model.Snapshot;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreAPI;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreSource;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Winston on 07/11/14.
|
* Created by Winston on 07/11/14.
|
||||||
*/
|
*/
|
||||||
public class SnapshotFetcher implements PersistentStoreSource {
|
public class SnapshotFetcher {
|
||||||
|
|
||||||
private PersistentStoreAPI persistentStore;
|
public List<Snapshot> getSnapshotsForProjectAfterVersion(String projectName, int version) throws FailedConnectionException, SnapshotPostException {
|
||||||
|
List<SnapshotInfo> snapshotInfos = getSnapshotInfosAfterVersion(projectName, version);
|
||||||
private final String projectName;
|
List<SnapshotData> snapshotDatas = getMatchingSnapshotData(projectName, snapshotInfos);
|
||||||
private final Map<Integer, Snapshot> snapshots;
|
List<Snapshot> snapshots = combine(snapshotInfos, snapshotDatas);
|
||||||
private final SortedSet<Integer> versions;
|
return snapshots;
|
||||||
|
|
||||||
public SnapshotFetcher(String projectName, Map<Integer, Snapshot> snapshots) {
|
|
||||||
this.projectName = projectName;
|
|
||||||
this.snapshots = snapshots;
|
|
||||||
versions = new TreeSet<Integer>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SortedSet<Snapshot> fetchNewSnapshots() throws FailedConnectionException, InvalidProjectException {
|
private List<SnapshotInfo> getSnapshotInfosAfterVersion(String projectName, int version) throws FailedConnectionException, SnapshotPostException {
|
||||||
SortedSet<Snapshot> newSnapshots = new TreeSet<Snapshot>();
|
SortedSet<SnapshotInfo> versions = new TreeSet<SnapshotInfo>();
|
||||||
while (getNew(newSnapshots));
|
|
||||||
for (Snapshot snapshot : newSnapshots) {
|
|
||||||
// persistentStore.addSnapshot(projectName, snapshot.getVersionID());
|
|
||||||
}
|
|
||||||
Util.sout("Fetched snapshots: " + newSnapshots);
|
|
||||||
return newSnapshots;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Snapshot getLatestSnapshot() {
|
|
||||||
if (versions.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return snapshots.get(versions.last());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void putLatestVersion(int versionID) {
|
|
||||||
versions.add(versionID);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initFromPersistentStore(PersistentStoreAPI persistentStore) {
|
|
||||||
this.persistentStore = persistentStore;
|
|
||||||
// for (Integer savedVersionID : persistentStore.getVersionIDsForProjectName(projectName)) {
|
|
||||||
// snapshots.put(savedVersionID, new Snapshot(savedVersionID));
|
|
||||||
// versions.add(savedVersionID);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean getNew(SortedSet<Snapshot> newSnapshots) throws FailedConnectionException, InvalidProjectException {
|
|
||||||
SnapshotGetDocRequest getDoc = new SnapshotGetDocRequest(projectName);
|
SnapshotGetDocRequest getDoc = new SnapshotGetDocRequest(projectName);
|
||||||
SnapshotGetSavedVersRequest getSavedVers = new SnapshotGetSavedVersRequest(projectName);
|
SnapshotGetSavedVersRequest getSavedVers = new SnapshotGetSavedVersRequest(projectName);
|
||||||
|
|
||||||
getDoc.request();
|
getDoc.request();
|
||||||
getSavedVers.request();
|
getSavedVers.request();
|
||||||
|
SnapshotGetDocResult latestDoc = getDoc.getResult();
|
||||||
Set<Integer> fetchedIDs = new HashSet<Integer>();
|
int latest = latestDoc.getVersionID();
|
||||||
Map<Integer, SnapshotInfo> fetchedSnapshotInfos = new HashMap<Integer, SnapshotInfo>();
|
if (latest > version) {
|
||||||
|
|
||||||
int latestVersionID = putLatestDoc(getDoc, fetchedIDs, fetchedSnapshotInfos);
|
|
||||||
|
|
||||||
putSavedVers(getSavedVers, fetchedIDs, fetchedSnapshotInfos);
|
|
||||||
|
|
||||||
List<Integer> idsToUpdate = getIDsToUpdate(fetchedIDs);
|
|
||||||
|
|
||||||
versions.addAll(fetchedIDs);
|
|
||||||
versions.add(latestVersionID);
|
|
||||||
|
|
||||||
return updateIDs(idsToUpdate, fetchedSnapshotInfos, newSnapshots);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void putFetchedResult(SnapshotInfo snapshotInfo, Set<Integer> ids, Map<Integer, SnapshotInfo> snapshotInfos) {
|
|
||||||
int versionID = snapshotInfo.getVersionId();
|
|
||||||
snapshotInfos.put(versionID, snapshotInfo);
|
|
||||||
ids.add(versionID);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int putLatestDoc(SnapshotGetDocRequest getDoc, Set<Integer> fetchedIDs, Map<Integer, SnapshotInfo> fetchedSnapshotInfos) throws FailedConnectionException, InvalidProjectException {
|
|
||||||
SnapshotGetDocResult result = getDoc.getResult();
|
|
||||||
int latestVersionID = 0;
|
|
||||||
try {
|
|
||||||
latestVersionID = result.getVersionID();
|
|
||||||
} catch (SnapshotPostException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
putFetchedResult(new SnapshotInfo(latestVersionID, result.getCreatedAt(), result.getName(), result.getEmail()), fetchedIDs, fetchedSnapshotInfos);
|
|
||||||
return latestVersionID;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void putSavedVers(SnapshotGetSavedVersRequest getSavedVers, Set<Integer> fetchedIDs, Map<Integer, SnapshotInfo> fetchedSnapshotInfos) throws FailedConnectionException {
|
|
||||||
for (SnapshotInfo snapshotInfo : getSavedVers.getResult().getSavedVers()) {
|
for (SnapshotInfo snapshotInfo : getSavedVers.getResult().getSavedVers()) {
|
||||||
putFetchedResult(snapshotInfo, fetchedIDs, fetchedSnapshotInfos);
|
if (snapshotInfo.getVersionId() > version) {
|
||||||
|
versions.add(snapshotInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
versions.add(new SnapshotInfo(latest, latestDoc.getCreatedAt(), latestDoc.getName(), latestDoc.getEmail()));
|
||||||
|
|
||||||
|
}
|
||||||
|
return new LinkedList<SnapshotInfo>(versions);
|
||||||
|
}
|
||||||
|
|
||||||
private List<Integer> getIDsToUpdate(Set<Integer> fetchedIDs) {
|
private List<SnapshotData> getMatchingSnapshotData(String projectName, List<SnapshotInfo> snapshotInfos) throws FailedConnectionException {
|
||||||
List<Integer> idsToUpdate = new LinkedList<Integer>();
|
List<SnapshotGetForVersionRequest> firedRequests = fireDataRequests(projectName, snapshotInfos);
|
||||||
for (Integer id : fetchedIDs) {
|
List<SnapshotData> snapshotDataList = new LinkedList<SnapshotData>();
|
||||||
if (!versions.contains(id)) {
|
for (SnapshotGetForVersionRequest fired : firedRequests) {
|
||||||
idsToUpdate.add(id);
|
snapshotDataList.add(fired.getResult().getSnapshotData());
|
||||||
}
|
}
|
||||||
}
|
return snapshotDataList;
|
||||||
return idsToUpdate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean updateIDs(List<Integer> idsToUpdate, Map<Integer, SnapshotInfo> fetchedSnapshotInfos, SortedSet<Snapshot> newSnapshots) throws FailedConnectionException {
|
private List<SnapshotGetForVersionRequest> fireDataRequests(String projectName, List<SnapshotInfo> snapshotInfos) {
|
||||||
if (idsToUpdate.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
fetchVersions(idsToUpdate, fetchedSnapshotInfos, newSnapshots);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void fetchVersions(List<Integer> idsToUpdate, Map<Integer, SnapshotInfo> fetchedSnapshotInfos, SortedSet<Snapshot> newSnapshots) throws FailedConnectionException {
|
|
||||||
List<SnapshotGetForVersionRequest> requests = createFiredRequests(idsToUpdate);
|
|
||||||
processResults(fetchedSnapshotInfos, newSnapshots, requests);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<SnapshotGetForVersionRequest> createFiredRequests(List<Integer> idsToUpdate) {
|
|
||||||
List<SnapshotGetForVersionRequest> requests = new LinkedList<SnapshotGetForVersionRequest>();
|
List<SnapshotGetForVersionRequest> requests = new LinkedList<SnapshotGetForVersionRequest>();
|
||||||
for (int id : idsToUpdate) {
|
for (SnapshotInfo snapshotInfo : snapshotInfos) {
|
||||||
SnapshotGetForVersionRequest request = new SnapshotGetForVersionRequest(projectName, id);
|
SnapshotGetForVersionRequest request = new SnapshotGetForVersionRequest(projectName, snapshotInfo.getVersionId());
|
||||||
requests.add(request);
|
requests.add(request);
|
||||||
request.request();
|
request.request();
|
||||||
}
|
}
|
||||||
return requests;
|
return requests;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processResults(Map<Integer, SnapshotInfo> fetchedSnapshotInfos, SortedSet<Snapshot> newSnapshots, List<SnapshotGetForVersionRequest> requests) throws FailedConnectionException {
|
private List<Snapshot> combine(List<SnapshotInfo> snapshotInfos, List<SnapshotData> snapshotDatas) {
|
||||||
for (SnapshotGetForVersionRequest request : requests) {
|
List<Snapshot> snapshots = new LinkedList<Snapshot>();
|
||||||
processResult(fetchedSnapshotInfos, newSnapshots, request);
|
Iterator<SnapshotInfo> infos = snapshotInfos.iterator();
|
||||||
|
Iterator<SnapshotData> datas = snapshotDatas.iterator();
|
||||||
|
while (infos.hasNext()) {
|
||||||
|
snapshots.add(new Snapshot(infos.next(), datas.next()));
|
||||||
}
|
}
|
||||||
|
return snapshots;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processResult(Map<Integer, SnapshotInfo> fetchedSnapshotInfos, SortedSet<Snapshot> newSnapshots, SnapshotGetForVersionRequest request) throws FailedConnectionException {
|
|
||||||
SnapshotGetForVersionResult result = request.getResult();
|
|
||||||
SnapshotData data = result.getSnapshotData();
|
|
||||||
Snapshot snapshot = new Snapshot(fetchedSnapshotInfos.get(request.getVersionID()), data);
|
|
||||||
snapshots.put(request.getVersionID(), snapshot);
|
|
||||||
newSnapshots.add(snapshot);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SortedSet<Integer> getVersions() {
|
|
||||||
return versions;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,84 +3,78 @@ package uk.ac.ic.wlgitbridge.writelatex;
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import uk.ac.ic.wlgitbridge.bridge.CandidateSnapshot;
|
|
||||||
import uk.ac.ic.wlgitbridge.bridge.CandidateSnapshotCallback;
|
|
||||||
import uk.ac.ic.wlgitbridge.util.Util;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.node.FileNode;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.node.WLDirectoryNode;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.WLProject;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Winston on 16/11/14.
|
* Created by Winston on 16/11/14.
|
||||||
*/
|
*/
|
||||||
public class WLDirectoryNodeSnapshot implements CandidateSnapshot {
|
public class WLDirectoryNodeSnapshot /*implements CandidateSnapshot*/ {
|
||||||
|
|
||||||
private final int previousVersionID;
|
// private final int previousVersionID;
|
||||||
private final String projectName;
|
// private final String projectName;
|
||||||
private final String projectURL;
|
// private final String projectURL;
|
||||||
private final WLDirectoryNode directoryNode;
|
// private final WLDirectoryNode directoryNode;
|
||||||
private final String postbackKey;
|
// private final String postbackKey;
|
||||||
private final CandidateSnapshotCallback callback;
|
// private final CandidateSnapshotCallback callback;
|
||||||
|
|
||||||
public WLDirectoryNodeSnapshot(WLProject project, WLDirectoryNode directoryNode, String hostname, String postbackKey, CandidateSnapshotCallback callback) {
|
// public WLDirectoryNodeSnapshot(WLProject project, WLDirectoryNode directoryNode, String hostname, String postbackKey, CandidateSnapshotCallback callback) {
|
||||||
previousVersionID = project.getLatestSnapshotID();
|
// previousVersionID = project.getLatestSnapshotID();
|
||||||
projectName = project.getName();
|
// projectName = project.getName();
|
||||||
projectURL = Util.getPostbackURL() + projectName;
|
// projectURL = Util.getPostbackURL() + projectName;
|
||||||
|
//
|
||||||
|
// this.directoryNode = directoryNode;
|
||||||
|
// this.postbackKey = postbackKey;
|
||||||
|
// this.callback = callback;
|
||||||
|
// }
|
||||||
|
|
||||||
this.directoryNode = directoryNode;
|
// @Override
|
||||||
this.postbackKey = postbackKey;
|
|
||||||
this.callback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonElement getJsonRepresentation() {
|
public JsonElement getJsonRepresentation() {
|
||||||
JsonObject jsonObject = new JsonObject();
|
JsonObject jsonObject = new JsonObject();
|
||||||
jsonObject.addProperty("latestVerId", previousVersionID);
|
// jsonObject.addProperty("latestVerId", previousVersionID);
|
||||||
jsonObject.add("files", getFilesAsJson());
|
// jsonObject.add("files", getFilesAsJson());
|
||||||
jsonObject.addProperty("postbackUrl", projectURL + "/" + postbackKey + "/postback");
|
// jsonObject.addProperty("postbackUrl", projectURL + "/" + postbackKey + "/postback");
|
||||||
return jsonObject;
|
return jsonObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JsonArray getFilesAsJson() {
|
private JsonArray getFilesAsJson() {
|
||||||
JsonArray filesArray = new JsonArray();
|
JsonArray filesArray = new JsonArray();
|
||||||
for (FileNode fileNode : directoryNode.getFileNodes()) {
|
// for (FileNode fileNode : directoryNode.getFileNodes()) {
|
||||||
filesArray.add(getFileAsJson(fileNode));
|
// filesArray.add(getFileAsJson(fileNode));
|
||||||
}
|
// }
|
||||||
return filesArray;
|
return filesArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JsonObject getFileAsJson(FileNode fileNode) {
|
// private JsonObject getFileAsJson(FileNode fileNode) {
|
||||||
JsonObject file = new JsonObject();
|
// JsonObject file = new JsonObject();
|
||||||
file.addProperty("name", fileNode.getFilePath());
|
// file.addProperty("name", fileNode.getFilePath());
|
||||||
if (fileNode.isChanged()) {
|
// if (fileNode.isChanged()) {
|
||||||
file.addProperty("url", projectURL + "/" + fileNode.getFilePath() + "?key=" + postbackKey);
|
// file.addProperty("url", projectURL + "/" + fileNode.getFilePath() + "?key=" + postbackKey);
|
||||||
}
|
// }
|
||||||
return file;
|
// return file;
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public int getPreviousVersionID() {
|
// public int getPreviousVersionID() {
|
||||||
return previousVersionID;
|
// return previousVersionID;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public String getProjectURL() {
|
// public String getProjectURL() {
|
||||||
return projectURL;
|
// return projectURL;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public void approveWithVersionID(int versionID) {
|
// public void approveWithVersionID(int versionID) {
|
||||||
callback.approveSnapshot(versionID, this);
|
// callback.approveSnapshot(versionID, this);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public String getProjectName() {
|
// public String getProjectName() {
|
||||||
return projectName;
|
// return projectName;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public WLDirectoryNode getDirectoryNode() {
|
// public WLDirectoryNode getDirectoryNode() {
|
||||||
return directoryNode;
|
// return directoryNode;
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package uk.ac.ic.wlgitbridge.writelatex;
|
package uk.ac.ic.wlgitbridge.writelatex;
|
||||||
|
|
||||||
|
import org.eclipse.jgit.lib.Repository;
|
||||||
import org.eclipse.jgit.transport.ServiceMayNotContinueException;
|
import org.eclipse.jgit.transport.ServiceMayNotContinueException;
|
||||||
import uk.ac.ic.wlgitbridge.bridge.CandidateSnapshot;
|
import uk.ac.ic.wlgitbridge.bridge.CandidateSnapshot;
|
||||||
import uk.ac.ic.wlgitbridge.bridge.RawDirectoryContents;
|
import uk.ac.ic.wlgitbridge.bridge.RawDirectoryContents;
|
||||||
|
@ -13,7 +14,7 @@ import uk.ac.ic.wlgitbridge.writelatex.api.request.push.PostbackManager;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.push.SnapshotPushRequest;
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.push.SnapshotPushRequest;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.push.SnapshotPushRequestResult;
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.push.SnapshotPushRequestResult;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.*;
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.*;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.WLDataModel;
|
import uk.ac.ic.wlgitbridge.writelatex.model.DataStore;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -23,11 +24,11 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public class WriteLatexAPI implements WriteLatexDataSource {
|
public class WriteLatexAPI implements WriteLatexDataSource {
|
||||||
|
|
||||||
private final WLDataModel dataModel;
|
private final DataStore dataModel;
|
||||||
private final PostbackManager postbackManager;
|
private final PostbackManager postbackManager;
|
||||||
private final ProjectLock mainProjectLock;
|
private final ProjectLock mainProjectLock;
|
||||||
|
|
||||||
public WriteLatexAPI(WLDataModel dataModel) {
|
public WriteLatexAPI(DataStore dataModel) {
|
||||||
this.dataModel = dataModel;
|
this.dataModel = dataModel;
|
||||||
postbackManager = new PostbackManager();
|
postbackManager = new PostbackManager();
|
||||||
mainProjectLock = new ProjectLock();
|
mainProjectLock = new ProjectLock();
|
||||||
|
@ -64,9 +65,9 @@ public class WriteLatexAPI implements WriteLatexDataSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<WritableRepositoryContents> getWritableRepositories(String projectName) throws FailedConnectionException, InvalidProjectException {
|
public List<WritableRepositoryContents> getWritableRepositories(String projectName, Repository repository) throws IOException, SnapshotPostException {
|
||||||
Util.sout("Fetching project: " + projectName);
|
Util.sout("Fetching project: " + projectName);
|
||||||
List<WritableRepositoryContents> writableRepositoryContents = dataModel.updateProjectWithName(projectName);
|
List<WritableRepositoryContents> writableRepositoryContents = dataModel.updateProjectWithName(projectName, repository);
|
||||||
return writableRepositoryContents;
|
return writableRepositoryContents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,24 +3,42 @@ package uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion;
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonPrimitive;
|
import com.google.gson.JsonPrimitive;
|
||||||
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.base.JSONSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Winston on 06/11/14.
|
* Created by Winston on 06/11/14.
|
||||||
*/
|
*/
|
||||||
public class SnapshotAttachment extends SnapshotFile {
|
public class SnapshotAttachment implements JSONSource {
|
||||||
|
|
||||||
private String url;
|
private String url;
|
||||||
|
private String path;
|
||||||
|
|
||||||
public SnapshotAttachment(JsonElement json) {
|
public SnapshotAttachment(JsonElement json) {
|
||||||
super(json);
|
fromJSON(json);
|
||||||
}
|
|
||||||
|
|
||||||
public SnapshotAttachment(String url, String path) {
|
|
||||||
super(null, path);
|
|
||||||
this.url = url;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public void fromJSON(JsonElement json) {
|
||||||
|
JsonArray jsonArray = json.getAsJsonArray();
|
||||||
|
url = jsonArray.get(0).getAsString();
|
||||||
|
path = jsonArray.get(1).getAsString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPath() {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For the Mock Snapshot server */
|
||||||
|
|
||||||
|
public SnapshotAttachment(String url, String path) {
|
||||||
|
this.url = url;
|
||||||
|
this.path = path;
|
||||||
|
}
|
||||||
|
|
||||||
public JsonElement toJson() {
|
public JsonElement toJson() {
|
||||||
JsonArray jsonThis = new JsonArray();
|
JsonArray jsonThis = new JsonArray();
|
||||||
jsonThis.add(new JsonPrimitive(url));
|
jsonThis.add(new JsonPrimitive(url));
|
||||||
|
@ -28,18 +46,4 @@ public class SnapshotAttachment extends SnapshotFile {
|
||||||
return jsonThis;
|
return jsonThis;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getContents() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void getContentsFromJSON(JsonArray jsonArray) {
|
|
||||||
url = jsonArray.get(0).getAsString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUrl() {
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,27 +9,20 @@ import uk.ac.ic.wlgitbridge.writelatex.api.request.base.JSONSource;
|
||||||
/**
|
/**
|
||||||
* Created by Winston on 06/11/14.
|
* Created by Winston on 06/11/14.
|
||||||
*/
|
*/
|
||||||
public class SnapshotFile implements JSONSource, RawFile {
|
public class SnapshotFile extends RawFile implements JSONSource {
|
||||||
|
|
||||||
protected byte[] contents;
|
|
||||||
private String path;
|
private String path;
|
||||||
|
private byte[] contents;
|
||||||
|
|
||||||
public SnapshotFile(JsonElement json) {
|
public SnapshotFile(JsonElement json) {
|
||||||
fromJSON(json);
|
fromJSON(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SnapshotFile(String contents, String path) {
|
@Override
|
||||||
this.path = path;
|
public void fromJSON(JsonElement json) {
|
||||||
if (contents != null) {
|
JsonArray jsonArray = json.getAsJsonArray();
|
||||||
this.contents = contents.getBytes();
|
contents = jsonArray.get(0).getAsString().getBytes();
|
||||||
}
|
path = jsonArray.get(1).getAsString();
|
||||||
}
|
|
||||||
|
|
||||||
public JsonElement toJson() {
|
|
||||||
JsonArray jsonThis = new JsonArray();
|
|
||||||
jsonThis.add(new JsonPrimitive(new String(contents)));
|
|
||||||
jsonThis.add(new JsonPrimitive(path));
|
|
||||||
return jsonThis;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -42,19 +35,22 @@ public class SnapshotFile implements JSONSource, RawFile {
|
||||||
return contents;
|
return contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/* Mock server */
|
||||||
public void fromJSON(JsonElement json) {
|
|
||||||
JsonArray jsonArray = json.getAsJsonArray();
|
public SnapshotFile(String contents, String path) {
|
||||||
getContentsFromJSON(jsonArray);
|
this.path = path;
|
||||||
getPathFromJSON(jsonArray);
|
if (contents != null) {
|
||||||
|
this.contents = contents.getBytes();
|
||||||
|
} else {
|
||||||
|
this.contents = new byte[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void getContentsFromJSON(JsonArray jsonArray) {
|
public JsonElement toJson() {
|
||||||
contents = jsonArray.get(0).getAsString().getBytes();
|
JsonArray jsonThis = new JsonArray();
|
||||||
}
|
jsonThis.add(new JsonPrimitive(new String(contents)));
|
||||||
|
jsonThis.add(new JsonPrimitive(path));
|
||||||
protected void getPathFromJSON(JsonArray jsonArray) {
|
return jsonThis;
|
||||||
path = jsonArray.get(1).getAsString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import uk.ac.ic.wlgitbridge.util.Util;
|
||||||
/**
|
/**
|
||||||
* Created by Winston on 06/11/14.
|
* Created by Winston on 06/11/14.
|
||||||
*/
|
*/
|
||||||
public class SnapshotInfo {
|
public class SnapshotInfo implements Comparable<SnapshotInfo> {
|
||||||
|
|
||||||
private int versionId;
|
private int versionId;
|
||||||
private String comment;
|
private String comment;
|
||||||
|
@ -39,4 +39,17 @@ public class SnapshotInfo {
|
||||||
return createdAt;
|
return createdAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (!(obj instanceof SnapshotInfo)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SnapshotInfo that = (SnapshotInfo) obj;
|
||||||
|
return versionId == that.versionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(SnapshotInfo o) {
|
||||||
|
return Integer.compare(versionId, o.versionId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
package uk.ac.ic.wlgitbridge.writelatex.filestore;
|
package uk.ac.ic.wlgitbridge.writelatex.filestore;
|
||||||
|
|
||||||
|
import uk.ac.ic.wlgitbridge.bridge.RawFile;
|
||||||
import uk.ac.ic.wlgitbridge.bridge.WritableRepositoryContents;
|
import uk.ac.ic.wlgitbridge.bridge.WritableRepositoryContents;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.node.FileNode;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.store.WLFileStore;
|
import uk.ac.ic.wlgitbridge.writelatex.filestore.store.WLFileStore;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.Snapshot;
|
import uk.ac.ic.wlgitbridge.writelatex.model.Snapshot;
|
||||||
|
|
||||||
|
@ -16,15 +15,15 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public class GitDirectoryContents implements WritableRepositoryContents {
|
public class GitDirectoryContents implements WritableRepositoryContents {
|
||||||
|
|
||||||
private final List<FileNode> fileNodes;
|
private final List<RawFile> files;
|
||||||
private final File gitDirectory;
|
private final File gitDirectory;
|
||||||
private final String userName;
|
private final String userName;
|
||||||
private final String userEmail;
|
private final String userEmail;
|
||||||
private final String commitMessage;
|
private final String commitMessage;
|
||||||
private final Date when;
|
private final Date when;
|
||||||
|
|
||||||
public GitDirectoryContents(List<FileNode> fileNodes, File rootGitDirectory, String projectName, Snapshot snapshot) {
|
public GitDirectoryContents(List<RawFile> files, File rootGitDirectory, String projectName, Snapshot snapshot) {
|
||||||
this.fileNodes = fileNodes;
|
this.files = files;
|
||||||
gitDirectory = new File(rootGitDirectory, projectName);
|
gitDirectory = new File(rootGitDirectory, projectName);
|
||||||
userName = snapshot.getUserName();
|
userName = snapshot.getUserName();
|
||||||
userEmail = snapshot.getUserEmail();
|
userEmail = snapshot.getUserEmail();
|
||||||
|
@ -33,9 +32,9 @@ public class GitDirectoryContents implements WritableRepositoryContents {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write() throws IOException, FailedConnectionException {
|
public void write() throws IOException {
|
||||||
WLFileStore.deleteInDirectoryApartFrom(gitDirectory, ".git");
|
WLFileStore.deleteInDirectoryApartFrom(gitDirectory, ".git");
|
||||||
for (FileNode fileNode : fileNodes) {
|
for (RawFile fileNode : files) {
|
||||||
fileNode.writeToDisk(gitDirectory);
|
fileNode.writeToDisk(gitDirectory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,22 +7,29 @@ import java.util.Map.Entry;
|
||||||
/**
|
/**
|
||||||
* Created by Winston on 16/11/14.
|
* Created by Winston on 16/11/14.
|
||||||
*/
|
*/
|
||||||
public class RepositoryFile implements RawFile {
|
public class RepositoryFile extends RawFile {
|
||||||
|
|
||||||
private final Entry<String, byte[]> fileContents;
|
private final String path;
|
||||||
|
private final byte[] contents;
|
||||||
|
|
||||||
public RepositoryFile(Entry<String, byte[]> fileContents) {
|
public RepositoryFile(Entry<String, byte[]> fileContents) {
|
||||||
this.fileContents = fileContents;
|
path = fileContents.getKey();
|
||||||
|
contents = fileContents.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public RepositoryFile(String path, byte[] contents) {
|
||||||
|
this.path = path;
|
||||||
|
this.contents = contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPath() {
|
public String getPath() {
|
||||||
return fileContents.getKey();
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] getContents() {
|
public byte[] getContents() {
|
||||||
return fileContents.getValue();
|
return contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
package uk.ac.ic.wlgitbridge.writelatex.filestore.blob;
|
|
||||||
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.node.FileNode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Winston on 14/11/14.
|
|
||||||
*/
|
|
||||||
public class AttachmentBlob extends ByteBlob {
|
|
||||||
|
|
||||||
public AttachmentBlob(FileNode fileNode) throws FailedConnectionException {
|
|
||||||
super(fileNode.getContents());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
package uk.ac.ic.wlgitbridge.writelatex.filestore.blob;
|
|
||||||
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.node.AttachmentNode;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreUpdater;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Winston on 14/11/14.
|
|
||||||
*/
|
|
||||||
public abstract class Blob implements PersistentStoreUpdater<AttachmentNode> {
|
|
||||||
|
|
||||||
public abstract byte[] getContents() throws FailedConnectionException;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (!(obj instanceof Blob)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Blob that = (Blob) obj;
|
|
||||||
try {
|
|
||||||
return Arrays.equals(getContents(), that.getContents());
|
|
||||||
} catch (FailedConnectionException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
package uk.ac.ic.wlgitbridge.writelatex.filestore.blob;
|
|
||||||
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.node.AttachmentNode;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreAPI;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Winston on 14/11/14.
|
|
||||||
*/
|
|
||||||
public class ByteBlob extends Blob {
|
|
||||||
|
|
||||||
private final byte[] contents;
|
|
||||||
|
|
||||||
public ByteBlob(byte[] contents) {
|
|
||||||
this.contents = contents;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getContents() {
|
|
||||||
return contents;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updatePersistentStore(PersistentStoreAPI persistentStore, AttachmentNode node) {
|
|
||||||
// persistentStore.addFileNodeBlob(node.getProjectName(), node.getFilePath(), node.isChanged(), contents);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
package uk.ac.ic.wlgitbridge.writelatex.filestore.blob;
|
|
||||||
|
|
||||||
import com.ning.http.client.AsyncCompletionHandler;
|
|
||||||
import com.ning.http.client.AsyncHttpClient;
|
|
||||||
import com.ning.http.client.HttpResponseBodyPart;
|
|
||||||
import com.ning.http.client.Response;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.node.AttachmentNode;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreAPI;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Winston on 14/11/14.
|
|
||||||
*/
|
|
||||||
public class ExternalBlob extends Blob {
|
|
||||||
|
|
||||||
private Future<byte[]> future;
|
|
||||||
|
|
||||||
public ExternalBlob(String url) throws FailedConnectionException {
|
|
||||||
super();
|
|
||||||
fetchContents(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getContents() throws FailedConnectionException {
|
|
||||||
try {
|
|
||||||
return future.get();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
throw new FailedConnectionException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void fetchContents(String url) throws FailedConnectionException {
|
|
||||||
AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
|
|
||||||
future = asyncHttpClient.prepareGet(url).execute(new AsyncCompletionHandler<byte[]>() {
|
|
||||||
|
|
||||||
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public STATE onBodyPartReceived(HttpResponseBodyPart bodyPart) throws Exception {
|
|
||||||
bytes.write(bodyPart.getBodyPartBytes());
|
|
||||||
return STATE.CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] onCompleted(Response response) throws Exception {
|
|
||||||
return bytes.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updatePersistentStore(PersistentStoreAPI persistentStore, AttachmentNode node) {
|
|
||||||
// persistentStore.addFileNodeExternal(node.getProjectName(), node.getFilePath(), node.isChanged(), node.getURL());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
package uk.ac.ic.wlgitbridge.writelatex.filestore.blob;
|
|
||||||
|
|
||||||
import uk.ac.ic.wlgitbridge.bridge.RawFile;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Winston on 14/11/14.
|
|
||||||
*/
|
|
||||||
public class RawFileBlob extends ByteBlob {
|
|
||||||
|
|
||||||
public RawFileBlob(RawFile rawFile) {
|
|
||||||
super(rawFile.getContents());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
package uk.ac.ic.wlgitbridge.writelatex.filestore.node;
|
|
||||||
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion.SnapshotAttachment;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.blob.AttachmentBlob;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.blob.Blob;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.blob.ByteBlob;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.blob.ExternalBlob;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.store.FileIndexStore;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreAPI;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Winston on 12/11/14.
|
|
||||||
*/
|
|
||||||
public class AttachmentNode extends FileNode {
|
|
||||||
|
|
||||||
private String projectName;
|
|
||||||
|
|
||||||
private final String url;
|
|
||||||
private Blob blob;
|
|
||||||
|
|
||||||
public AttachmentNode(SnapshotAttachment snapshotAttachment, Map<String, FileNode> context, FileIndexStore fileIndexes) throws FailedConnectionException {
|
|
||||||
super(snapshotAttachment, context);
|
|
||||||
url = snapshotAttachment.getUrl();
|
|
||||||
initBlob(fileIndexes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AttachmentNode(String filePath, boolean changed, String url, FileIndexStore fileIndexStore) {
|
|
||||||
super(filePath, changed);
|
|
||||||
this.url = url;
|
|
||||||
try {
|
|
||||||
initBlob(fileIndexStore);
|
|
||||||
} catch (FailedConnectionException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public AttachmentNode(String url, byte[] blob) {
|
|
||||||
super();
|
|
||||||
this.url = url;
|
|
||||||
this.blob = new ByteBlob(blob);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void indexWith(FileNodeIndexer fileNodeIndexer) {
|
|
||||||
fileNodeIndexer.index(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Blob getBlob() {
|
|
||||||
return blob;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updatePersistentStore(PersistentStoreAPI persistentStore, String projectName) {
|
|
||||||
this.projectName = projectName;
|
|
||||||
getBlob().updatePersistentStore(persistentStore, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getURL() {
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initBlob(FileIndexStore fileIndexes) throws FailedConnectionException {
|
|
||||||
if (fileIndexes.hasAttachmentWithURL(url)) {
|
|
||||||
FileNode attachment = fileIndexes.getAttachment(url);
|
|
||||||
blob = new AttachmentBlob(attachment);
|
|
||||||
} else {
|
|
||||||
blob = new ExternalBlob(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProjectName() {
|
|
||||||
return projectName;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -3,10 +3,6 @@ package uk.ac.ic.wlgitbridge.writelatex.filestore.node;
|
||||||
import uk.ac.ic.wlgitbridge.bridge.RawFile;
|
import uk.ac.ic.wlgitbridge.bridge.RawFile;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.RepositoryFile;
|
import uk.ac.ic.wlgitbridge.writelatex.filestore.RepositoryFile;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.blob.Blob;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.blob.ByteBlob;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.blob.RawFileBlob;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreAPI;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -15,48 +11,43 @@ import java.util.Map;
|
||||||
/**
|
/**
|
||||||
* Created by Winston on 12/11/14.
|
* Created by Winston on 12/11/14.
|
||||||
*/
|
*/
|
||||||
public class BlobNode extends FileNode {
|
public class BlobNode /*extends FileNode*/ {
|
||||||
|
|
||||||
private ByteBlob blob;
|
// private ByteBlob blob;
|
||||||
|
|
||||||
public BlobNode(RawFile rawFile, Map<String, FileNode> context) {
|
public BlobNode(RawFile rawFile, Map<String, FileNode> context) {
|
||||||
super(rawFile, context);
|
// super(rawFile, context);
|
||||||
blob = new RawFileBlob(rawFile);
|
// blob = new RawFileBlob(rawFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlobNode(RepositoryFile repositoryFile, Map<String, FileNode> fileNodeTable, File projectAttDirectory) throws IOException, FailedConnectionException {
|
public BlobNode(RepositoryFile repositoryFile, Map<String, FileNode> fileNodeTable, File projectAttDirectory) throws IOException, FailedConnectionException {
|
||||||
this(repositoryFile, fileNodeTable);
|
this(repositoryFile, fileNodeTable);
|
||||||
blob = new RawFileBlob(repositoryFile);
|
// blob = new RawFileBlob(repositoryFile);
|
||||||
writeChanged(projectAttDirectory);
|
writeChanged(projectAttDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlobNode(String fileName, boolean changed, byte[] blob) {
|
public BlobNode(String fileName, boolean changed, byte[] blob) {
|
||||||
super(fileName, changed);
|
// super(fileName, changed);
|
||||||
this.blob = new ByteBlob(blob);
|
// this.blob = new ByteBlob(blob);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public void indexWith(FileNodeIndexer fileNodeIndexer) {
|
// protected Blob getBlob() {
|
||||||
fileNodeIndexer.index(this);
|
// return blob;
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
protected Blob getBlob() {
|
// public void updatePersistentStore(PersistentStoreAPI persistentStore, String projectName) {
|
||||||
return blob;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updatePersistentStore(PersistentStoreAPI persistentStore, String projectName) {
|
|
||||||
// try {
|
// try {
|
||||||
// persistentStore.addFileNodeBlob(projectName, getFilePath(), isChanged(), getBlob().getContents());
|
// persistentStore.addFileNodeBlob(projectName, getFilePath(), isChanged(), getBlob().getContents());
|
||||||
// } catch (FailedConnectionException e) {
|
// } catch (FailedConnectionException e) {
|
||||||
// throw new RuntimeException(e);
|
// throw new RuntimeException(e);
|
||||||
// }
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
private void writeChanged(File projectAttDirectory) throws FailedConnectionException, IOException {
|
private void writeChanged(File projectAttDirectory) throws FailedConnectionException, IOException {
|
||||||
if (isChanged()) {
|
// if (isChanged()) {
|
||||||
writeToDisk(projectAttDirectory);
|
// writeToDisk(projectAttDirectory);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package uk.ac.ic.wlgitbridge.writelatex.filestore.node;
|
||||||
|
|
||||||
import uk.ac.ic.wlgitbridge.bridge.RawFile;
|
import uk.ac.ic.wlgitbridge.bridge.RawFile;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.blob.Blob;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreUpdater;
|
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreUpdater;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -41,7 +40,8 @@ public abstract class FileNode implements PersistentStoreUpdater<String> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getContents() throws FailedConnectionException {
|
public byte[] getContents() throws FailedConnectionException {
|
||||||
return getBlob().getContents();
|
// return getBlob().getContents();
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeToDisk(File directory) throws FailedConnectionException, IOException {
|
public void writeToDisk(File directory) throws FailedConnectionException, IOException {
|
||||||
|
@ -61,17 +61,16 @@ public abstract class FileNode implements PersistentStoreUpdater<String> {
|
||||||
return changed || previous == null || !equals(previous);
|
return changed || previous == null || !equals(previous);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void indexWith(FileNodeIndexer indexer);
|
// protected abstract Blob getBlob();
|
||||||
protected abstract Blob getBlob();
|
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public boolean equals(Object obj) {
|
// public boolean equals(Object obj) {
|
||||||
if (!(obj instanceof FileNode)) {
|
// if (!(obj instanceof FileNode)) {
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
FileNode that = (FileNode) obj;
|
// FileNode that = (FileNode) obj;
|
||||||
return filePath.equals(that.filePath) && getBlob().equals(that.getBlob());
|
// return filePath.equals(that.filePath) && getBlob().equals(that.getBlob());
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
package uk.ac.ic.wlgitbridge.writelatex.filestore.node;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Winston on 14/11/14.
|
|
||||||
*/
|
|
||||||
public interface FileNodeIndexer {
|
|
||||||
|
|
||||||
public void index(BlobNode blobNode);
|
|
||||||
public void index(AttachmentNode attachmentNode);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,72 +1,56 @@
|
||||||
package uk.ac.ic.wlgitbridge.writelatex.filestore.node;
|
package uk.ac.ic.wlgitbridge.writelatex.filestore.node;
|
||||||
|
|
||||||
import uk.ac.ic.wlgitbridge.bridge.RawDirectoryContents;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion.SnapshotAttachment;
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion.SnapshotAttachment;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion.SnapshotFile;
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion.SnapshotFile;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.RepositoryFile;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.store.FileIndexStore;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.store.WLFileStore;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.Snapshot;
|
import uk.ac.ic.wlgitbridge.writelatex.model.Snapshot;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreAPI;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreSource;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreUpdater;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Winston on 08/11/14.
|
* Created by Winston on 08/11/14.
|
||||||
*/
|
*/
|
||||||
public class WLDirectoryNode implements PersistentStoreSource, PersistentStoreUpdater<Void> {
|
public class WLDirectoryNode /*implements PersistentStoreSource, PersistentStoreUpdater<Void>*/ {
|
||||||
|
|
||||||
private final String projectName;
|
// private final String projectName;
|
||||||
private Map<String, FileNode> fileNodeTable;
|
private Map<String, FileNode> fileNodeTable;
|
||||||
private FileIndexStore fileIndexStore;
|
|
||||||
|
|
||||||
public WLDirectoryNode(String projectName, File attsDirectory, File rootGitDirectory, PersistentStoreAPI persistentStore) {
|
// public WLDirectoryNode(String projectName, File attsDirectory, File rootGitDirectory, PersistentStoreAPI persistentStore) {
|
||||||
this(projectName, attsDirectory, rootGitDirectory);
|
// this(projectName, attsDirectory, rootGitDirectory);
|
||||||
initFromPersistentStore(persistentStore);
|
// initFromPersistentStore(persistentStore);
|
||||||
}
|
// }
|
||||||
|
|
||||||
private WLDirectoryNode(String projectName, File attsDirectory, File rootGitDirectory) {
|
private WLDirectoryNode(String projectName, File attsDirectory, File rootGitDirectory) {
|
||||||
this.projectName = projectName;
|
// this.projectName = projectName;
|
||||||
new File(attsDirectory, projectName).mkdirs();
|
new File(attsDirectory, projectName).mkdirs();
|
||||||
new File(rootGitDirectory, projectName).mkdirs();
|
new File(rootGitDirectory, projectName).mkdirs();
|
||||||
}
|
}
|
||||||
|
|
||||||
private WLDirectoryNode(String projectName, Map<String, FileNode> fileNodeTable, FileIndexStore fileIndexStore) {
|
// @Override
|
||||||
this.projectName = projectName;
|
// public void initFromPersistentStore(PersistentStoreAPI persistentStore) {
|
||||||
this.fileNodeTable = fileNodeTable;
|
// fileIndexStore = new FileIndexStore(projectName, persistentStore);
|
||||||
this.fileIndexStore = fileIndexStore;
|
// fileNodeTable = new HashMap<String, FileNode>();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initFromPersistentStore(PersistentStoreAPI persistentStore) {
|
|
||||||
fileIndexStore = new FileIndexStore(projectName, persistentStore);
|
|
||||||
fileNodeTable = new HashMap<String, FileNode>();
|
|
||||||
// for (FileNode fileNode : persistentStore.getFileNodesForProjectName(projectName, fileIndexStore)) {
|
// for (FileNode fileNode : persistentStore.getFileNodesForProjectName(projectName, fileIndexStore)) {
|
||||||
// fileNodeTable.put(fileNode.getFilePath(), fileNode);
|
// fileNodeTable.put(fileNode.getFilePath(), fileNode);
|
||||||
// }
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public void updatePersistentStore(PersistentStoreAPI persistentStore, Void info) {
|
// public void updatePersistentStore(PersistentStoreAPI persistentStore, Void info) {
|
||||||
updateFileNodeTableInPersistentStore(persistentStore);
|
// updateFileNodeTableInPersistentStore(persistentStore);
|
||||||
fileIndexStore.updatePersistentStore(persistentStore, projectName);
|
// fileIndexStore.updatePersistentStore(persistentStore, projectName);
|
||||||
}
|
// }
|
||||||
|
|
||||||
private void updateFileNodeTableInPersistentStore(PersistentStoreAPI persistentStore) {
|
// private void updateFileNodeTableInPersistentStore(PersistentStoreAPI persistentStore) {
|
||||||
// persistentStore.deleteFileNodesForProjectName(projectName);
|
// persistentStore.deleteFileNodesForProjectName(projectName);
|
||||||
for (FileNode fileNode : fileNodeTable.values()) {
|
// for (FileNode fileNode : fileNodeTable.values()) {
|
||||||
fileNode.updatePersistentStore(persistentStore, projectName);
|
// fileNode.updatePersistentStore(persistentStore, projectName);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
public List<FileNode> getFileNodes() {
|
public List<FileNode> getFileNodes() {
|
||||||
return new LinkedList<FileNode>(fileNodeTable.values());
|
return new LinkedList<FileNode>(fileNodeTable.values());
|
||||||
|
@ -78,34 +62,33 @@ public class WLDirectoryNode implements PersistentStoreSource, PersistentStoreUp
|
||||||
List<SnapshotAttachment> atts = snapshot.getAtts();
|
List<SnapshotAttachment> atts = snapshot.getAtts();
|
||||||
for (SnapshotFile src : srcs) {
|
for (SnapshotFile src : srcs) {
|
||||||
BlobNode blobNode = new BlobNode(src, fileNodeTable);
|
BlobNode blobNode = new BlobNode(src, fileNodeTable);
|
||||||
updatedFileNodeTable.put(blobNode.getFilePath(), blobNode);
|
// updatedFileNodeTable.put(blobNode.getFilePath(), blobNode);
|
||||||
}
|
}
|
||||||
for (SnapshotAttachment att : atts) {
|
for (SnapshotAttachment att : atts) {
|
||||||
AttachmentNode attachmentNode = new AttachmentNode(att, fileNodeTable, fileIndexStore);
|
// AttachmentNode attachmentNode = new AttachmentNode(att, fileNodeTable, fileIndexStore);
|
||||||
updatedFileNodeTable.put(attachmentNode.getFilePath(), attachmentNode);
|
// updatedFileNodeTable.put(attachmentNode.getFilePath(), attachmentNode);
|
||||||
}
|
}
|
||||||
LinkedList<FileNode> fileNodes = new LinkedList<FileNode>(updatedFileNodeTable.values());
|
LinkedList<FileNode> fileNodes = new LinkedList<FileNode>(updatedFileNodeTable.values());
|
||||||
fileNodeTable = updatedFileNodeTable;
|
fileNodeTable = updatedFileNodeTable;
|
||||||
fileIndexStore = new FileIndexStore(fileNodes);
|
|
||||||
return fileNodes;
|
return fileNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WLDirectoryNode createFromRawDirectoryContents(RawDirectoryContents rawDirectoryContents, File attachmentDirectory) throws IOException, FailedConnectionException {
|
// public WLDirectoryNode createFromRawDirectoryContents(RawDirectoryContents rawDirectoryContents, File attachmentDirectory) throws IOException, FailedConnectionException {
|
||||||
Map<String, FileNode> candidateFileNodeTable = new HashMap<String, FileNode>();
|
// Map<String, FileNode> candidateFileNodeTable = new HashMap<String, FileNode>();
|
||||||
File projectAttDirectory = new File(attachmentDirectory, projectName);
|
// File projectAttDirectory = new File(attachmentDirectory, projectName);
|
||||||
projectAttDirectory.mkdirs();
|
// projectAttDirectory.mkdirs();
|
||||||
WLFileStore.deleteInDirectory(projectAttDirectory);
|
// WLFileStore.deleteInDirectory(projectAttDirectory);
|
||||||
for (Entry<String, byte[]> fileContents : rawDirectoryContents.getFileContentsTable().entrySet()) {
|
// for (Entry<String, byte[]> fileContents : rawDirectoryContents.getFileContentsTable().entrySet()) {
|
||||||
BlobNode blobNode = new BlobNode(new RepositoryFile(fileContents), fileNodeTable, projectAttDirectory);
|
// BlobNode blobNode = new BlobNode(new RepositoryFile(fileContents), fileNodeTable, projectAttDirectory);
|
||||||
candidateFileNodeTable.put(blobNode.getFilePath(), blobNode);
|
// candidateFileNodeTable.put(blobNode.getFilePath(), blobNode);
|
||||||
}
|
// }
|
||||||
return new WLDirectoryNode(projectName, candidateFileNodeTable,
|
// return new WLDirectoryNode(projectName, candidateFileNodeTable,
|
||||||
new FileIndexStore(new LinkedList<FileNode>(candidateFileNodeTable.values())));
|
// new FileIndexStore(new LinkedList<FileNode>(candidateFileNodeTable.values())));
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public String toString() {
|
// public String toString() {
|
||||||
return fileNodeTable.toString();
|
// return fileNodeTable.toString();
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
package uk.ac.ic.wlgitbridge.writelatex.filestore.store;
|
|
||||||
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.node.AttachmentNode;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.node.BlobNode;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.node.FileNode;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.node.FileNodeIndexer;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreAPI;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreSource;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreUpdater;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Winston on 08/11/14.
|
|
||||||
*/
|
|
||||||
public class FileIndexStore implements FileNodeIndexer, PersistentStoreSource, PersistentStoreUpdater<String> {
|
|
||||||
|
|
||||||
private final Map<BlobHash, FileNode> blobHashMappings;
|
|
||||||
private Map<String, FileNode> urlMappings;
|
|
||||||
|
|
||||||
private String projectName;
|
|
||||||
|
|
||||||
public FileIndexStore(List<FileNode> fileNodes) {
|
|
||||||
blobHashMappings = new HashMap<BlobHash, FileNode>();
|
|
||||||
urlMappings = new HashMap<String, FileNode>();
|
|
||||||
for (FileNode fileNode : fileNodes) {
|
|
||||||
fileNode.indexWith(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public FileIndexStore(String projectName, PersistentStoreAPI persistentStore) {
|
|
||||||
this.projectName = projectName;
|
|
||||||
blobHashMappings = new HashMap<BlobHash, FileNode>();
|
|
||||||
initFromPersistentStore(persistentStore);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void index(BlobNode blobNode) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void index(AttachmentNode attachmentNode) {
|
|
||||||
urlMappings.put(attachmentNode.getURL(), attachmentNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initFromPersistentStore(PersistentStoreAPI persistentStore) {
|
|
||||||
// urlMappings = persistentStore.getURLIndexTableForProjectName(projectName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasAttachmentWithURL(String url) {
|
|
||||||
return urlMappings.containsKey(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
public FileNode getAttachment(String url) {
|
|
||||||
return urlMappings.get(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updatePersistentStore(PersistentStoreAPI persistentStore, String projectName) {
|
|
||||||
// persistentStore.deleteURLIndexesForProjectName(projectName);
|
|
||||||
for (Entry<String, FileNode> urlMapping : urlMappings.entrySet()) {
|
|
||||||
// try {
|
|
||||||
// persistentStore.addURLIndex(projectName, urlMapping.getKey(), urlMapping.getValue().getContents());
|
|
||||||
// } catch (FailedConnectionException e) {
|
|
||||||
// throw new RuntimeException(e);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Winston is really cool
|
|
||||||
and he's a cat
|
|
||||||
meow
|
|
||||||
miaow
|
|
||||||
meaaaoowww
|
|
||||||
=^.^=
|
|
||||||
*/
|
|
|
@ -1,31 +1,21 @@
|
||||||
package uk.ac.ic.wlgitbridge.writelatex.filestore.store;
|
package uk.ac.ic.wlgitbridge.writelatex.filestore.store;
|
||||||
|
|
||||||
import uk.ac.ic.wlgitbridge.bridge.CandidateSnapshot;
|
import uk.ac.ic.wlgitbridge.bridge.CandidateSnapshot;
|
||||||
import uk.ac.ic.wlgitbridge.bridge.RawDirectoryContents;
|
|
||||||
import uk.ac.ic.wlgitbridge.bridge.WritableRepositoryContents;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.exception.InvalidProjectException;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.GitDirectoryContents;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.node.WLDirectoryNode;
|
import uk.ac.ic.wlgitbridge.writelatex.filestore.node.WLDirectoryNode;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.Snapshot;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.WLProject;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreAPI;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreSource;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Winston on 08/11/14.
|
* Created by Winston on 08/11/14.
|
||||||
*/
|
*/
|
||||||
public class WLFileStore implements PersistentStoreSource {
|
public class WLFileStore /*implements PersistentStoreSource*/ {
|
||||||
|
|
||||||
private final Map<String, WLDirectoryNode> fileStore;
|
private final Map<String, WLDirectoryNode> fileStore;
|
||||||
private final File rootGitDirectory;
|
private final File rootGitDirectory;
|
||||||
private final File attDirectory;
|
private final File attDirectory;
|
||||||
|
|
||||||
private PersistentStoreAPI persistentStore;
|
// private PersistentStoreAPI persistentStore;
|
||||||
|
|
||||||
public WLFileStore(File rootGitDirectory) {
|
public WLFileStore(File rootGitDirectory) {
|
||||||
fileStore = new HashMap<String, WLDirectoryNode>();
|
fileStore = new HashMap<String, WLDirectoryNode>();
|
||||||
|
@ -34,18 +24,18 @@ public class WLFileStore implements PersistentStoreSource {
|
||||||
attDirectory.mkdirs();
|
attDirectory.mkdirs();
|
||||||
}
|
}
|
||||||
|
|
||||||
public WLFileStore(File rootGitDirectory, PersistentStoreAPI persistentStoreAPI) {
|
// public WLFileStore(File rootGitDirectory, PersistentStoreAPI persistentStoreAPI) {
|
||||||
this(rootGitDirectory);
|
// this(rootGitDirectory);
|
||||||
initFromPersistentStore(persistentStoreAPI);
|
// initFromPersistentStore(persistentStoreAPI);
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public void initFromPersistentStore(PersistentStoreAPI persistentStore) {
|
// public void initFromPersistentStore(PersistentStoreAPI persistentStore) {
|
||||||
this.persistentStore = persistentStore;
|
// this.persistentStore = persistentStore;
|
||||||
// for (String projectName : persistentStore.getProjectNames()) {
|
// for (String projectName : persistentStore.getProjectNames()) {
|
||||||
// fileStore.put(projectName, new WLDirectoryNode(projectName, attDirectory, rootGitDirectory, persistentStore));
|
// fileStore.put(projectName, new WLDirectoryNode(projectName, attDirectory, rootGitDirectory, persistentStore));
|
||||||
// }
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
public static void deleteInDirectory(File directory) {
|
public static void deleteInDirectory(File directory) {
|
||||||
deleteInDirectoryApartFrom(directory);
|
deleteInDirectoryApartFrom(directory);
|
||||||
|
@ -63,36 +53,36 @@ public class WLFileStore implements PersistentStoreSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<WritableRepositoryContents> updateForProject(WLProject project) throws FailedConnectionException,
|
// public List<WritableRepositoryContents> updateForProject(WLProject project) throws FailedConnectionException,
|
||||||
InvalidProjectException {
|
// InvalidProjectException {
|
||||||
SortedSet<Snapshot> snapshots = project.fetchNewSnapshots();
|
// SortedSet<Snapshot> snapshots = project.fetchNewSnapshots();
|
||||||
String projectName = project.getName();
|
// String projectName = project.getName();
|
||||||
WLDirectoryNode directoryNode = getDirectoryNodeForProjectName(projectName);
|
// WLDirectoryNode directoryNode = getDirectoryNodeForProjectName(projectName);
|
||||||
List<WritableRepositoryContents> writableRepositories = new LinkedList<WritableRepositoryContents>();
|
// List<WritableRepositoryContents> writableRepositories = new LinkedList<WritableRepositoryContents>();
|
||||||
for (Snapshot snapshot : snapshots) {
|
// for (Snapshot snapshot : snapshots) {
|
||||||
writableRepositories.add(new GitDirectoryContents(directoryNode.updateFromSnapshot(snapshot),
|
// writableRepositories.add(new GitDirectoryContents(directoryNode.updateFromSnapshot(snapshot),
|
||||||
rootGitDirectory,
|
// rootGitDirectory,
|
||||||
projectName,
|
// projectName,
|
||||||
snapshot));
|
// snapshot));
|
||||||
}
|
// }
|
||||||
directoryNode.updatePersistentStore(persistentStore, null);
|
// directoryNode.updatePersistentStore(persistentStore, null);
|
||||||
return writableRepositories;
|
// return writableRepositories;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public WLDirectoryNode createNextDirectoryNodeInProjectFromContents(WLProject project, RawDirectoryContents directoryContents) throws IOException, FailedConnectionException {
|
// public WLDirectoryNode createNextDirectoryNodeInProjectFromContents(WLProject project, RawDirectoryContents directoryContents) throws IOException, FailedConnectionException {
|
||||||
return getDirectoryNodeForProjectName(project.getName()).createFromRawDirectoryContents(directoryContents, attDirectory);
|
// return getDirectoryNodeForProjectName(project.getName()).createFromRawDirectoryContents(directoryContents, attDirectory);
|
||||||
}
|
// }
|
||||||
|
|
||||||
public void approveCandidateSnapshot(CandidateSnapshot candidateSnapshot) {
|
public void approveCandidateSnapshot(CandidateSnapshot candidateSnapshot) {
|
||||||
WLDirectoryNode directoryNode = candidateSnapshot.getDirectoryNode();
|
WLDirectoryNode directoryNode = candidateSnapshot.getDirectoryNode();
|
||||||
fileStore.put(candidateSnapshot.getProjectName(), directoryNode);
|
fileStore.put(candidateSnapshot.getProjectName(), directoryNode);
|
||||||
directoryNode.updatePersistentStore(persistentStore, null);
|
// directoryNode.updatePersistentStore(persistentStore, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private WLDirectoryNode getDirectoryNodeForProjectName(String projectName) {
|
private WLDirectoryNode getDirectoryNodeForProjectName(String projectName) {
|
||||||
WLDirectoryNode directoryNode = fileStore.get(projectName);
|
WLDirectoryNode directoryNode = fileStore.get(projectName);
|
||||||
if (directoryNode == null) {
|
if (directoryNode == null) {
|
||||||
directoryNode = new WLDirectoryNode(projectName, attDirectory, rootGitDirectory, persistentStore);
|
// directoryNode = new WLDirectoryNode(projectName, attDirectory, rootGitDirectory, persistentStore);
|
||||||
fileStore.put(projectName, directoryNode);
|
fileStore.put(projectName, directoryNode);
|
||||||
}
|
}
|
||||||
return directoryNode;
|
return directoryNode;
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
package uk.ac.ic.wlgitbridge.writelatex.model;
|
||||||
|
|
||||||
|
import org.eclipse.jgit.lib.Repository;
|
||||||
|
import uk.ac.ic.wlgitbridge.bridge.*;
|
||||||
|
import uk.ac.ic.wlgitbridge.writelatex.SnapshotFetcher;
|
||||||
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
|
||||||
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion.SnapshotAttachment;
|
||||||
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.SnapshotPostException;
|
||||||
|
import uk.ac.ic.wlgitbridge.writelatex.filestore.GitDirectoryContents;
|
||||||
|
import uk.ac.ic.wlgitbridge.writelatex.filestore.store.WLFileStore;
|
||||||
|
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStore;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Winston on 06/11/14.
|
||||||
|
*/
|
||||||
|
public class DataStore implements CandidateSnapshotCallback {
|
||||||
|
|
||||||
|
private final File rootGitDirectory;
|
||||||
|
private final PersistentStore persistentStore;
|
||||||
|
private final SnapshotFetcher snapshotFetcher;
|
||||||
|
private final ResourceFetcher resourceFetcher;
|
||||||
|
|
||||||
|
public DataStore(String rootGitDirectoryPath) {
|
||||||
|
rootGitDirectory = initRootGitDirectory(rootGitDirectoryPath);
|
||||||
|
persistentStore = new PersistentStore(rootGitDirectory);
|
||||||
|
List<String> excludedFromDeletion = persistentStore.getProjectNames();
|
||||||
|
excludedFromDeletion.add(".wlgb");
|
||||||
|
WLFileStore.deleteInDirectoryApartFrom(rootGitDirectory, excludedFromDeletion.toArray(new String[] {}));
|
||||||
|
|
||||||
|
snapshotFetcher = new SnapshotFetcher();
|
||||||
|
resourceFetcher = new ResourceFetcher(persistentStore);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<WritableRepositoryContents> updateProjectWithName(String name, Repository repository) throws IOException, SnapshotPostException {
|
||||||
|
List<Snapshot> snapshots = snapshotFetcher.getSnapshotsForProjectAfterVersion(name, persistentStore.getLatestVersionForProject(name));
|
||||||
|
List<WritableRepositoryContents> commits = makeCommitsFromSnapshots(name, repository, snapshots);
|
||||||
|
return commits;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<WritableRepositoryContents> makeCommitsFromSnapshots(String name, Repository repository, List<Snapshot> snapshots) throws IOException {
|
||||||
|
List<WritableRepositoryContents> commits = new LinkedList<WritableRepositoryContents>();
|
||||||
|
for (Snapshot snapshot : snapshots) {
|
||||||
|
List<RawFile> files = new LinkedList<RawFile>();
|
||||||
|
files.addAll(snapshot.getSrcs());
|
||||||
|
for (SnapshotAttachment snapshotAttachment : snapshot.getAtts()) {
|
||||||
|
files.add(resourceFetcher.get(name, snapshotAttachment.getUrl(), snapshotAttachment.getPath(), repository));
|
||||||
|
}
|
||||||
|
commits.add(new GitDirectoryContents(files, rootGitDirectory, name, snapshot));
|
||||||
|
}
|
||||||
|
return commits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CandidateSnapshot createCandidateSnapshotFromProjectWithContents(String projectName, RawDirectoryContents directoryContents, String hostname, String postbackKey) throws SnapshotPostException, IOException, FailedConnectionException {
|
||||||
|
// return new WLDirectoryNodeSnapshot(getProjectWithName(projectName),
|
||||||
|
// fileStore.createNextDirectoryNodeInProjectFromContents(getProjectWithName(projectName),
|
||||||
|
// directoryContents),
|
||||||
|
// hostname,
|
||||||
|
// postbackKey,
|
||||||
|
// this);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void approveSnapshot(int versionID, CandidateSnapshot candidateSnapshot) {
|
||||||
|
// getProjectWithName(candidateSnapshot.getProjectName()).putLatestSnapshot(versionID);
|
||||||
|
// fileStore.approveCandidateSnapshot(candidateSnapshot);
|
||||||
|
}
|
||||||
|
|
||||||
|
private File initRootGitDirectory(String rootGitDirectoryPath) {
|
||||||
|
File rootGitDirectory = new File(rootGitDirectoryPath);
|
||||||
|
rootGitDirectory.mkdirs();
|
||||||
|
return rootGitDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package uk.ac.ic.wlgitbridge.writelatex.model;
|
||||||
|
|
||||||
|
import com.ning.http.client.AsyncCompletionHandler;
|
||||||
|
import com.ning.http.client.AsyncHttpClient;
|
||||||
|
import com.ning.http.client.HttpResponseBodyPart;
|
||||||
|
import com.ning.http.client.Response;
|
||||||
|
import org.eclipse.jgit.lib.Repository;
|
||||||
|
import uk.ac.ic.wlgitbridge.bridge.RawFile;
|
||||||
|
import uk.ac.ic.wlgitbridge.git.util.RepositoryObjectTreeWalker;
|
||||||
|
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
|
||||||
|
import uk.ac.ic.wlgitbridge.writelatex.filestore.RepositoryFile;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Winston on 21/02/15.
|
||||||
|
*/
|
||||||
|
public class ResourceFetcher {
|
||||||
|
|
||||||
|
private final URLIndexStore urlIndexStore;
|
||||||
|
|
||||||
|
public ResourceFetcher(URLIndexStore urlIndexStore) {
|
||||||
|
this.urlIndexStore = urlIndexStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RawFile get(String projectName, String url, String newPath, Repository repository) throws IOException {
|
||||||
|
String path = urlIndexStore.getPathForURLInProject(projectName, url);
|
||||||
|
byte[] contents;
|
||||||
|
if (path == null) {
|
||||||
|
path = newPath;
|
||||||
|
contents = fetch(projectName, url, path);
|
||||||
|
} else {
|
||||||
|
contents = new RepositoryObjectTreeWalker(repository).getDirectoryContents().getFileContentsTable().get(path);
|
||||||
|
}
|
||||||
|
return new RepositoryFile(path, contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] fetch(String projectName, String url, String path) throws FailedConnectionException {
|
||||||
|
byte[] contents;
|
||||||
|
try {
|
||||||
|
contents = new AsyncHttpClient().prepareGet(url).execute(new AsyncCompletionHandler<byte[]>() {
|
||||||
|
|
||||||
|
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public STATE onBodyPartReceived(HttpResponseBodyPart bodyPart) throws Exception {
|
||||||
|
bytes.write(bodyPart.getBodyPartBytes());
|
||||||
|
return STATE.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] onCompleted(Response response) throws Exception {
|
||||||
|
return bytes.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
}).get();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new FailedConnectionException();
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
throw new FailedConnectionException();
|
||||||
|
}
|
||||||
|
urlIndexStore.addURLIndexForProject(projectName, url, path);
|
||||||
|
return contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package uk.ac.ic.wlgitbridge.writelatex.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Winston on 21/02/15.
|
||||||
|
*/
|
||||||
|
public interface URLIndexStore {
|
||||||
|
|
||||||
|
public void addURLIndexForProject(String projectName, String url, String path);
|
||||||
|
public String getPathForURLInProject(String projectName, String url);
|
||||||
|
|
||||||
|
}
|
|
@ -1,70 +0,0 @@
|
||||||
package uk.ac.ic.wlgitbridge.writelatex.model;
|
|
||||||
|
|
||||||
import uk.ac.ic.wlgitbridge.bridge.CandidateSnapshot;
|
|
||||||
import uk.ac.ic.wlgitbridge.bridge.CandidateSnapshotCallback;
|
|
||||||
import uk.ac.ic.wlgitbridge.bridge.RawDirectoryContents;
|
|
||||||
import uk.ac.ic.wlgitbridge.bridge.WritableRepositoryContents;
|
|
||||||
import uk.ac.ic.wlgitbridge.util.Util;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.WLDirectoryNodeSnapshot;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.exception.InvalidProjectException;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.SnapshotPostException;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.filestore.store.WLFileStore;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreAPI;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStore;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Winston on 06/11/14.
|
|
||||||
*/
|
|
||||||
public class WLDataModel implements CandidateSnapshotCallback {
|
|
||||||
|
|
||||||
private final PersistentStoreAPI persistentStore;
|
|
||||||
private final WLProjectStore projectStore;
|
|
||||||
private final WLFileStore fileStore;
|
|
||||||
|
|
||||||
public WLDataModel(String rootGitDirectoryPath) {
|
|
||||||
File rootGitDirectory = initRootGitDirectory(rootGitDirectoryPath);
|
|
||||||
persistentStore = new PersistentStore(rootGitDirectory);
|
|
||||||
projectStore = null;//persistentStore.loadProjectStore();
|
|
||||||
Util.sout("Loaded projects: " + projectStore.getProjectNames().size() + ".");
|
|
||||||
fileStore = null;//persistentStore.loadFileStore();
|
|
||||||
Util.sout("Loaded file store and index tables.");
|
|
||||||
List<String> excludedFromDeletion = projectStore.getProjectNames();
|
|
||||||
excludedFromDeletion.add(".wlgb");
|
|
||||||
WLFileStore.deleteInDirectoryApartFrom(rootGitDirectory, excludedFromDeletion.toArray(new String[] {}));
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<WritableRepositoryContents> updateProjectWithName(String name) throws FailedConnectionException, InvalidProjectException {
|
|
||||||
return fileStore.updateForProject(getProjectWithName(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
public WLProject getProjectWithName(String name) {
|
|
||||||
return projectStore.getProjectWithName(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CandidateSnapshot createCandidateSnapshotFromProjectWithContents(String projectName, RawDirectoryContents directoryContents, String hostname, String postbackKey) throws SnapshotPostException, IOException, FailedConnectionException {
|
|
||||||
return new WLDirectoryNodeSnapshot(getProjectWithName(projectName),
|
|
||||||
fileStore.createNextDirectoryNodeInProjectFromContents(getProjectWithName(projectName),
|
|
||||||
directoryContents),
|
|
||||||
hostname,
|
|
||||||
postbackKey,
|
|
||||||
this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void approveSnapshot(int versionID, CandidateSnapshot candidateSnapshot) {
|
|
||||||
getProjectWithName(candidateSnapshot.getProjectName()).putLatestSnapshot(versionID);
|
|
||||||
fileStore.approveCandidateSnapshot(candidateSnapshot);
|
|
||||||
}
|
|
||||||
|
|
||||||
private File initRootGitDirectory(String rootGitDirectoryPath) {
|
|
||||||
File rootGitDirectory = new File(rootGitDirectoryPath);
|
|
||||||
rootGitDirectory.mkdirs();
|
|
||||||
return rootGitDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
package uk.ac.ic.wlgitbridge.writelatex.model;
|
|
||||||
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.SnapshotFetcher;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.exception.InvalidProjectException;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreAPI;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreSource;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.SortedSet;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Winston on 06/11/14.
|
|
||||||
*/
|
|
||||||
public class WLProject implements PersistentStoreSource {
|
|
||||||
|
|
||||||
public static final int INVALID_VERSION_ID = -1;
|
|
||||||
private final String name;
|
|
||||||
private final Map<Integer, Snapshot> snapshots;
|
|
||||||
private final SnapshotFetcher snapshotFetcher;
|
|
||||||
|
|
||||||
private int latestSnapshotID;
|
|
||||||
private PersistentStoreAPI persistentStore;
|
|
||||||
|
|
||||||
public WLProject(String name) {
|
|
||||||
this.name = name;
|
|
||||||
snapshots = new HashMap<Integer, Snapshot>();
|
|
||||||
snapshotFetcher = new SnapshotFetcher(name, snapshots);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WLProject(String projectName, PersistentStoreAPI database) {
|
|
||||||
this(projectName);
|
|
||||||
initFromPersistentStore(database);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SortedSet<Snapshot> fetchNewSnapshots() throws FailedConnectionException, InvalidProjectException {
|
|
||||||
SortedSet<Snapshot> newSnapshots = snapshotFetcher.fetchNewSnapshots();
|
|
||||||
updateLatestSnapshot();
|
|
||||||
return newSnapshots;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLatestSnapshotID() {
|
|
||||||
return latestSnapshotID;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateLatestSnapshot() {
|
|
||||||
Snapshot latest = snapshotFetcher.getLatestSnapshot();
|
|
||||||
if (latest == null) {
|
|
||||||
latestSnapshotID = INVALID_VERSION_ID;
|
|
||||||
} else {
|
|
||||||
latestSnapshotID = latest.getVersionID();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void putLatestSnapshot(int versionID) {
|
|
||||||
snapshots.put(versionID, new Snapshot(versionID));
|
|
||||||
snapshotFetcher.putLatestVersion(versionID);
|
|
||||||
latestSnapshotID = versionID;
|
|
||||||
// persistentStore.addSnapshot(name, versionID);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initFromPersistentStore(PersistentStoreAPI persistentStore) {
|
|
||||||
this.persistentStore = persistentStore;
|
|
||||||
snapshotFetcher.initFromPersistentStore(persistentStore);
|
|
||||||
updateLatestSnapshot();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
package uk.ac.ic.wlgitbridge.writelatex.model;
|
|
||||||
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreAPI;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreSource;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Winston on 17/11/14.
|
|
||||||
*/
|
|
||||||
public class WLProjectStore implements PersistentStoreSource {
|
|
||||||
|
|
||||||
private PersistentStoreAPI persistentStore;
|
|
||||||
private final Map<String, WLProject> projects;
|
|
||||||
|
|
||||||
public WLProjectStore() {
|
|
||||||
projects = new HashMap<String, WLProject>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public WLProjectStore(PersistentStoreAPI persistentStore) {
|
|
||||||
this();
|
|
||||||
initFromPersistentStore(persistentStore);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WLProject getProjectWithName(String name) {
|
|
||||||
WLProject project;
|
|
||||||
if (projects.containsKey(name)) {
|
|
||||||
project = projects.get(name);
|
|
||||||
} else {
|
|
||||||
project = new WLProject(name, persistentStore);
|
|
||||||
projects.put(name, project);
|
|
||||||
// persistentStore.addProject(name);
|
|
||||||
}
|
|
||||||
return project;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getProjectNames() {
|
|
||||||
return new ArrayList<String>(projects.keySet());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initFromPersistentStore(PersistentStoreAPI persistentStore) {
|
|
||||||
this.persistentStore = persistentStore;
|
|
||||||
// for (String projectName : persistentStore.getProjectNames()) {
|
|
||||||
// projects.put(projectName, new WLProject(projectName, persistentStore));
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,14 +1,16 @@
|
||||||
package uk.ac.ic.wlgitbridge.writelatex.model.db;
|
package uk.ac.ic.wlgitbridge.writelatex.model.db;
|
||||||
|
|
||||||
|
import uk.ac.ic.wlgitbridge.writelatex.model.URLIndexStore;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.SQLiteWLDatabase;
|
import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.SQLiteWLDatabase;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Winston on 19/11/14.
|
* Created by Winston on 19/11/14.
|
||||||
*/
|
*/
|
||||||
public class PersistentStore {
|
public class PersistentStore implements URLIndexStore {
|
||||||
|
|
||||||
private final SQLiteWLDatabase database;
|
private final SQLiteWLDatabase database;
|
||||||
|
|
||||||
|
@ -21,6 +23,14 @@ public class PersistentStore {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> getProjectNames() {
|
||||||
|
try {
|
||||||
|
return database.getProjectNames();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
public void setLatestVersionForProject(String project, int versionID) {
|
public void setLatestVersionForProject(String project, int versionID) {
|
||||||
try {
|
try {
|
||||||
database.setVersionIDForProject(project, versionID);
|
database.setVersionIDForProject(project, versionID);
|
||||||
|
@ -29,22 +39,6 @@ public class PersistentStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteFilesForProject(String project, String... files) {
|
|
||||||
try {
|
|
||||||
database.deleteFilesForProject(project, files);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addURLIndexesForProject(String projectName, String url, String path) {
|
|
||||||
try {
|
|
||||||
database.addURLIndex(projectName, url, path);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLatestVersionForProject(String project) {
|
public int getLatestVersionForProject(String project) {
|
||||||
try {
|
try {
|
||||||
return database.getVersionIDForProjectName(project);
|
return database.getVersionIDForProjectName(project);
|
||||||
|
@ -53,6 +47,24 @@ public class PersistentStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addURLIndexForProject(String projectName, String url, String path) {
|
||||||
|
try {
|
||||||
|
database.addURLIndex(projectName, url, path);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteFilesForProject(String project, String... files) {
|
||||||
|
try {
|
||||||
|
database.deleteFilesForProject(project, files);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getPathForURLInProject(String projectName, String url) {
|
public String getPathForURLInProject(String projectName, String url) {
|
||||||
try {
|
try {
|
||||||
return database.getPathForURLInProject(projectName, url);
|
return database.getPathForURLInProject(projectName, url);
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package uk.ac.ic.wlgitbridge.writelatex.model.db.sql;
|
package uk.ac.ic.wlgitbridge.writelatex.model.db.sql;
|
||||||
|
|
||||||
import uk.ac.ic.wlgitbridge.util.Util;
|
import uk.ac.ic.wlgitbridge.util.Util;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.query.GetPathForURLInProjectSQLQuery;
|
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.query.GetLatestVersionForProjectSQLQuery;
|
import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.query.GetLatestVersionForProjectSQLQuery;
|
||||||
|
import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.query.GetPathForURLInProjectSQLQuery;
|
||||||
|
import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.query.GetProjectNamesSQLQuery;
|
||||||
|
import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.create.CreateIndexURLIndexStore;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.create.CreateProjectsTableSQLUpdate;
|
import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.create.CreateProjectsTableSQLUpdate;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.create.CreateURLIndexStoreSQLUpdate;
|
import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.create.CreateURLIndexStoreSQLUpdate;
|
||||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.delete.DeleteFilesForProjectSQLUpdate;
|
import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.delete.DeleteFilesForProjectSQLUpdate;
|
||||||
|
@ -11,6 +13,7 @@ import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.insert.SetProjectSQLU
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Winston on 17/11/14.
|
* Created by Winston on 17/11/14.
|
||||||
|
@ -48,10 +51,15 @@ public class SQLiteWLDatabase {
|
||||||
return query(new GetPathForURLInProjectSQLQuery(projectName, url));
|
return query(new GetPathForURLInProjectSQLQuery(projectName, url));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> getProjectNames() throws SQLException {
|
||||||
|
return query(new GetProjectNamesSQLQuery());
|
||||||
|
}
|
||||||
|
|
||||||
private void createTables() throws SQLException {
|
private void createTables() throws SQLException {
|
||||||
final SQLUpdate[] createTableUpdates = {
|
final SQLUpdate[] createTableUpdates = {
|
||||||
new CreateProjectsTableSQLUpdate(),
|
new CreateProjectsTableSQLUpdate(),
|
||||||
new CreateURLIndexStoreSQLUpdate()
|
new CreateURLIndexStoreSQLUpdate(),
|
||||||
|
new CreateIndexURLIndexStore()
|
||||||
};
|
};
|
||||||
|
|
||||||
for (SQLUpdate update : createTableUpdates) {
|
for (SQLUpdate update : createTableUpdates) {
|
||||||
|
|
|
@ -12,7 +12,7 @@ import java.sql.SQLException;
|
||||||
public class GetLatestVersionForProjectSQLQuery implements SQLQuery<Integer> {
|
public class GetLatestVersionForProjectSQLQuery implements SQLQuery<Integer> {
|
||||||
|
|
||||||
private static final String GET_VERSION_IDS_FOR_PROJECT_NAME =
|
private static final String GET_VERSION_IDS_FOR_PROJECT_NAME =
|
||||||
"SELECT `version_id` FROM `projects` WHERE `project_name` = ?";
|
"SELECT `version_id` FROM `projects` WHERE `name` = ?";
|
||||||
|
|
||||||
private final String projectName;
|
private final String projectName;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
package uk.ac.ic.wlgitbridge.writelatex.model.db.sql.query;
|
||||||
|
|
||||||
|
import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.SQLQuery;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Winston on 21/02/15.
|
||||||
|
*/
|
||||||
|
public class GetProjectNamesSQLQuery implements SQLQuery<List<String>> {
|
||||||
|
|
||||||
|
private static final String GET_URL_INDEXES_FOR_PROJECT_NAME =
|
||||||
|
"SELECT `name` FROM `projects`";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> processResultSet(ResultSet resultSet) throws SQLException {
|
||||||
|
List<String> projectNames = new LinkedList<String>();
|
||||||
|
while (resultSet.next()) {
|
||||||
|
projectNames.add(resultSet.getString("name"));
|
||||||
|
}
|
||||||
|
return projectNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSQL() {
|
||||||
|
return GET_URL_INDEXES_FOR_PROJECT_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addParametersToStatement(PreparedStatement statement) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package uk.ac.ic.wlgitbridge.writelatex.model.db.sql.update.create;
|
||||||
|
|
||||||
|
import uk.ac.ic.wlgitbridge.writelatex.model.db.sql.SQLUpdate;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Winston on 21/02/15.
|
||||||
|
*/
|
||||||
|
public class CreateIndexURLIndexStore implements SQLUpdate {
|
||||||
|
|
||||||
|
public static final String CREATE_INDEX_URL_INDEX_STORE = "CREATE INDEX `project_path_index` ON `url_index_store`(`project_name`, `path`);\n";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSQL() {
|
||||||
|
return CREATE_INDEX_URL_INDEX_STORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addParametersToStatement(PreparedStatement statement) throws SQLException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -11,16 +11,13 @@ import java.sql.SQLException;
|
||||||
public class CreateURLIndexStoreSQLUpdate implements SQLUpdate {
|
public class CreateURLIndexStoreSQLUpdate implements SQLUpdate {
|
||||||
|
|
||||||
private static final String CREATE_URL_INDEX_STORE =
|
private static final String CREATE_URL_INDEX_STORE =
|
||||||
"BEGIN;\n"+
|
|
||||||
"CREATE TABLE IF NOT EXISTS `url_index_store` (\n"+
|
"CREATE TABLE IF NOT EXISTS `url_index_store` (\n"+
|
||||||
" `project_name` varchar(10) NOT NULL DEFAULT '',\n"+
|
" `project_name` varchar(10) NOT NULL DEFAULT '',\n"+
|
||||||
" `url` text NOT NULL,\n"+
|
" `url` text NOT NULL,\n"+
|
||||||
" `path` text NOT NULL,\n"+
|
" `path` text NOT NULL,\n"+
|
||||||
" PRIMARY KEY (`project_name`,`url`),\n"+
|
" PRIMARY KEY (`project_name`,`url`),\n"+
|
||||||
" CONSTRAINT `url_index_store_ibfk_1` FOREIGN KEY (`project_name`) REFERENCES `projects` (`name`) ON DELETE CASCADE ON UPDATE CASCADE\n"+
|
" CONSTRAINT `url_index_store_ibfk_1` FOREIGN KEY (`project_name`) REFERENCES `projects` (`name`) ON DELETE CASCADE ON UPDATE CASCADE\n"+
|
||||||
");\n"+
|
");\n";
|
||||||
"CREATE INDEX `project_path_index` ON `url_index_store`(`project_name`, `path`);\n"+
|
|
||||||
"COMMIT;\n";
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSQL() {
|
public String getSQL() {
|
||||||
|
|
Loading…
Reference in a new issue