diff --git a/lib/pod/cli.rb b/lib/pod/cli.rb index 4d173ca..923b19a 100644 --- a/lib/pod/cli.rb +++ b/lib/pod/cli.rb @@ -52,9 +52,9 @@ def podcasts method_option :order_by, type: :string, default: "id", desc: "Choose how pod will order the episodes." method_option :all, type: :boolean, default: false, desc: "List archived episodes too." def episodes(podcast_id) - result = Pod::Commands::Episodes.call(podcast_id, options) + result = Pod::Commands::Episodes::Runner.call(podcast_id, options) - puts Pod::Outputs::Text::Episodes.call(result) + puts Pod::Commands::Episodes::Output.call(result) end desc "open EPISODE_ID", "Open a episode in the browser" @@ -70,23 +70,23 @@ def open(episode_id) desc "archive EPISODE_ID", "Archive the episode" def archive(episode_id) - result = Pod::Commands::Archive.call(episode_id) + result = Pod::Commands::Archive::Runner.call(episode_id) - puts Pod::Outputs::Text::Archive.call(result) + puts Pod::Commands::Archive::Output.call(result) end desc "dearchive EPISODE_ID", "Dearchive the episode." def dearchive(episode_id) - result = Pod::Commands::Dearchive.call(episode_id) + result = Pod::Commands::Dearchive::Runner.call(episode_id) - puts Pod::Outputs::Text::Dearchive.call(result) + puts Pod::Commands::Dearchive::Output.call(result) end desc "delete PODCAST_ID", "Delete the podcast from pod's database." def delete(podcast_id) - result = Pod::Commands::Delete.call(podcast_id) + result = Pod::Commands::Delete::Runner.call(podcast_id) - puts Pod::Outputs::Text::Delete.call(result) + puts Pod::Commands::Delete::Output.call(result) end desc "sync PODCAST_ID", "Sync the podcast." diff --git a/lib/pod/commands.rb b/lib/pod/commands.rb index 22ef1b7..5a15940 100644 --- a/lib/pod/commands.rb +++ b/lib/pod/commands.rb @@ -4,14 +4,18 @@ require_relative "commands/base_output" require_relative "commands/add/runner" require_relative "commands/add/output" +require_relative "commands/archive/runner" +require_relative "commands/archive/output" +require_relative "commands/dearchive/runner" +require_relative "commands/dearchive/output" +require_relative "commands/delete/runner" +require_relative "commands/delete/output" +require_relative "commands/episodes/runner" +require_relative "commands/episodes/output" require_relative "commands/init" require_relative "commands/podcasts" -require_relative "commands/episodes" require_relative "commands/open" -require_relative "commands/archive" -require_relative "commands/dearchive" -require_relative "commands/delete" require_relative "commands/sync" require_relative "commands/update" diff --git a/lib/pod/commands/archive.rb b/lib/pod/commands/archive.rb deleted file mode 100644 index 4381763..0000000 --- a/lib/pod/commands/archive.rb +++ /dev/null @@ -1,24 +0,0 @@ -# frozen_string_literal: true - -module Pod - module Commands - class Archive < Pod::Commands::BaseRunner - def call(episode_id) - db = Infrastructure::Storage::SQL.new(db: pod_db_dir) - - if db.query("select id from episodes where id = #{episode_id}").empty? - return build_failure_response(details: :not_found) - end - - sql_code = <<~SQL - update episodes - set archived_at = '#{Time.now.iso8601}' - where id = #{episode_id}; - SQL - db.execute(sql_code) - - build_success_response(details: :episode_archived) - end - end - end -end diff --git a/lib/pod/outputs/text/archive.rb b/lib/pod/commands/archive/output.rb similarity index 80% rename from lib/pod/outputs/text/archive.rb rename to lib/pod/commands/archive/output.rb index 33a4854..1e4fb5b 100644 --- a/lib/pod/outputs/text/archive.rb +++ b/lib/pod/commands/archive/output.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true module Pod - module Outputs - module Text - class Archive < ::Pod::Commands::BaseOutput + module Commands + module Archive + class Output < ::Pod::Commands::BaseOutput def call case @context[:details] when :episode_archived diff --git a/lib/pod/commands/archive/runner.rb b/lib/pod/commands/archive/runner.rb new file mode 100644 index 0000000..20d26e7 --- /dev/null +++ b/lib/pod/commands/archive/runner.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module Pod + module Commands + module Archive + class Runner < Pod::Commands::BaseRunner + def call(episode_id) + db = Infrastructure::Storage::SQL.new(db: pod_db_dir) + + if db.query("select id from episodes where id = #{episode_id}").empty? + return build_failure_response(details: :not_found) + end + + sql_code = <<~SQL + update episodes + set archived_at = '#{Time.now.iso8601}' + where id = #{episode_id}; + SQL + db.execute(sql_code) + + build_success_response(details: :episode_archived) + end + end + end + end +end diff --git a/lib/pod/commands/dearchive.rb b/lib/pod/commands/dearchive.rb deleted file mode 100644 index 4ec6af2..0000000 --- a/lib/pod/commands/dearchive.rb +++ /dev/null @@ -1,24 +0,0 @@ -# frozen_string_literal: true - -module Pod - module Commands - class Dearchive < Pod::Commands::BaseRunner - def call(episode_id) - db = Infrastructure::Storage::SQL.new(db: pod_db_dir) - - if db.query("select id from episodes where id = #{episode_id}").empty? - return build_failure_response(details: :not_found) - end - - sql_code = <<~SQL - update episodes - set archived_at = null - where id = #{episode_id}; - SQL - db.execute(sql_code) - - build_success_response(details: :episode_dearchived) - end - end - end -end diff --git a/lib/pod/outputs/text/dearchive.rb b/lib/pod/commands/dearchive/output.rb similarity index 80% rename from lib/pod/outputs/text/dearchive.rb rename to lib/pod/commands/dearchive/output.rb index dcf642a..a5b51b5 100644 --- a/lib/pod/outputs/text/dearchive.rb +++ b/lib/pod/commands/dearchive/output.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true module Pod - module Outputs - module Text - class Dearchive < ::Pod::Commands::BaseOutput + module Commands + module Dearchive + class Output < ::Pod::Commands::BaseOutput def call case @context[:details] when :episode_dearchived diff --git a/lib/pod/commands/dearchive/runner.rb b/lib/pod/commands/dearchive/runner.rb new file mode 100644 index 0000000..0185e7d --- /dev/null +++ b/lib/pod/commands/dearchive/runner.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module Pod + module Commands + module Dearchive + class Runner < Pod::Commands::BaseRunner + def call(episode_id) + db = Infrastructure::Storage::SQL.new(db: pod_db_dir) + + if db.query("select id from episodes where id = #{episode_id}").empty? + return build_failure_response(details: :not_found) + end + + sql_code = <<~SQL + update episodes + set archived_at = null + where id = #{episode_id}; + SQL + db.execute(sql_code) + + build_success_response(details: :episode_dearchived) + end + end + end + end +end diff --git a/lib/pod/commands/delete.rb b/lib/pod/commands/delete.rb deleted file mode 100644 index 22f4413..0000000 --- a/lib/pod/commands/delete.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -module Pod - module Commands - class Delete < Pod::Commands::BaseRunner - def call(podcast_id) - db = Infrastructure::Storage::SQL.new(db: pod_db_dir) - - if db.query("select id from podcasts where id = #{podcast_id}").empty? - return build_failure_response(details: :not_found) - end - - sql_code = <<~SQL - delete from episodes - where podcast_id = #{podcast_id}; - SQL - db.execute(sql_code) - - sql_code = <<~SQL - delete from podcasts - where id = #{podcast_id}; - SQL - db.execute(sql_code) - - build_success_response(details: :podcast_deleted) - end - end - end -end diff --git a/lib/pod/outputs/text/delete.rb b/lib/pod/commands/delete/output.rb similarity index 81% rename from lib/pod/outputs/text/delete.rb rename to lib/pod/commands/delete/output.rb index e284879..1f56258 100644 --- a/lib/pod/outputs/text/delete.rb +++ b/lib/pod/commands/delete/output.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true module Pod - module Outputs - module Text - class Delete < ::Pod::Commands::BaseOutput + module Commands + module Delete + class Output < ::Pod::Commands::BaseOutput def call case @context[:details] when :podcast_deleted diff --git a/lib/pod/commands/delete/runner.rb b/lib/pod/commands/delete/runner.rb new file mode 100644 index 0000000..5f817b1 --- /dev/null +++ b/lib/pod/commands/delete/runner.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module Pod + module Commands + module Delete + class Runner < Pod::Commands::BaseRunner + def call(podcast_id) + db = Infrastructure::Storage::SQL.new(db: pod_db_dir) + + if db.query("select id from podcasts where id = #{podcast_id}").empty? + return build_failure_response(details: :not_found) + end + + sql_code = <<~SQL + delete from episodes + where podcast_id = #{podcast_id}; + SQL + db.execute(sql_code) + + sql_code = <<~SQL + delete from podcasts + where id = #{podcast_id}; + SQL + db.execute(sql_code) + + build_success_response(details: :podcast_deleted) + end + end + end + end +end diff --git a/lib/pod/commands/episodes.rb b/lib/pod/commands/episodes.rb deleted file mode 100644 index c65971a..0000000 --- a/lib/pod/commands/episodes.rb +++ /dev/null @@ -1,43 +0,0 @@ -module Pod - module Commands - class Episodes < Pod::Commands::BaseRunner - ALL_COLUMNS = %w[id title release_date duration link].freeze - private_constant :ALL_COLUMNS - - def call(podcast_id, options = {}) - parsed_options = parse_options(options) - - columns = parsed_options["fields"] || ALL_COLUMNS - sql_code = <<~SQL - select #{columns.join(", ")} - from episodes - where podcast_id = #{podcast_id} - SQL - - unless parsed_options["all"] - sql_code << "and archived_at is null\n" - end - - order_by = parsed_options["order_by"] || "id" - sql_code << "order by #{order_by};\n" - - db = Infrastructure::Storage::SQL.new(db: pod_db_dir) - records = db.query(sql_code) - - build_success_response( - details: records.empty? ? :not_found : :records_found, - metadata: {records: records, columns: columns} - ) - rescue Infrastructure::Storage::Exceptions::WrongSyntax => exc - cause = exc.message - if cause.include?("no such column") - invalid_column = cause.delete_prefix("no such column: ") - build_failure_response( - details: :invalid_column, - metadata: {invalid_column: invalid_column} - ) - end - end - end - end -end diff --git a/lib/pod/outputs/text/episodes.rb b/lib/pod/commands/episodes/output.rb similarity index 88% rename from lib/pod/outputs/text/episodes.rb rename to lib/pod/commands/episodes/output.rb index a1f18f6..def358f 100644 --- a/lib/pod/outputs/text/episodes.rb +++ b/lib/pod/commands/episodes/output.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true module Pod - module Outputs - module Text - class Episodes < ::Pod::Commands::BaseOutput + module Commands + module Episodes + class Output < ::Pod::Commands::BaseOutput def call case @context[:details] when :records_found diff --git a/lib/pod/commands/episodes/runner.rb b/lib/pod/commands/episodes/runner.rb new file mode 100644 index 0000000..a052f6d --- /dev/null +++ b/lib/pod/commands/episodes/runner.rb @@ -0,0 +1,45 @@ +module Pod + module Commands + module Episodes + class Runner < Pod::Commands::BaseRunner + ALL_COLUMNS = %w[id title release_date duration link].freeze + private_constant :ALL_COLUMNS + + def call(podcast_id, options = {}) + parsed_options = parse_options(options) + + columns = parsed_options["fields"] || ALL_COLUMNS + sql_code = <<~SQL + select #{columns.join(", ")} + from episodes + where podcast_id = #{podcast_id} + SQL + + unless parsed_options["all"] + sql_code << "and archived_at is null\n" + end + + order_by = parsed_options["order_by"] || "id" + sql_code << "order by #{order_by};\n" + + db = Infrastructure::Storage::SQL.new(db: pod_db_dir) + records = db.query(sql_code) + + build_success_response( + details: records.empty? ? :not_found : :records_found, + metadata: {records: records, columns: columns} + ) + rescue Infrastructure::Storage::Exceptions::WrongSyntax => exc + cause = exc.message + if cause.include?("no such column") + invalid_column = cause.delete_prefix("no such column: ") + build_failure_response( + details: :invalid_column, + metadata: {invalid_column: invalid_column} + ) + end + end + end + end + end +end diff --git a/lib/pod/outputs/text.rb b/lib/pod/outputs/text.rb index ecc7028..3017e47 100644 --- a/lib/pod/outputs/text.rb +++ b/lib/pod/outputs/text.rb @@ -2,11 +2,7 @@ require_relative "text/init" require_relative "text/podcasts" -require_relative "text/episodes" require_relative "text/open" -require_relative "text/archive" -require_relative "text/dearchive" -require_relative "text/delete" require_relative "text/sync" require_relative "text/update" diff --git a/spec/pod/outputs/text/archive_spec.rb b/spec/pod/commands/archive/output_spec.rb similarity index 93% rename from spec/pod/outputs/text/archive_spec.rb rename to spec/pod/commands/archive/output_spec.rb index fd97a7e..c2edb25 100644 --- a/spec/pod/outputs/text/archive_spec.rb +++ b/spec/pod/commands/archive/output_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.describe Pod::Outputs::Text::Archive do +RSpec.describe Pod::Commands::Archive::Output do describe "#call" do context "when episode was archived" do it "generates the correct message" do diff --git a/spec/pod/commands/archive_spec.rb b/spec/pod/commands/archive/runner_spec.rb similarity index 90% rename from spec/pod/commands/archive_spec.rb rename to spec/pod/commands/archive/runner_spec.rb index 48d548f..a6b08d9 100644 --- a/spec/pod/commands/archive_spec.rb +++ b/spec/pod/commands/archive/runner_spec.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true -require_relative "../../support/test_helpers" +require_relative "../../../support/test_helpers" -RSpec.describe Pod::Commands::Archive do +RSpec.describe Pod::Commands::Archive::Runner do describe "#call", :init_pod do context "when episode is found", :populate_db do it "archive the episode and returns a success response" do diff --git a/spec/pod/outputs/text/dearchive_spec.rb b/spec/pod/commands/dearchive/output_spec.rb similarity index 93% rename from spec/pod/outputs/text/dearchive_spec.rb rename to spec/pod/commands/dearchive/output_spec.rb index 3693112..c136bb4 100644 --- a/spec/pod/outputs/text/dearchive_spec.rb +++ b/spec/pod/commands/dearchive/output_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.describe Pod::Outputs::Text::Dearchive do +RSpec.describe Pod::Commands::Dearchive::Output do describe "#call" do context "when episode was dearchived" do it "generates the correct message" do diff --git a/spec/pod/commands/dearchive_spec.rb b/spec/pod/commands/dearchive/runner_spec.rb similarity index 85% rename from spec/pod/commands/dearchive_spec.rb rename to spec/pod/commands/dearchive/runner_spec.rb index 9d0073f..e488c32 100644 --- a/spec/pod/commands/dearchive_spec.rb +++ b/spec/pod/commands/dearchive/runner_spec.rb @@ -1,14 +1,14 @@ # frozen_string_literal: true -require_relative "../../support/test_helpers" +require_relative "../../../support/test_helpers" -RSpec.describe Pod::Commands::Dearchive do +RSpec.describe Pod::Commands::Dearchive::Runner do describe "#call", :init_pod do context "when episode is found", :populate_db do it "dearchive the episode and returns a success response" do db = Infrastructure::Storage::SQL.new(db: TestHelpers::Path.db_dir) - Pod::Commands::Archive.call(1) + Pod::Commands::Archive::Runner.call(1) result = described_class.call(1) expect(result[:status]).to eq(:success) diff --git a/spec/pod/outputs/text/delete_spec.rb b/spec/pod/commands/delete/output_spec.rb similarity index 94% rename from spec/pod/outputs/text/delete_spec.rb rename to spec/pod/commands/delete/output_spec.rb index 98f03a3..75c54c6 100644 --- a/spec/pod/outputs/text/delete_spec.rb +++ b/spec/pod/commands/delete/output_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.describe Pod::Outputs::Text::Delete do +RSpec.describe Pod::Commands::Delete::Output do describe "#call" do context "when podcast was deleted" do it "generates the correct message" do diff --git a/spec/pod/commands/delete_spec.rb b/spec/pod/commands/delete/runner_spec.rb similarity index 90% rename from spec/pod/commands/delete_spec.rb rename to spec/pod/commands/delete/runner_spec.rb index 3b6f545..f1fc550 100644 --- a/spec/pod/commands/delete_spec.rb +++ b/spec/pod/commands/delete/runner_spec.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true -require_relative "../../support/test_helpers" +require_relative "../../../support/test_helpers" -RSpec.describe Pod::Commands::Delete do +RSpec.describe Pod::Commands::Delete::Runner do describe "#call", :init_pod do context "when the podcast is found", :populate_db do it "delete the podcast and its episodes" do diff --git a/spec/pod/outputs/text/episodes_spec.rb b/spec/pod/commands/episodes/output_spec.rb similarity index 98% rename from spec/pod/outputs/text/episodes_spec.rb rename to spec/pod/commands/episodes/output_spec.rb index 723e2d4..735cb64 100644 --- a/spec/pod/outputs/text/episodes_spec.rb +++ b/spec/pod/commands/episodes/output_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.describe Pod::Outputs::Text::Episodes do +RSpec.describe Pod::Commands::Episodes::Output do describe "#call" do context "when records are found" do it "generates the correct message" do diff --git a/spec/pod/commands/episodes_spec.rb b/spec/pod/commands/episodes/runner_spec.rb similarity index 96% rename from spec/pod/commands/episodes_spec.rb rename to spec/pod/commands/episodes/runner_spec.rb index 87adbbe..f8435f6 100644 --- a/spec/pod/commands/episodes_spec.rb +++ b/spec/pod/commands/episodes/runner_spec.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true -require_relative "../../support/test_helpers" +require_relative "../../../support/test_helpers" -RSpec.describe Pod::Commands::Episodes do +RSpec.describe Pod::Commands::Episodes::Runner do describe "#call", :init_pod do context "when there are episodes", :populate_db do it "returns a success response with the table records" do @@ -82,7 +82,7 @@ context "when there are archived episodes", :populate_db do it "ignores them" do - Pod::Commands::Archive.call(3) + Pod::Commands::Archive::Runner.call(3) result = described_class.call(1) expect(result[:status]).to eq(:success) @@ -102,7 +102,7 @@ context "when there are archived episodes, but the all option is used", :populate_db do it "returns all episodes, including the archived ones" do - Pod::Commands::Archive.call(3) + Pod::Commands::Archive::Runner.call(3) result = described_class.call(1, {"all" => true}) expect(result[:status]).to eq(:success)