mirror of
https://github.com/kristoferssolo/telescope-frecency.nvim.git
synced 2025-10-21 20:10:38 +00:00
137 lines
3.8 KiB
Lua
137 lines
3.8 KiB
Lua
local util = require("telescope._extensions.frecency.util")
|
|
local vim = vim
|
|
|
|
local has_sql, sql = pcall(require, "sql")
|
|
if not has_sql then
|
|
error("This plugin requires sql.nvim (https://github.com/tami5/sql.nvim)")
|
|
end
|
|
|
|
-- TODO: pass in max_timestamps from db.lua
|
|
local MAX_TIMESTAMPS = 10
|
|
|
|
-- TODO: prioritize files in project root!
|
|
|
|
local schemas = {[[
|
|
CREATE TABLE IF NOT EXISTS files (
|
|
id INTEGER PRIMARY KEY,
|
|
count INTEGER,
|
|
path TEXT
|
|
);
|
|
]],
|
|
[[
|
|
CREATE TABLE IF NOT EXISTS timestamps (
|
|
id INTEGER PRIMARY KEY,
|
|
file_id INTEGER,
|
|
timestamp REAL,
|
|
FOREIGN KEY(file_id) REFERENCES files(id)
|
|
);
|
|
]]}
|
|
|
|
local queries = {
|
|
["file_add_entry"] = "INSERT INTO files (path, count) values(:path, 1);",
|
|
["file_delete_entry"] = "DELETE FROM files WHERE id == :id;",
|
|
["file_update_counter"] = "UPDATE files SET count = count + 1 WHERE path == :path;",
|
|
["timestamp_add_entry"] = "INSERT INTO timestamps (file_id, timestamp) values(:file_id, julianday('now'));",
|
|
["timestamp_delete_before_id"] = "DELETE FROM timestamps WHERE id < :id and file_id == :file_id;",
|
|
["timestamp_delete_with_file_id"] = "DELETE FROM timestamps WHERE file_id == :file_id;",
|
|
["get_all_filepaths"] = "SELECT * FROM files;",
|
|
["get_all_timestamp_ages"] = "SELECT id, file_id, CAST((julianday('now') - julianday(timestamp)) * 24 * 60 AS INTEGER) AS age FROM timestamps;",
|
|
["get_row"] = "SELECT * FROM files WHERE path == :path;",
|
|
["get_timestamp_ids_for_file"] = "SELECT id FROM timestamps WHERE file_id == :file_id;",
|
|
}
|
|
|
|
-- local ignore_patterns = {
|
|
-- }
|
|
|
|
--
|
|
|
|
local M = {}
|
|
M.queries = queries
|
|
|
|
function M:new()
|
|
local o = {}
|
|
setmetatable(o, self)
|
|
self.__index = self
|
|
self.db = nil
|
|
|
|
return o
|
|
end
|
|
|
|
function M:bootstrap(opts)
|
|
opts = opts or {}
|
|
|
|
if self.db then
|
|
print("sql wrapper already initialised")
|
|
return
|
|
end
|
|
|
|
self.max_entries = opts.max_entries or 2000
|
|
|
|
-- create the db if it doesn't exist
|
|
local db_root = opts.docs_root or vim.fn.stdpath('data')
|
|
local db_filename = db_root .. "/file_frecency.sqlite3"
|
|
self.db = sql.open(db_filename)
|
|
if not self.db then
|
|
print("error")
|
|
return
|
|
end
|
|
|
|
-- create tables if they don't exist
|
|
for _, s in pairs(schemas) do
|
|
self.db:eval(s)
|
|
end
|
|
self.db:close()
|
|
|
|
end
|
|
|
|
function M:do_transaction(query, params)
|
|
if not queries[query] then
|
|
print("invalid query_preset: " .. query )
|
|
return
|
|
end
|
|
|
|
local res
|
|
self.db:with_open(function(db) res = db:eval(queries[query], params) end)
|
|
return res
|
|
end
|
|
|
|
function M:get_row_id(filepath)
|
|
local result = self:do_transaction('get_row', { path = filepath })
|
|
|
|
return type(result) == "table" and result[1].id or nil
|
|
end
|
|
|
|
function M:update(filepath)
|
|
local filestat = util.fs_stat(filepath)
|
|
if (vim.tbl_isempty(filestat) or
|
|
filestat.exists == false or
|
|
filestat.isdirectory == true) then
|
|
return end
|
|
|
|
-- create entry if it doesn't exist
|
|
local file_id
|
|
file_id = self:get_row_id(filepath)
|
|
if not file_id then
|
|
self:do_transaction('file_add_entry', { path = filepath })
|
|
file_id = self:get_row_id(filepath)
|
|
else
|
|
-- ..or update existing entry
|
|
self:do_transaction('file_update_counter', { path = filepath })
|
|
end
|
|
|
|
-- register timestamp for this update
|
|
self:do_transaction('timestamp_add_entry', { file_id = file_id })
|
|
|
|
-- trim timestamps to MAX_TIMESTAMPS per file (there should be up to MAX_TS + 1 at this point)
|
|
local timestamps = self:do_transaction('get_timestamp_ids_for_file', { file_id = file_id })
|
|
local trim_at = timestamps[(#timestamps - MAX_TIMESTAMPS) + 1]
|
|
if trim_at then
|
|
self:do_transaction('timestamp_delete_before_id', { id = trim_at.id, file_id = file_id })
|
|
end
|
|
end
|
|
|
|
function M:validate()
|
|
end
|
|
|
|
return M
|