mirror of
https://github.com/l5yth/potato-mesh.git
synced 2026-05-10 07:14:49 +02:00
Compare commits
1 Commits
v0.6.1-rc0
..
v0.6.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 13b2ce9067 |
@@ -171,16 +171,20 @@ module PotatoMesh
|
||||
return if existing
|
||||
|
||||
long_name = "#{protocol_display_label(protocol)} #{short_id}"
|
||||
default_role = case protocol
|
||||
when "meshcore" then "COMPANION"
|
||||
else "CLIENT_HIDDEN"
|
||||
end
|
||||
heard_time = coerce_integer(heard_time)
|
||||
inserted = false
|
||||
|
||||
with_busy_retry do
|
||||
db.execute(
|
||||
<<~SQL,
|
||||
INSERT OR IGNORE INTO nodes(node_id,num,short_name,long_name,role,last_heard,first_heard)
|
||||
VALUES (?,?,?,?,?,?,?)
|
||||
INSERT OR IGNORE INTO nodes(node_id,num,short_name,long_name,role,last_heard,first_heard,protocol)
|
||||
VALUES (?,?,?,?,?,?,?,?)
|
||||
SQL
|
||||
[node_id, node_num, short_id, long_name, "CLIENT_HIDDEN", heard_time, heard_time],
|
||||
[node_id, node_num, short_id, long_name, default_role, heard_time, heard_time, protocol],
|
||||
)
|
||||
inserted = db.changes.positive?
|
||||
end
|
||||
|
||||
@@ -147,6 +147,14 @@ module PotatoMesh
|
||||
db.execute("CREATE INDEX IF NOT EXISTS idx_nodes_long_name ON nodes(long_name)")
|
||||
end
|
||||
end
|
||||
|
||||
# Backfill #747: ensure_unknown_node previously omitted the protocol
|
||||
# column and hardcoded role=CLIENT_HIDDEN, causing meshcore placeholder
|
||||
# nodes to be stored as meshtastic/CLIENT_HIDDEN. Fix both in one pass.
|
||||
if node_columns.include?("protocol")
|
||||
db.execute("UPDATE nodes SET protocol = 'meshcore' WHERE long_name LIKE 'Meshcore %' AND protocol = 'meshtastic'")
|
||||
db.execute("UPDATE nodes SET role = 'COMPANION' WHERE protocol = 'meshcore' AND role = 'CLIENT_HIDDEN'")
|
||||
end
|
||||
end
|
||||
|
||||
message_table_exists = db.get_first_value(
|
||||
|
||||
+71
-1
@@ -3022,7 +3022,7 @@ RSpec.describe "Potato Mesh Sinatra app" do
|
||||
db.results_as_hash = true
|
||||
row = db.get_first_row(
|
||||
<<~SQL,
|
||||
SELECT short_name, long_name, role, last_heard, first_heard
|
||||
SELECT short_name, long_name, role, protocol, last_heard, first_heard
|
||||
FROM nodes
|
||||
WHERE node_id = ?
|
||||
SQL
|
||||
@@ -3032,11 +3032,81 @@ RSpec.describe "Potato Mesh Sinatra app" do
|
||||
expect(row["short_name"]).to eq("ABCD")
|
||||
expect(row["long_name"]).to eq("Meshtastic ABCD")
|
||||
expect(row["role"]).to eq("CLIENT_HIDDEN")
|
||||
expect(row["protocol"]).to eq("meshtastic")
|
||||
expect(row["last_heard"]).to eq(reference_time.to_i)
|
||||
expect(row["first_heard"]).to eq(reference_time.to_i)
|
||||
end
|
||||
end
|
||||
|
||||
it "stores meshcore protocol and COMPANION role for meshcore nodes" do
|
||||
with_db do |db|
|
||||
created = ensure_unknown_node(db, "!abcd1234", nil, heard_time: reference_time.to_i, protocol: "meshcore")
|
||||
expect(created).to be_truthy
|
||||
end
|
||||
|
||||
with_db(readonly: true) do |db|
|
||||
db.results_as_hash = true
|
||||
row = db.get_first_row(
|
||||
<<~SQL,
|
||||
SELECT short_name, long_name, role, protocol
|
||||
FROM nodes
|
||||
WHERE node_id = ?
|
||||
SQL
|
||||
["!abcd1234"],
|
||||
)
|
||||
|
||||
expect(row["short_name"]).to eq("1234")
|
||||
expect(row["long_name"]).to eq("Meshcore 1234")
|
||||
expect(row["role"]).to eq("COMPANION")
|
||||
expect(row["protocol"]).to eq("meshcore")
|
||||
end
|
||||
end
|
||||
|
||||
it "defaults to meshtastic protocol and CLIENT_HIDDEN role" do
|
||||
with_db do |db|
|
||||
created = ensure_unknown_node(db, "!beef0000", nil)
|
||||
expect(created).to be_truthy
|
||||
end
|
||||
|
||||
with_db(readonly: true) do |db|
|
||||
db.results_as_hash = true
|
||||
row = db.get_first_row(
|
||||
<<~SQL,
|
||||
SELECT role, protocol
|
||||
FROM nodes
|
||||
WHERE node_id = ?
|
||||
SQL
|
||||
["!beef0000"],
|
||||
)
|
||||
|
||||
expect(row["role"]).to eq("CLIENT_HIDDEN")
|
||||
expect(row["protocol"]).to eq("meshtastic")
|
||||
end
|
||||
end
|
||||
|
||||
it "falls back to CLIENT_HIDDEN for an unknown protocol" do
|
||||
with_db do |db|
|
||||
created = ensure_unknown_node(db, "!cafe9999", nil, protocol: "reticulum")
|
||||
expect(created).to be_truthy
|
||||
end
|
||||
|
||||
with_db(readonly: true) do |db|
|
||||
db.results_as_hash = true
|
||||
row = db.get_first_row(
|
||||
<<~SQL,
|
||||
SELECT role, protocol, long_name
|
||||
FROM nodes
|
||||
WHERE node_id = ?
|
||||
SQL
|
||||
["!cafe9999"],
|
||||
)
|
||||
|
||||
expect(row["role"]).to eq("CLIENT_HIDDEN")
|
||||
expect(row["protocol"]).to eq("reticulum")
|
||||
expect(row["long_name"]).to eq("Reticulum 9999")
|
||||
end
|
||||
end
|
||||
|
||||
it "leaves timestamps nil when no receive time is provided" do
|
||||
with_db do |db|
|
||||
created = ensure_unknown_node(db, "!1111beef", nil)
|
||||
|
||||
@@ -258,4 +258,53 @@ RSpec.describe PotatoMesh::App::Database do
|
||||
|
||||
expect(column_names_for("instances")).to include("contact_link")
|
||||
end
|
||||
|
||||
it "backfills misclassified meshcore placeholder nodes" do
|
||||
SQLite3::Database.new(PotatoMesh::Config.db_path) do |db|
|
||||
db.execute(<<~SQL)
|
||||
CREATE TABLE nodes(
|
||||
node_id TEXT PRIMARY KEY, num INTEGER, short_name TEXT, long_name TEXT,
|
||||
role TEXT, last_heard INTEGER, first_heard INTEGER,
|
||||
protocol TEXT NOT NULL DEFAULT 'meshtastic', synthetic BOOLEAN NOT NULL DEFAULT 0
|
||||
)
|
||||
SQL
|
||||
db.execute("CREATE TABLE messages(id INTEGER PRIMARY KEY)")
|
||||
|
||||
# Misclassified meshcore placeholder (bug #747)
|
||||
db.execute(
|
||||
"INSERT INTO nodes(node_id, short_name, long_name, role, protocol) VALUES (?, ?, ?, ?, ?)",
|
||||
["!aabb0001", "0001", "Meshcore 0001", "CLIENT_HIDDEN", "meshtastic"],
|
||||
)
|
||||
|
||||
# Meshcore node where protocol self-healed but role did not
|
||||
db.execute(
|
||||
"INSERT INTO nodes(node_id, short_name, long_name, role, protocol) VALUES (?, ?, ?, ?, ?)",
|
||||
["!aabb0002", "0002", "SomeNode", "CLIENT_HIDDEN", "meshcore"],
|
||||
)
|
||||
|
||||
# Meshtastic node that should remain untouched
|
||||
db.execute(
|
||||
"INSERT INTO nodes(node_id, short_name, long_name, role, protocol) VALUES (?, ?, ?, ?, ?)",
|
||||
["!aabb0003", "0003", "Meshtastic 0003", "CLIENT_HIDDEN", "meshtastic"],
|
||||
)
|
||||
end
|
||||
|
||||
harness_class.ensure_schema_upgrades
|
||||
|
||||
SQLite3::Database.new(PotatoMesh::Config.db_path, readonly: true) do |db|
|
||||
db.results_as_hash = true
|
||||
|
||||
fixed_proto = db.get_first_row("SELECT protocol, role FROM nodes WHERE node_id = '!aabb0001'")
|
||||
expect(fixed_proto["protocol"]).to eq("meshcore")
|
||||
expect(fixed_proto["role"]).to eq("COMPANION")
|
||||
|
||||
fixed_role = db.get_first_row("SELECT protocol, role FROM nodes WHERE node_id = '!aabb0002'")
|
||||
expect(fixed_role["protocol"]).to eq("meshcore")
|
||||
expect(fixed_role["role"]).to eq("COMPANION")
|
||||
|
||||
untouched = db.get_first_row("SELECT protocol, role FROM nodes WHERE node_id = '!aabb0003'")
|
||||
expect(untouched["protocol"]).to eq("meshtastic")
|
||||
expect(untouched["role"]).to eq("CLIENT_HIDDEN")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user