feat!: make use_sqlite = false be the default (#148)

* refactor: load lazily sqlite to get filename

* feat: add logic to start migration automatically

* feat: make use_sqlite = false be the default

* docs: update README for removing dependencies

* feat: migrate silently when use_sqlite = false

* chore: remove `SQLite3` from messages

* test: run again max to 5 times in Windows
This commit is contained in:
JINNOUCHI Yasushi
2023-10-10 18:17:08 +09:00
committed by GitHub
parent 4bdd9bafc7
commit daf59744f6
6 changed files with 175 additions and 88 deletions

View File

@@ -8,6 +8,7 @@
---@class FrecencyDatabase
---@field config FrecencyDatabaseConfig
---@field filename string
---@field has_entry fun(): boolean
---@field new fun(fs: FrecencyFS, config: FrecencyDatabaseConfig): FrecencyDatabase
---@field protected fs FrecencyFS

View File

@@ -7,7 +7,6 @@ local Path = require "plenary.path" --[[@as PlenaryPath]]
---@class FrecencyDatabaseNative: FrecencyDatabase
---@field version "v1"
---@field filename string
---@field file_lock FrecencyFileLock
---@field table FrecencyDatabaseNativeTable
local Native = {}

View File

@@ -1,5 +1,6 @@
local sqlite = require "frecency.sqlite"
local log = require "plenary.log"
local Path = require "plenary.path" --[[@as PlenaryPath]]
---@class FrecencySqliteDB: sqlite_db
---@field files sqlite_tbl
@@ -25,20 +26,32 @@ local Sqlite = {}
---@param config FrecencyDatabaseConfig
---@return FrecencyDatabaseSqlite
Sqlite.new = function(fs, config)
local lib = sqlite.lib
local self = setmetatable(
{ config = config, buf_registered_flag_name = "telescope_frecency_registered", fs = fs },
{ __index = Sqlite }
)
self.sqlite = sqlite {
uri = self.config.root .. "/file_frecency.sqlite3",
files = { id = true, count = { "integer", default = 1, required = true }, path = "string" },
timestamps = {
id = true,
file_id = { "integer", reference = "files.id", on_delete = "cascade" },
timestamp = { "real", default = lib.julianday "now" },
},
}
self.filename = Path.new(self.config.root, "file_frecency.sqlite3").filename
self.sqlite = setmetatable({}, {
__index = function(this, key)
if not rawget(this, "instance") then
local lib = sqlite.lib
rawset(
this,
"instance",
sqlite {
uri = self.filename,
files = { id = true, count = { "integer", default = 1, required = true }, path = "string" },
timestamps = {
id = true,
file_id = { "integer", reference = "files.id", on_delete = "cascade" },
timestamp = { "real", default = lib.julianday "now" },
},
}
)
end
return rawget(this, "instance")[key]
end,
})
return self
end

View File

@@ -33,7 +33,7 @@ local Frecency = {}
---@field show_filter_column boolean|string[]|nil default: true
---@field show_scores boolean? default: false
---@field show_unindexed boolean? default: true
---@field use_sqlite boolean? default: true
---@field use_sqlite boolean? default: false
---@field workspaces table<string, string>? default: {}
---@param opts FrecencyConfig?
@@ -53,7 +53,7 @@ Frecency.new = function(opts)
show_filter_column = true,
show_scores = false,
show_unindexed = true,
use_sqlite = true,
use_sqlite = false,
workspaces = {},
}, opts or {})
local self = setmetatable({ buf_registered = {}, config = config }, { __index = Frecency })--[[@as Frecency]]
@@ -66,6 +66,7 @@ Frecency.new = function(opts)
self:warn "use_sqlite = true, but sqlite module can not be found. It fallbacks to native code."
Database = Native
else
self:warn "SQLite mode is deprecated."
Database = Sqlite
end
self.database = Database.new(self.fs, { root = config.db_root })
@@ -88,10 +89,7 @@ function Frecency:setup()
vim.api.nvim_set_hl(0, "TelescopeQueryFilter", { link = "WildMenu", default = true })
-- TODO: Should we schedule this after loading shada?
if not self.database:has_entry() then
self.database:insert_files(vim.v.oldfiles)
self:notify("Imported %d entries from oldfiles.", #vim.v.oldfiles)
end
self:assert_db_entries()
---@param cmd_info { bang: boolean }
vim.api.nvim_create_user_command("FrecencyValidate", function(cmd_info)
@@ -142,6 +140,22 @@ function Frecency:complete(findstart, base)
return self.picker:complete(findstart, base)
end
---@private
---@return nil
function Frecency:assert_db_entries()
if self.database:has_entry() then
return
elseif not self.config.use_sqlite and sqlite_module.can_use then
local sqlite = Sqlite.new(self.fs, { root = self.config.db_root })
if sqlite:has_entry() then
self:migrate_database(false, true)
return
end
end
self.database:insert_files(vim.v.oldfiles)
self:notify("Imported %d entries from oldfiles.", #vim.v.oldfiles)
end
---@private
---@param force boolean?
---@return nil
@@ -159,7 +173,7 @@ function Frecency:validate_database(force)
return
end
vim.ui.select({ "y", "n" }, {
prompt = self:message("remove %d entries from SQLite3 database?", #unlinked),
prompt = self:message("remove %d entries from database?", #unlinked),
---@param item "y"|"n"
---@return string
format_item = function(item)
@@ -186,10 +200,28 @@ function Frecency:register(bufnr, datetime)
end
---@param to_sqlite boolean?
---@param silently boolean?
---@return nil
function Frecency:migrate_database(to_sqlite)
local prompt = to_sqlite and "migrate the DB into SQLite from native code?"
or "migrate the DB into native code from SQLite?"
function Frecency:migrate_database(to_sqlite, silently)
local function migrate()
if not sqlite_module.can_use then
self:error "sqlite.lua is unavailable"
elseif to_sqlite then
self.migrator:to_sqlite()
self:notify "Migration is finished successfully."
else
self.migrator:to_v1()
self:notify "Migration is finished successfully. You can remove sqlite.lua from dependencies."
end
end
if silently then
migrate()
return
end
local prompt = to_sqlite and "Migrate the DB into SQLite from native code?"
or "Migrate the DB into native code from SQLite?"
vim.ui.select({ "y", "n" }, {
prompt = prompt,
---@param item "y"|"n"
@@ -198,20 +230,11 @@ function Frecency:migrate_database(to_sqlite)
return item == "y" and "Yes, Migrate it." or "No. Do nothing."
end,
}, function(item)
if item == "n" then
self:notify "migration aborted"
return
elseif to_sqlite then
if sqlite_module.can_use then
self.migrator:to_sqlite()
else
self:error "sqlite.lua is unavailable"
return
end
if item == "y" then
migrate()
else
self.migrator:to_v1()
self:notify "Migration aborted"
end
self:notify "migration finished successfully"
end)
end