prepare for multiple apps
This commit is contained in:
@@ -0,0 +1,295 @@
|
||||
import 'package:weblibre/features/bangs/data/database/drift/converters/bang_format.dart';
|
||||
import 'package:weblibre/features/bangs/data/database/drift/converters/trigger_list.dart';
|
||||
import 'package:weblibre/features/bangs/data/models/bang_data.dart';
|
||||
import 'package:weblibre/features/bangs/data/models/bang_group.dart';
|
||||
import 'package:weblibre/features/bangs/data/models/bang.dart';
|
||||
import 'package:weblibre/features/bangs/data/models/search_history_entry.dart';
|
||||
|
||||
CREATE TABLE bang (
|
||||
"trigger" TEXT NOT NULL,
|
||||
"group" ENUM(BangGroup) NOT NULL,
|
||||
website_name TEXT NOT NULL,
|
||||
domain TEXT NOT NULL,
|
||||
url_template TEXT NOT NULL,
|
||||
category TEXT,
|
||||
sub_category TEXT,
|
||||
format TEXT MAPPED BY `const BangFormatConverter()`,
|
||||
additional_triggers TEXT MAPPED BY `const TriggerListConverter()`,
|
||||
searxng_api BOOL NOT NULL DEFAULT FALSE,
|
||||
snap_domain TEXT,
|
||||
PRIMARY KEY ("trigger", "group")
|
||||
) WITH Bang;
|
||||
|
||||
CREATE TABLE bang_triggers (
|
||||
"trigger" TEXT NOT NULL,
|
||||
"group" ENUM(BangGroup) NOT NULL,
|
||||
additional_trigger TEXT NOT NULL,
|
||||
PRIMARY KEY ("trigger", "group", additional_trigger),
|
||||
FOREIGN KEY ("trigger", "group") REFERENCES bang ("trigger", "group") ON DELETE CASCADE
|
||||
);
|
||||
CREATE INDEX idx_bang_triggers_lookup ON bang_triggers (additional_trigger, "group");
|
||||
|
||||
-- Trigger to populate bang_triggers when inserting a new bang
|
||||
CREATE TRIGGER bang_triggers_after_insert AFTER INSERT ON bang
|
||||
WHEN new.additional_triggers IS NOT NULL
|
||||
BEGIN
|
||||
INSERT INTO bang_triggers("trigger", "group", additional_trigger)
|
||||
SELECT
|
||||
new."trigger",
|
||||
new."group",
|
||||
json_each.value
|
||||
FROM json_each(new.additional_triggers);
|
||||
END;
|
||||
|
||||
-- Trigger to update bang_triggers when updating a bang
|
||||
CREATE TRIGGER bang_triggers_after_update AFTER UPDATE ON bang BEGIN
|
||||
-- Delete old additional triggers
|
||||
DELETE FROM bang_triggers
|
||||
WHERE "trigger" = old."trigger" AND "group" = old."group";
|
||||
|
||||
-- Insert new additional triggers if they exist
|
||||
INSERT INTO bang_triggers("trigger", "group", additional_trigger)
|
||||
SELECT
|
||||
new."trigger",
|
||||
new."group",
|
||||
json_each.value
|
||||
FROM json_each(new.additional_triggers)
|
||||
WHERE new.additional_triggers IS NOT NULL;
|
||||
END;
|
||||
|
||||
CREATE TABLE bang_sync (
|
||||
"group" ENUM(BangGroup) PRIMARY KEY NOT NULL,
|
||||
last_sync DATETIME NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE bang_frequency (
|
||||
"trigger" TEXT NOT NULL,
|
||||
"group" ENUM(BangGroup) NOT NULL,
|
||||
frequency INTEGER NOT NULL,
|
||||
last_used DATETIME NOT NULL,
|
||||
PRIMARY KEY ("trigger", "group"),
|
||||
FOREIGN KEY ("trigger", "group") REFERENCES bang ("trigger", "group") ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE bang_history (
|
||||
search_query TEXT UNIQUE NOT NULL,
|
||||
"trigger" TEXT NOT NULL,
|
||||
"group" ENUM(BangGroup) NOT NULL,
|
||||
search_date DATETIME NOT NULL,
|
||||
FOREIGN KEY ("trigger", "group") REFERENCES bang ("trigger", "group") ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE VIRTUAL TABLE bang_fts
|
||||
USING fts5(
|
||||
trigger,
|
||||
website_name,
|
||||
content=bang,
|
||||
prefix='2 3'
|
||||
);
|
||||
|
||||
CREATE VIRTUAL TABLE bang_triggers_fts
|
||||
USING fts5(
|
||||
additional_trigger,
|
||||
content=bang_triggers,
|
||||
prefix='2 3'
|
||||
);
|
||||
|
||||
CREATE VIEW bang_data_view WITH BangData AS
|
||||
SELECT
|
||||
b.*,
|
||||
bf.frequency,
|
||||
bf.last_used
|
||||
FROM
|
||||
bang b
|
||||
LEFT JOIN
|
||||
bang_frequency bf ON b."trigger" = bf."trigger" AND b."group" = bf."group";
|
||||
|
||||
-- Triggers to keep the FTS index up to date.
|
||||
CREATE TRIGGER bang_after_insert AFTER INSERT ON bang BEGIN
|
||||
INSERT INTO
|
||||
bang_fts(rowid, "trigger", website_name)
|
||||
VALUES (new.rowid, new."trigger", new.website_name);
|
||||
END;
|
||||
CREATE TRIGGER bang_after_delete AFTER DELETE ON bang BEGIN
|
||||
INSERT INTO
|
||||
bang_fts(bang_fts, rowid, "trigger", website_name)
|
||||
VALUES('delete', old.rowid, old."trigger", old.website_name);
|
||||
END;
|
||||
CREATE TRIGGER bang_after_update AFTER UPDATE ON bang BEGIN
|
||||
INSERT INTO
|
||||
bang_fts(bang_fts, rowid, "trigger", website_name)
|
||||
VALUES('delete', old.rowid, old."trigger", old.website_name);
|
||||
INSERT INTO
|
||||
bang_fts(rowid, "trigger", website_name)
|
||||
VALUES (new.rowid, new."trigger", new.website_name);
|
||||
END;
|
||||
|
||||
CREATE TRIGGER bang_triggers_after_insert_fts AFTER INSERT ON bang_triggers BEGIN
|
||||
INSERT INTO
|
||||
bang_triggers_fts(rowid, additional_trigger)
|
||||
VALUES (new.rowid, new.additional_trigger);
|
||||
END;
|
||||
CREATE TRIGGER bang_triggers_after_delete_fts AFTER DELETE ON bang_triggers BEGIN
|
||||
INSERT INTO
|
||||
bang_triggers_fts(bang_triggers_fts, rowid, additional_trigger)
|
||||
VALUES('delete', old.rowid, old.additional_trigger);
|
||||
END;
|
||||
CREATE TRIGGER bang_triggers_after_update_fts AFTER UPDATE ON bang_triggers BEGIN
|
||||
INSERT INTO
|
||||
bang_triggers_fts(bang_triggers_fts, rowid, additional_trigger)
|
||||
VALUES('delete', old.rowid, old.additional_trigger);
|
||||
INSERT INTO
|
||||
bang_triggers_fts(rowid, additional_trigger)
|
||||
VALUES (new.rowid, new.additional_trigger);
|
||||
END;
|
||||
|
||||
optimizeBangFtsIndex:
|
||||
INSERT INTO bang_fts(bang_fts) VALUES ('optimize');
|
||||
|
||||
optimizeTriggerFtsIndex:
|
||||
INSERT INTO bang_triggers_fts(bang_triggers_fts) VALUES ('optimize');
|
||||
|
||||
queryBangs WITH BangData:
|
||||
WITH weights AS (
|
||||
SELECT
|
||||
10.0 AS "trigger",
|
||||
8.0 AS additional_trigger,
|
||||
5.0 AS website_name
|
||||
),
|
||||
bang_results AS (
|
||||
SELECT
|
||||
b.*,
|
||||
bf.frequency,
|
||||
bf.last_used,
|
||||
bm25(bang_fts, weights."trigger", weights.website_name) AS weighted_rank
|
||||
FROM
|
||||
bang_fts(:query) fts
|
||||
INNER JOIN
|
||||
bang b ON b.rowid = fts.rowid
|
||||
LEFT JOIN
|
||||
bang_frequency bf ON b."trigger" = bf."trigger" AND b."group" = bf."group"
|
||||
CROSS JOIN weights
|
||||
),
|
||||
trigger_results AS (
|
||||
SELECT
|
||||
b.*,
|
||||
bf.frequency,
|
||||
bf.last_used,
|
||||
bm25(bang_triggers_fts, weights.additional_trigger) AS weighted_rank
|
||||
FROM
|
||||
bang_triggers_fts(:query) tfts
|
||||
INNER JOIN
|
||||
bang_triggers bt ON bt.rowid = tfts.rowid
|
||||
INNER JOIN
|
||||
bang b ON b."trigger" = bt."trigger" AND b."group" = bt."group"
|
||||
LEFT JOIN
|
||||
bang_frequency bf ON b."trigger" = bf."trigger" AND b."group" = bf."group"
|
||||
CROSS JOIN weights
|
||||
),
|
||||
combined_results AS (
|
||||
SELECT * FROM bang_results
|
||||
UNION ALL
|
||||
SELECT * FROM trigger_results
|
||||
)
|
||||
SELECT
|
||||
*,
|
||||
MIN(weighted_rank) AS weighted_rank
|
||||
FROM combined_results
|
||||
GROUP BY "trigger", "group"
|
||||
ORDER BY
|
||||
weighted_rank ASC,
|
||||
frequency NULLS LAST;
|
||||
|
||||
queryBangsBasic WITH BangData:
|
||||
WITH weights AS (
|
||||
SELECT
|
||||
10.0 AS "trigger",
|
||||
8.0 AS additional_trigger,
|
||||
5.0 AS website_name
|
||||
),
|
||||
bang_results AS (
|
||||
SELECT
|
||||
b.*,
|
||||
bf.frequency,
|
||||
bf.last_used,
|
||||
bm25(bang_fts, weights."trigger", weights.website_name) AS weighted_rank
|
||||
FROM
|
||||
bang_fts fts
|
||||
INNER JOIN
|
||||
bang b ON b.rowid = fts.rowid
|
||||
LEFT JOIN
|
||||
bang_frequency bf ON b."trigger" = bf."trigger" AND b."group" = bf."group"
|
||||
CROSS JOIN weights
|
||||
WHERE
|
||||
fts."trigger" LIKE :query OR
|
||||
fts.website_name LIKE :query
|
||||
),
|
||||
trigger_results AS (
|
||||
SELECT
|
||||
b.*,
|
||||
bf.frequency,
|
||||
bf.last_used,
|
||||
bm25(bang_triggers_fts, weights.additional_trigger) AS weighted_rank
|
||||
FROM
|
||||
bang_triggers_fts tfts
|
||||
INNER JOIN
|
||||
bang_triggers bt ON bt.rowid = tfts.rowid
|
||||
INNER JOIN
|
||||
bang b ON b."trigger" = bt."trigger" AND b."group" = bt."group"
|
||||
LEFT JOIN
|
||||
bang_frequency bf ON b."trigger" = bf."trigger" AND b."group" = bf."group"
|
||||
CROSS JOIN weights
|
||||
WHERE
|
||||
tfts.additional_trigger LIKE :query
|
||||
),
|
||||
combined_results AS (
|
||||
SELECT * FROM bang_results
|
||||
UNION ALL
|
||||
SELECT * FROM trigger_results
|
||||
)
|
||||
SELECT
|
||||
*,
|
||||
MIN(weighted_rank) AS weighted_rank
|
||||
FROM combined_results
|
||||
GROUP BY "trigger", "group"
|
||||
ORDER BY
|
||||
weighted_rank ASC,
|
||||
frequency NULLS LAST;
|
||||
|
||||
categoriesJson:
|
||||
WITH categories AS (
|
||||
SELECT
|
||||
b.category,
|
||||
json_group_array(
|
||||
DISTINCT b.sub_category
|
||||
ORDER BY b.sub_category
|
||||
) AS sub_categories
|
||||
FROM
|
||||
bang b
|
||||
WHERE
|
||||
b.category IS NOT NULL AND
|
||||
b.sub_category IS NOT NULL
|
||||
GROUP BY b.category
|
||||
ORDER BY b.category
|
||||
)
|
||||
SELECT
|
||||
json_group_object(
|
||||
c.category,
|
||||
json(c.sub_categories)
|
||||
) AS categories_json
|
||||
FROM categories c;
|
||||
|
||||
searchHistoryEntries WITH SearchHistoryEntry:
|
||||
SELECT *
|
||||
FROM bang_history
|
||||
ORDER BY search_date DESC
|
||||
LIMIT :limit;
|
||||
|
||||
evictHistoryEntries:
|
||||
DELETE FROM bang_history
|
||||
WHERE rowid IN (
|
||||
SELECT rowid
|
||||
FROM bang_history
|
||||
ORDER BY search_date DESC
|
||||
LIMIT -1 OFFSET :limit
|
||||
);
|
||||
Reference in New Issue
Block a user