From: <sh...@us...> - 2007-10-23 22:16:57
|
Revision: 10947 http://jedit.svn.sourceforge.net/jedit/?rev=10947&view=rev Author: shlomy Date: 2007-10-23 15:16:55 -0700 (Tue, 23 Oct 2007) Log Message: ----------- Finished updating the plugin with the 4-table DB design. Modified Paths: -------------- plugins/CtagsInterface/trunk/design.txt plugins/CtagsInterface/trunk/src/ctags/CtagsInterfacePlugin.java plugins/CtagsInterface/trunk/src/ctags/Runner.java plugins/CtagsInterface/trunk/src/db/TagDB.java plugins/CtagsInterface/trunk/src/options/DirsOptionPane.java plugins/CtagsInterface/trunk/src/options/ProjectsOptionPane.java plugins/CtagsInterface/trunk/todo.txt Modified: plugins/CtagsInterface/trunk/design.txt =================================================================== --- plugins/CtagsInterface/trunk/design.txt 2007-10-23 11:23:55 UTC (rev 10946) +++ plugins/CtagsInterface/trunk/design.txt 2007-10-23 22:16:55 UTC (rev 10947) @@ -44,7 +44,7 @@ } } INSERT INTO TAGS (TAG, FILE_ID, ...) VALUES {tag}, {id}, ... -- Adding a source tree: ++ Adding a source tree: INSERT INTO ORIGINS (NAME, TYPE) VALUES {tree}, 'SourceTree' originId = SELECT ID FROM ORIGINS WHERE TYPE='SourceTree' and NAME={tree} Run "ctags -R" on source tree @@ -52,24 +52,24 @@ For each element in fileSet: id = SELECT ID FROM FILES WHERE FILE={path} INSERT INTO MAP (FILE_ID, ORIGIN_ID) VALUES {id}, {originId} -- Removing a source tree: ++ Removing a source tree: originId = SELECT ID FROM ORIGINS WHERE TYPE='SourceTree' and NAME={tree} DELETE FROM ORIGINS WHERE ID={originId} DELETE FROM MAP WHERE ORIGIN_ID={originId} DELETE FROM TAGS WHERE FILE_ID IN ( SELECT ID FROM FILES WHERE NOT EXISTS (SELECT FILE_ID FROM MAP WHERE ID=FILE_ID)) DELETE FROM FILES WHERE NOT EXISTS (SELECT FILE_ID FROM MAP WHERE ID=FILE_ID) -- Updating a source tree: ++ Updating a source tree: Same as removing and then adding, except no changes to the ORIGINS table (same ID used). -- Adding a project: ++ Adding a project: INSERT INTO ORIGINS (NAME, TYPE) VALUES {project}, 'Project' originId = SELECT ID FROM ORIGINS WHERE TYPE='Project' and NAME={project} Run "ctags" on project files Rest is the same as adding a source tree. -- Removing a project: ++ Removing a project: originId = SELECT ID FROM ORIGINS WHERE TYPE='Project' and NAME={project} Rest is the same as removing a source tree. -- Updating a project: ++ Updating a project: Same as updating a source tree. + Finding a tag by name: SELECT * FROM TAGS, FILES WHERE TAGS.FILE_ID=FILES.ID Modified: plugins/CtagsInterface/trunk/src/ctags/CtagsInterfacePlugin.java =================================================================== --- plugins/CtagsInterface/trunk/src/ctags/CtagsInterfacePlugin.java 2007-10-23 11:23:55 UTC (rev 10946) +++ plugins/CtagsInterface/trunk/src/ctags/CtagsInterfacePlugin.java 2007-10-23 22:16:55 UTC (rev 10947) @@ -48,7 +48,7 @@ { db = new TagDB(); parser = new Parser(); - runner = new Runner(db); + runner = new Runner(); watcher = new BufferWatcher(db); EditPlugin p = jEdit.getPlugin("projectviewer.ProjectPlugin",false); if(p == null) @@ -119,6 +119,10 @@ static private class TagFileHandler implements TagHandler { private HashSet<Integer> files = new HashSet<Integer>(); + private int originId; + public TagFileHandler(int originId) { + this.originId = originId; + } public void processTag(Hashtable<String, String> info) { String file = info.get(TagDB.TAGS_FILE_ID); int fileId = db.getSourceFileID(file); @@ -132,6 +136,7 @@ db.deleteTagsFromSourceFile(fileId); } files.add(fileId); + db.insertSourceFileOrigin(fileId, originId); } db.insertTag(info, fileId); } @@ -140,7 +145,7 @@ // Adds a temporary tag file to the DB // Existing tags from source files in the tag file are removed first. static private void addTempTagFile(String tagFile) { - parser.parseTagFile(tagFile, new TagFileHandler()); + parser.parseTagFile(tagFile, new TagFileHandler(TagDB.TEMP_ORIGIN_INDEX)); } // Action: Prompt for a temporary tag file to add to the DB @@ -226,13 +231,16 @@ jumpToQueryResults(view, rs); } + // Returns the tag to jump to: The selected tag or the one at the caret. static public String getDestinationTag(View view) { String tag = view.getTextArea().getSelectedText(); if (tag == null || tag.length() == 0) tag = getTagAtCaret(view); return tag; } - private static String getTagAtCaret(View view) { + + // Returns the tag at the caret. + static private String getTagAtCaret(View view) { JEditTextArea ta = view.getTextArea(); int line = ta.getCaretLine(); int index = ta.getCaretPosition() - ta.getLineStartOffset(line); @@ -254,6 +262,7 @@ return selected; } + // Jumps to the specified location public static void jumpTo(final View view, String file, final int line) { Buffer buffer = jEdit.openFile(view, file); if (buffer == null) { @@ -268,6 +277,65 @@ }); } + // Updates the given origins in the DB + static public void updateOrigins(String type, Vector<String> names) { + // Remove obsolete origins + Vector<String> current = db.getOrigins(type); + for (int i = 0; i < current.size(); i++) { + String name = current.get(i); + if (! names.contains(name)) + deleteOrigin(type, name); + } + // Add new origins + for (int i = 0; i < names.size(); i++) { + String name = names.get(i); + if (! current.contains(name)) + insertOrigin(type, name); + } + } + + // Refreshes the given origin in the DB + static public void refreshOrigin(String type, String name) { + try { + db.deleteOriginAssociatedData(type, name); + } catch (SQLException e) { + e.printStackTrace(); + } + tagOrigin(type, name); + } + + // Deletes an origin with all associated data from the DB + private static void deleteOrigin(String type, String name) { + try { + db.deleteOrigin(type, name); + } catch (SQLException e) { + e.printStackTrace(); + } + } + // Inserts a new origin to the DB, runs Ctags on it and adds the tags + // to the DB. + private static void insertOrigin(String type, String name) { + try { + db.insertOrigin(type, name); + } catch (SQLException e) { + e.printStackTrace(); + } + tagOrigin(type, name); + } + // Runs Ctags on the specified origin and adds the tags to the DB. + private static void tagOrigin(String type, String name) { + int originId = db.getOriginID(type, name); + if (originId < 0) { + System.err.println("Cannot find newly inserted origin " + name + " in DB."); + return; + } + TagFileHandler handler = new TagFileHandler(originId); + if (type.equals(TagDB.PROJECT_ORIGIN)) + tagProject(name, handler); + else if (type.equals(TagDB.DIR_ORIGIN)) + tagSourceTree(name, handler); + } + private static void addWorkRequest(Runnable run, boolean inAWT) { if (! GeneralOptionPane.getUpdateInBackground()) { run.run(); @@ -291,11 +359,13 @@ public void run() { final int fileId = db.getSourceFileID(file); db.deleteTagsFromSourceFile(fileId); - runner.runOnFile(file, new TagHandler() { + String tagFile = runner.runOnFile(file); + TagHandler handler = new TagHandler() { public void processTag(Hashtable<String, String> info) { db.insertTag(info, fileId); } - }); + }; + parser.parseTagFile(tagFile, handler); } }, false); removeStatusMessage(); @@ -303,30 +373,13 @@ /* Source tree support */ - public static void tagSourceTree(final String tree) { + // Runs Ctags on a source tree and add the tags and associated data to the DB + public static void tagSourceTree(final String tree, final TagHandler handler) { setStatusMessage("Tagging source tree: " + tree); addWorkRequest(new Runnable() { public void run() { - int originId = db.queryInteger(TagDB.ORIGINS_ID, - "SELECT ID FROM ORIGINS WHERE TYPE='DIR' AND " + - "NAME=" + db.quote(tree), -1); - if (originId < 0) - return; - // Find file ids - required for cleanup - Vector<Integer> fileIds = db.queryIntegerList( - TagDB.MAP_FILE_ID, - "SELECT FILE_ID FROM MAP WHERE ORIGIN_ID=" + originId); - db.deleteRowsWithValue(TagDB.MAP_TABLE, TagDB.MAP_ORIGIN_ID, - Integer.valueOf(originId)); - db.deleteRowsWithValueList(TagDB.TAGS_TABLE, - TagDB.TAGS_FILE_ID, fileIds); - try { - db.query("DELETE FROM FILES WHERE NOT EXISTS (" + - "SELECT FILE_ID FROM MAP WHERE ID=FILE_ID)"); - } catch (SQLException e) { - e.printStackTrace(); - } - runner.runOnTree(tree, tagHandler); + String tagFile = runner.runOnTree(tree); + parser.parseTagFile(tagFile, handler); } }, false); removeStatusMessage(); @@ -338,9 +391,6 @@ return pvi; } - private static void removeProject(String project) { - //db.deleteRowsWithValue(TagDB.PROJECT_COL, project); - } private static void removeProjectFiles(String project, Vector<String> files) { @@ -351,34 +401,35 @@ db.deleteRowsWithValues(values); } } - private static void addProjectFiles(String project, - Vector<String> files) + + // Runs Ctags on a list of files and add the tags and associated data to the DB + private static void tagFiles(Vector<String> files, TagHandler handler) { - db.setProject(project); - runner.runOnFiles(files, tagHandler); - db.unsetProject(); + String tagFile = runner.runOnFiles(files); + parser.parseTagFile(tagFile, handler); } - public static void tagProject(final String project) { + + // Runs Ctags on a project and inserts the tags and associated data to the DB + public static void tagProject(final String project, final TagHandler handler) { if (pvi == null) return; setStatusMessage("Tagging project: " + project); addWorkRequest(new Runnable() { public void run() { - removeProject(project); Vector<String> files = pvi.getFiles(project); - addProjectFiles(project, files); + tagFiles(files, handler); } }, false); removeStatusMessage(); } - public static void updateProject(String project, - Vector<String> added, Vector<String> removed) + public static void updateProject(String project, Vector<String> added, + Vector<String> removed) { setStatusMessage("Updating project: " + project); if (removed != null) removeProjectFiles(project, removed); if (added != null) - addProjectFiles(project, added); + tagFiles(added, tagHandler); removeStatusMessage(); } } Modified: plugins/CtagsInterface/trunk/src/ctags/Runner.java =================================================================== --- plugins/CtagsInterface/trunk/src/ctags/Runner.java 2007-10-23 11:23:55 UTC (rev 10946) +++ plugins/CtagsInterface/trunk/src/ctags/Runner.java 2007-10-23 22:16:55 UTC (rev 10947) @@ -3,37 +3,32 @@ import java.io.IOException; import java.util.Vector; -import org.gjt.sp.jedit.jEdit; - -import ctags.Parser.TagHandler; - import options.GeneralOptionPane; -import db.TagDB; +import org.gjt.sp.jedit.jEdit; + public class Runner { private static final String SPACES = "\\s+"; - private Parser parser; - public Runner(TagDB db) { - parser = null; - } - - public void runOnFile(String file, TagHandler handler) { + // Runs Ctags on a single file. Returns the tag file. + public String runOnFile(String file) { Vector<String> what = new Vector<String>(); what.add(file); - run(what, handler); + return run(what); } - public void runOnTree(String tree, TagHandler handler) { + // Runs Ctags on a source tree. Returns the tag file. + public String runOnTree(String tree) { Vector<String> what = new Vector<String>(); what.add("-R"); what.add(tree); - run(what, handler); + return run(what); } - public void runOnFiles(Vector<String> files, TagHandler handler) { - run(files, handler); + // Runs Ctags on a list of files. Returns the tag file. + public String runOnFiles(Vector<String> files) { + return run(files); } - private void run(Vector<String> what, TagHandler handler) { + private String run(Vector<String> what) { String ctags = GeneralOptionPane.getCtags(); String cmd = GeneralOptionPane.getCmd(); String tagFile = getTempTagFilePath(); @@ -52,13 +47,12 @@ p.waitFor(); } catch (IOException e) { e.printStackTrace(); - return; + return null; } catch (InterruptedException e) { e.printStackTrace(); + return null; } - if (parser == null) - parser = new Parser(); - parser.parseTagFile(tagFile, handler); + return tagFile; } private String getTempTagFilePath() { Modified: plugins/CtagsInterface/trunk/src/db/TagDB.java =================================================================== --- plugins/CtagsInterface/trunk/src/db/TagDB.java 2007-10-23 11:23:55 UTC (rev 10946) +++ plugins/CtagsInterface/trunk/src/db/TagDB.java 2007-10-23 22:16:55 UTC (rev 10947) @@ -44,6 +44,9 @@ public static final String MAP_FILE_ID = "FILE_ID"; public static final String MAP_ORIGIN_ID = "ORIGIN_ID"; // Origin types + public static final int TEMP_ORIGIN_INDEX = 0; + public static final String TEMP_ORIGIN_NAME = "Temp"; + public static final String TEMP_ORIGIN = "Temp"; public static final String PROJECT_ORIGIN = "Project"; public static final String DIR_ORIGIN = "Dir"; @@ -83,6 +86,21 @@ } } + // Inserts a source file -> origin mapping to the DB + public void insertSourceFileOrigin(int fileId, int originId) { + try { + ResultSet rs = query("SELECT * FROM " + MAP_TABLE + " WHERE " + + MAP_FILE_ID + "=" + quote(fileId) + " AND " + + MAP_ORIGIN_ID + "=" + quote(originId)); + if (rs.next()) + return; + update("INSERT INTO " + MAP_TABLE + " (" + MAP_FILE_ID + "," + MAP_ORIGIN_ID + + ") VALUES (" + quote(fileId) + "," + quote(originId) + ")"); + } catch (SQLException e) { + e.printStackTrace(); + } + } + // Delete tags from source file public void deleteTagsFromSourceFile(int fileId) { if (fileId < 0) @@ -140,14 +158,14 @@ public ResultSet queryTag(String tag) throws SQLException { String query = "SELECT * FROM " + TAGS_TABLE + "," + FILES_TABLE + " WHERE " + field(TAGS_TABLE, TAGS_NAME) + "=" + quote(tag) + - " AND " + field(TAGS_TABLE, TAGS_FILE_ID) + "=" + - field(FILES_TABLE, FILES_ID); + " AND " + field(TAGS_TABLE, TAGS_FILE_ID) + "=" + field(FILES_TABLE, FILES_ID); return query(query); } // Runs a query for the specified tag name in the specified project public ResultSet queryTagInProject(String tag, String project) throws SQLException { String query = "SELECT * FROM " + TAGS_TABLE + "," + FILES_TABLE + " WHERE " + field(TAGS_TABLE, TAGS_NAME) + "=" + quote(tag) + + " AND " + field(TAGS_TABLE, TAGS_FILE_ID) + "=" + field(FILES_TABLE, FILES_ID) + " AND EXISTS " + "(SELECT " + MAP_FILE_ID + " FROM " + MAP_TABLE + " WHERE " + field(MAP_TABLE, MAP_FILE_ID) + "=" + @@ -160,6 +178,49 @@ return query(query); } + // Returns the ID of an origin + public int getOriginID(String type, String name) { + return queryInteger(ORIGINS_ID, "SELECT " + ORIGINS_ID + " FROM " + ORIGINS_TABLE + + " WHERE " + ORIGINS_TYPE + "=" + quote(type) + " AND " + ORIGINS_NAME + "=" + + quote(name), -1); + } + + // Inserts a new origin to the DB + public void insertOrigin(String type, String name) throws SQLException { + update("INSERT INTO " + ORIGINS_TABLE + " (" + + ORIGINS_TYPE + "," + ORIGINS_NAME + ") VALUES (" + + quote(type) + "," + quote(name) + ")"); + } + + // Delete all data associated with the specified origin + public void deleteOriginAssociatedData(String type, String name) throws SQLException { + int originId = queryInteger(ORIGINS_ID, + "SELECT " + ORIGINS_ID + " FROM " + ORIGINS_TABLE + " WHERE " + + ORIGINS_TYPE + "=" + quote(type) + " AND " + + ORIGINS_NAME + "=" + quote(name), -1); + if (originId < 0) + return; + // Remove all mappings to the origin + query("DELETE FROM " + MAP_TABLE + " WHERE " + MAP_ORIGIN_ID + "=" + + quote(originId)); + // Remove all orphaned (with no origin) files + query("DELETE FROM " + FILES_TABLE + " WHERE NOT EXIST " + + "(SELECT " + MAP_FILE_ID + " FROM " + MAP_TABLE + " WHERE " + + MAP_FILE_ID + "=" + FILES_ID); + // Remove all orphaned (with no file) tags + query("DELETE FROM " + TAGS_TABLE + " WHERE NOT EXIST " + + "(SELECT " + FILES_ID + " FROM " + FILES_TABLE + " WHERE " + + FILES_ID + "=" + TAGS_FILE_ID); + } + + // Deletes an origin and all its associated data from the DB + public void deleteOrigin(String type, String name) throws SQLException { + query("DELETE FROM " + ORIGINS_TABLE + " WHERE " + + ORIGINS_TYPE + "=" + quote(type) + " AND " + + ORIGINS_NAME + "=" + quote(name)); + deleteOriginAssociatedData(type, name); + } + private String field(String table, String column) { return table + "." + column; } @@ -200,33 +261,7 @@ "SELECT * FROM " + ORIGINS_TABLE + " WHERE " + ORIGINS_TYPE + "=" + quote(type)); } - public void updateOrigins(String type, Vector<String> values) { - // Remove obsolete origins - Vector<String> current = queryStringList(ORIGINS_NAME, - "SELECT * FROM " + ORIGINS_TABLE + " WHERE " + - ORIGINS_TYPE + "=" + quote(type)); - for (int i = 0; i < current.size(); i++) { - String name = current.get(i); - if (! values.contains(name)) - deleteOrigin(type, name); - } - // Add new origins - for (int i = 0; i < values.size(); i++) { - String name = values.get(i); - if (! current.contains(name)) - try { - insertOrigin(type, name); - } catch (SQLException e) { - e.printStackTrace(); - } - } - } - public void setProject(String project) { - } - public void unsetProject() { - } - public synchronized void update(String expression) throws SQLException { //System.err.println("update: " + expression); Statement st = conn.createStatement(); @@ -418,6 +453,9 @@ ORIGINS_NAME, VARCHAR_TYPE, ORIGINS_TYPE, VARCHAR_TYPE }); + update("INSERT INTO " + ORIGINS_TABLE + " (" + ORIGINS_ID + "," + + ORIGINS_NAME + "," + ORIGINS_TYPE + ") VALUES (" + TEMP_ORIGIN_INDEX + + "," + quote(TEMP_ORIGIN_NAME) + ", " + quote(TEMP_ORIGIN) + ")"); // Create Map table createTable(MAP_TABLE, new String [] { MAP_FILE_ID, INTEGER_TYPE, @@ -430,30 +468,4 @@ } } - private void insertOrigin(String type, String name) throws SQLException { - update("INSERT INTO " + ORIGINS_TABLE + " (" + - ORIGINS_TYPE + "," + ORIGINS_NAME + ") VALUES (" + - type + "," + name + ")"); - } - private void deleteOrigin(String type, String name) { - // TODO: Remove origin from origins table, remove all files - // originated in the removed origin only, and remove all tags - // from the removed files. - int originId = queryInteger(ORIGINS_ID, - "SELECT * FROM " + ORIGINS_TABLE + " WHERE " + - ORIGINS_TYPE + "=" + quote(type) + " AND " + - ORIGINS_NAME + "=" + quote(name), -1); - if (originId < 0) - return; - String fileIds = "SELECT " + MAP_FILE_ID + " FROM " + MAP_TABLE + - " WHERE " + MAP_ORIGIN_ID + "=" + quote(originId); - String deleteTags = "DELETE FROM TAGS WHERE FILE_ID IN (" + - fileIds + ")"; - try { - query(deleteTags); - } catch (SQLException e) { - e.printStackTrace(); - } - } - } Modified: plugins/CtagsInterface/trunk/src/options/DirsOptionPane.java =================================================================== --- plugins/CtagsInterface/trunk/src/options/DirsOptionPane.java 2007-10-23 11:23:55 UTC (rev 10946) +++ plugins/CtagsInterface/trunk/src/options/DirsOptionPane.java 2007-10-23 22:16:55 UTC (rev 10947) @@ -79,7 +79,7 @@ int i = dirs.getSelectedIndex(); if (i >= 0) { String tree = (String) dirsModel.getElementAt(i); - CtagsInterfacePlugin.tagSourceTree(tree); + CtagsInterfacePlugin.refreshOrigin(DIR_ORIGIN, tree); } } }); @@ -90,7 +90,7 @@ int nDirs = dirsModel.size(); for (int i = 0; i < nDirs; i++) names.add((String) dirsModel.getElementAt(i)); - CtagsInterfacePlugin.getDB().updateOrigins(DIR_ORIGIN, names); + CtagsInterfacePlugin.updateOrigins(DIR_ORIGIN, names); } static public Vector<String> getDirs() { Modified: plugins/CtagsInterface/trunk/src/options/ProjectsOptionPane.java =================================================================== --- plugins/CtagsInterface/trunk/src/options/ProjectsOptionPane.java 2007-10-23 11:23:55 UTC (rev 10946) +++ plugins/CtagsInterface/trunk/src/options/ProjectsOptionPane.java 2007-10-23 22:16:55 UTC (rev 10947) @@ -90,7 +90,7 @@ int i = projects.getSelectedIndex(); if (i >= 0) { String project = (String) projectsModel.getElementAt(i); - CtagsInterfacePlugin.tagProject(project); + CtagsInterfacePlugin.refreshOrigin(PROJECT_ORIGIN, project); } } }); @@ -109,7 +109,7 @@ int nProjects = projectsModel.size(); for (int i = 0; i < nProjects; i++) names.add((String) projectsModel.getElementAt(i)); - CtagsInterfacePlugin.getDB().updateOrigins(PROJECT_ORIGIN, names); + CtagsInterfacePlugin.updateOrigins(PROJECT_ORIGIN, names); jEdit.setBooleanProperty(AUTO_UPDATE, autoUpdate.isSelected()); jEdit.setBooleanProperty(ACTIVE_ONLY, activeOnly.isSelected()); } Modified: plugins/CtagsInterface/trunk/todo.txt =================================================================== --- plugins/CtagsInterface/trunk/todo.txt 2007-10-23 11:23:55 UTC (rev 10946) +++ plugins/CtagsInterface/trunk/todo.txt 2007-10-23 22:16:55 UTC (rev 10947) @@ -22,3 +22,5 @@ + Watched buffer is saved + Watched buffer is loaded + Add project name or id to each tag in the table. + +Update to released PV: tags/pv_2_1_3_7 \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |