Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions apps/plug_sync/.formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Used by "mix format"
[
import_deps: [:plug, :ecto, :phoenix_sync],
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
]
25 changes: 25 additions & 0 deletions apps/plug_sync/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# The directory Mix will write compiled artifacts to.
/_build/

# If you run "mix test --cover", coverage assets end up here.
/cover/

# The directory Mix downloads your dependencies sources to.
/deps/

# Where third-party dependencies like ExDoc output generated docs.
/doc/

# If the VM crashes, it generates a dump, let's ignore it too.
erl_crash.dump

# Also ignore archive artifacts (built via "mix archive.build").
*.ez

# Ignore package tarball (built via "mix hex.build").
plug_sync-*.tar

# Temporary files, for example, from tests.
/tmp/

/persistent/
7 changes: 7 additions & 0 deletions apps/plug_sync/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# PlugSync

A test Plug app for easy validation of Phoenix.Sync features within a real app.

Use `PHOENIX_SYNC_MODE` to set the interaction mode, either `"http"` or `"embedded"`.

In `http` mode, you should run an Electric server on port 3000.
3 changes: 3 additions & 0 deletions apps/plug_sync/config/config.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Config

import_config "#{config_env()}.exs"
35 changes: 35 additions & 0 deletions apps/plug_sync/config/dev.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import Config

config :plug_sync, ecto_repos: [PlugSync.Repo], start_server: false

case System.get_env("PHOENIX_SYNC_MODE", "embedded") do
"http" ->
IO.puts("Starting in HTTP mode")

config :phoenix_sync,
mode: :http,
env: config_env(),
url: "http://localhost:3000"

config :plug_sync, PlugSync.Repo,
username: "postgres",
password: "password",
hostname: "localhost",
database: "electric",
port: 54321

_ ->
IO.puts("Starting in embedded mode")

config :phoenix_sync,
mode: :embedded,
env: config_env(),
repo: PlugSync.Repo

config :plug_sync, PlugSync.Repo,
username: "postgres",
password: "password",
hostname: "localhost",
database: "plug_sync",
port: 55555
end
1 change: 1 addition & 0 deletions apps/plug_sync/config/prod.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import Config
3 changes: 3 additions & 0 deletions apps/plug_sync/config/test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Config

config :phoenix_sync, mode: :sandbox, env: config_env()
37 changes: 37 additions & 0 deletions apps/plug_sync/lib/mix/tasks/plug_sync.insert.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
defmodule Mix.Tasks.PlugSync.Insert do
use Mix.Task

@shortdoc "Inserts sample data into the database for testing PlugSync"

alias PlugSync.Repo
alias PlugSync.Tasks.Task
alias PlugSync.Tasks.Step

def run(args) do
{opts, _, _} = OptionParser.parse(args, strict: [rows: :integer, data_size: :integer])

# {:ok, repo} = Repo.start_link()
Application.ensure_all_started(:plug_sync) |> dbg

data_size = Keyword.get(opts, :data_size, 1024)
rows = Keyword.get(opts, :rows, 1024)

Repo.transaction(fn ->

items = Stream.repeatedly(fn -> item(data_size) end) |> Enum.take(rows)
Repo.insert_all(PlugSync.Item, items)

end)

IO.puts("Sample data inserted successfully.")
end

defp item(data_size) do
%{
value: Enum.random(1..100_000),
data: :crypto.strong_rand_bytes(div(data_size , 2) ) |> Base.encode16(),
inserted_at: NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second),
updated_at: NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second),
}
end
end
18 changes: 18 additions & 0 deletions apps/plug_sync/lib/mix/tasks/plug_sync.server.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
defmodule Mix.Tasks.PlugSync.Server do
use Mix.Task

@shortdoc "Starts a PlugSync server"

def run(_args) do
Application.put_env(:plug_sync, :server, true, persistent: true)
Mix.Tasks.Run.run(run_args())
end

defp run_args do
if iex_running?(), do: [], else: ["--no-halt"]
end

defp iex_running? do
Code.ensure_loaded?(IEx) and IEx.started?()
end
end
18 changes: 18 additions & 0 deletions apps/plug_sync/lib/plug_sync.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
defmodule PlugSync do
@moduledoc """
Documentation for `PlugSync`.
"""

@doc """
Hello world.

## Examples

iex> PlugSync.hello()
:world

"""
def hello do
:world
end
end
29 changes: 29 additions & 0 deletions apps/plug_sync/lib/plug_sync/application.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
defmodule PlugSync.Application do
# See https://hexdocs.pm/elixir/Application.html
# for more information on OTP Applications
@moduledoc false

use Application

@impl true
def start(_type, _args) do
server =
if Application.get_env(:plug_sync, :server, false) do
[
{Bandit, plug: {PlugSync.Router, phoenix_sync: Phoenix.Sync.plug_opts()}, port: 4444}
]
else
[]
end

children =
[
PlugSync.Repo
] ++ server

# See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: PlugSync.Supervisor]
Supervisor.start_link(children, opts)
end
end
11 changes: 11 additions & 0 deletions apps/plug_sync/lib/plug_sync/item.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
defmodule PlugSync.Item do
use Ecto.Schema

schema "items" do
field :name, :string
field :value, :integer
field :data, :string

timestamps()
end
end
7 changes: 7 additions & 0 deletions apps/plug_sync/lib/plug_sync/repo.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
defmodule PlugSync.Repo do
use Phoenix.Sync.Sandbox.Postgres

use Ecto.Repo,
otp_app: :plug_sync,
adapter: Phoenix.Sync.Sandbox.Postgres.adapter()
end
19 changes: 19 additions & 0 deletions apps/plug_sync/lib/plug_sync/router.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
defmodule PlugSync.Router do
use Plug.Router, copy_opts_to_assign: :options
use Phoenix.Sync.Router

plug :match
plug :dispatch

sync "/items-mapped", table: "items", transform: &PlugSync.Router.map_item/1

match _ do
send_resp(conn, 404, "not found")
end

def map_item(item) do
[
Map.update!(item, "value", &Map.update!(&1, "name", fn name -> "#{name} mapped #{&1["id"]}" end)),
]
end
end
34 changes: 34 additions & 0 deletions apps/plug_sync/mix.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
defmodule PlugSync.MixProject do
use Mix.Project

def project do
[
app: :plug_sync,
version: "0.1.0",
elixir: "~> 1.18",
start_permanent: Mix.env() == :prod,
deps: deps()
]
end

# Run "mix help compile.app" to learn about applications.
def application do
[
extra_applications: [:logger],
mod: {PlugSync.Application, []}
]
end

# Run "mix help deps" to learn about dependencies.
defp deps do
[
{:plug, "~> 1.0"},
{:bandit, "~> 1.0"},
{:postgrex, "~> 0.21"},
{:ecto_sql, "~> 3.0"},
{:electric, "~> 1.1.2"},
{:phoenix_sync, [path: "../..", override: true]},
{:igniter, "~> 0.6"}
]
end
end
Loading
Loading