Add SQL queries to find numbers from local db

Amolith created

References: https://soprani.ca/todo/323
Signed-off-by: Amolith <amolith@secluded.site>

Change summary

lib/tel_selections.rb       |  57 +++++++++++++++++-
test/test_tel_selections.rb | 121 +++++++++++++++++++++++++++++++++++++++
2 files changed, 174 insertions(+), 4 deletions(-)

Detailed changes

lib/tel_selections.rb 🔗

@@ -237,7 +237,7 @@ class TelSelections
 				end
 			end
 
-			def initialize(q)
+			def initialize(q, **)
 				@q = q
 			end
 
@@ -248,9 +248,7 @@ class TelSelections
 			{
 				areaCode: [:AreaCode, /\A[2-9][0-9]{2}\Z/],
 				npaNxx: [:NpaNxx, /\A(?:[2-9][0-9]{2}){2}\Z/],
-				npaNxxx: [:NpaNxxx, /\A(?:[2-9][0-9]{2}){2}[0-9]\Z/],
-				zip: [:PostalCode, /\A\d{5}(?:-\d{4})?\Z/],
-				localVanity: [:LocalVanity, /\A~(.+)\Z/]
+				npaNxxx: [:NpaNxxx, /\A(?:[2-9][0-9]{2}){2}[0-9]\Z/]
 			}.each do |k, args|
 				klass = const_set(
 					args[0],
@@ -258,6 +256,10 @@ class TelSelections
 						define_method(:iris_query) do
 							{ k => @q }
 						end
+
+						define_method(:sql_query) do
+							["SELECT * FROM tel_inventory WHERE tel LIKE ?", "+1#{@q}%"]
+						end
 					}
 				)
 
@@ -266,6 +268,42 @@ class TelSelections
 				end
 			end
 
+			class PostalCode < Q
+				Q.register(/\A\d{5}(?:-\d{4})?\Z/, &method(:new))
+
+				def iris_query
+					{ zip: @q }
+				end
+
+				def sql_query
+					nil
+				end
+			end
+
+			class LocalVanity < Q
+				Q.register(/\A~(.+)\Z/, &method(:new))
+
+				def iris_query
+					{ localVanity: @q }
+				end
+
+				def sql_query
+					["SELECT * FROM tel_inventory WHERE tel LIKE ?", "%#{q_digits}%"]
+				end
+
+				def q_digits
+					@q
+						.gsub(/[ABC]/i, "2")
+						.gsub(/[DEF]/i, "3")
+						.gsub(/[GHI]/i, "4")
+						.gsub(/[JKL]/i, "5")
+						.gsub(/[MNO]/i, "6")
+						.gsub(/[PQRS]/i, "7")
+						.gsub(/[TUV]/i, "8")
+						.gsub(/[WXYZ]/i, "9")
+				end
+			end
+
 			class State
 				Q.register(/\A[a-zA-Z]{2}\Z/, &method(:new))
 
@@ -285,6 +323,10 @@ class TelSelections
 					{ state: @state }
 				end
 
+				def sql_query
+					["SELECT * FROM tel_inventory WHERE region = ?", @state]
+				end
+
 				def to_s
 					@state
 				end
@@ -328,6 +370,13 @@ class TelSelections
 					@state.iris_query.merge(city: @city)
 				end
 
+				def sql_query
+					[
+						"SELECT * FROM tel_inventory WHERE region = ? AND locality = ?",
+						@state.to_s, @city
+					]
+				end
+
 				def to_s
 					"#{@city}, #{@state}"
 				end

test/test_tel_selections.rb 🔗

@@ -168,41 +168,102 @@ class TelSelectionsTest < Minitest::Test
 			assert_equal({ areaCode: "226" }, q.iris_query)
 		end
 
+		def test_for_area_code_sql
+			q = TelSelections::ChooseTel::Q.for("226")
+			assert_equal(
+				["SELECT * FROM tel_inventory WHERE tel LIKE ?", "+1226%"],
+				q.sql_query
+			)
+		end
+
 		def test_for_npanxx
 			q = TelSelections::ChooseTel::Q.for("226666")
 			assert_equal({ npaNxx: "226666" }, q.iris_query)
 		end
 
+		def test_for_npanxx_sql
+			q = TelSelections::ChooseTel::Q.for("226666")
+			assert_equal(
+				["SELECT * FROM tel_inventory WHERE tel LIKE ?", "+1226666%"],
+				q.sql_query
+			)
+		end
+
 		def test_for_npanxxx
 			q = TelSelections::ChooseTel::Q.for("2266667")
 			assert_equal({ npaNxxx: "2266667" }, q.iris_query)
 		end
 
+		def test_for_npanxxx_sql
+			q = TelSelections::ChooseTel::Q.for("2266667")
+			assert_equal(
+				["SELECT * FROM tel_inventory WHERE tel LIKE ?", "+12266667%"],
+				q.sql_query
+			)
+		end
+
 		def test_for_zip
 			q = TelSelections::ChooseTel::Q.for("90210")
 			assert_equal({ zip: "90210" }, q.iris_query)
 		end
 
+		def test_for_zip_sql
+			q = TelSelections::ChooseTel::Q.for("90210")
+			refute q.sql_query
+		end
+
 		def test_for_localvanity
 			q = TelSelections::ChooseTel::Q.for("~mboa")
 			assert_equal({ localVanity: "mboa" }, q.iris_query)
 		end
 
+		def test_for_localvanity_sql
+			q = TelSelections::ChooseTel::Q.for("~mboa")
+			assert_equal(
+				["SELECT * FROM tel_inventory WHERE tel LIKE ?", "%6262%"],
+				q.sql_query
+			)
+		end
+
 		def test_for_state
 			q = TelSelections::ChooseTel::Q.for("ON")
 			assert_equal({ state: "ON" }, q.iris_query)
 		end
 
+		def test_for_state_sql
+			q = TelSelections::ChooseTel::Q.for("ON")
+			assert_equal(
+				["SELECT * FROM tel_inventory WHERE region = ?", "ON"],
+				q.sql_query
+			)
+		end
+
 		def test_for_state_name
 			q = TelSelections::ChooseTel::Q.for("ontario")
 			assert_equal({ state: "ON" }, q.iris_query)
 		end
 
+		def test_for_state_name_sql
+			q = TelSelections::ChooseTel::Q.for("ontario")
+			assert_equal(
+				["SELECT * FROM tel_inventory WHERE region = ?", "ON"],
+				q.sql_query
+			)
+		end
+
 		def test_for_new_york
 			q = TelSelections::ChooseTel::Q.for("New York")
 			assert_equal({ state: "NY" }, q.iris_query)
 		end
 
+		def test_for_new_york_sql
+			q = TelSelections::ChooseTel::Q.for("New York")
+			assert_equal(
+				["SELECT * FROM tel_inventory WHERE region = ?", "NY"],
+				q.sql_query
+			)
+		end
+
 		def test_for_new_york_ny
 			q = TelSelections::ChooseTel::Q.for(
 				"New York, NY",
@@ -212,6 +273,21 @@ class TelSelectionsTest < Minitest::Test
 			assert_equal({ city: "New York City", state: "NY" }, q.iris_query)
 		end
 
+		def test_for_new_york_ny_sql
+			q = TelSelections::ChooseTel::Q.for(
+				"New York, NY",
+				db: FakeDB.new,
+				memcache: FakeMemcache.new
+			)
+			assert_equal(
+				[
+					"SELECT * FROM tel_inventory WHERE region = ? AND locality = ?",
+					"NY", "New York City"
+				],
+				q.sql_query
+			)
+		end
+
 		def test_for_new_york_new_york
 			q = TelSelections::ChooseTel::Q.for(
 				"New York, New York",
@@ -221,6 +297,21 @@ class TelSelectionsTest < Minitest::Test
 			assert_equal({ city: "New York City", state: "NY" }, q.iris_query)
 		end
 
+		def test_for_new_york_new_york_sql
+			q = TelSelections::ChooseTel::Q.for(
+				"New York, New York",
+				db: FakeDB.new,
+				memcache: FakeMemcache.new
+			)
+			assert_equal(
+				[
+					"SELECT * FROM tel_inventory WHERE region = ? AND locality = ?",
+					"NY", "New York City"
+				],
+				q.sql_query
+			)
+		end
+
 		def test_for_citystate
 			q = TelSelections::ChooseTel::Q.for(
 				"Toronto, ON",
@@ -230,6 +321,21 @@ class TelSelectionsTest < Minitest::Test
 			assert_equal({ city: "Toronto", state: "ON" }, q.iris_query)
 		end
 
+		def test_for_citystate_sql
+			q = TelSelections::ChooseTel::Q.for(
+				"Toronto, ON",
+				db: FakeDB.new,
+				memcache: FakeMemcache.new
+			)
+			assert_equal(
+				[
+					"SELECT * FROM tel_inventory WHERE region = ? AND locality = ?",
+					"ON", "Toronto"
+				],
+				q.sql_query
+			)
+		end
+
 		def test_for_citystate_name
 			q = TelSelections::ChooseTel::Q.for(
 				"Toronto, Ontario",
@@ -239,6 +345,21 @@ class TelSelectionsTest < Minitest::Test
 			assert_equal({ city: "Toronto", state: "ON" }, q.iris_query)
 		end
 
+		def test_for_citystate_name_sql
+			q = TelSelections::ChooseTel::Q.for(
+				"Toronto, Ontario",
+				db: FakeDB.new,
+				memcache: FakeMemcache.new
+			)
+			assert_equal(
+				[
+					"SELECT * FROM tel_inventory WHERE region = ? AND locality = ?",
+					"ON", "Toronto"
+				],
+				q.sql_query
+			)
+		end
+
 		def test_for_garbage
 			assert_raises { TelSelections::ChooseTel::Q.for("garbage") }
 		end