Skip to content

Commit

Permalink
first
Browse files Browse the repository at this point in the history
  • Loading branch information
jpiepkow committed Mar 10, 2018
0 parents commit a37bf83
Show file tree
Hide file tree
Showing 10 changed files with 233 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Used by "mix format"
[
inputs: ["mix.exs", "{config,lib,test}/**/*.{ex,exs}"]
]
24 changes: 24 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# 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 3rd-party dependencies like ExDoc output generated docs.
/doc/

# Ignore .fetch files in case you like to edit your project deps locally.
/.fetch

# 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").
sync_m-*.tar

21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# SyncM

**TODO: Add description**

## Installation

If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `sync_m` to your list of dependencies in `mix.exs`:

```elixir
def deps do
[
{:sync_m, "~> 0.1.0"}
]
end
```

Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
be found at [https://hexdocs.pm/sync_m](https://hexdocs.pm/sync_m).

30 changes: 30 additions & 0 deletions config/config.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This file is responsible for configuring your application
# and its dependencies with the aid of the Mix.Config module.
use Mix.Config

# This configuration is loaded before any dependency and is restricted
# to this project. If another project depends on this project, this
# file won't be loaded nor affect the parent project. For this reason,
# if you want to provide default values for your application for
# 3rd-party users, it should be done in your "mix.exs" file.

# You can configure your application as:
#
# config :sync_m, key: :value
#
# and access this configuration in your application as:
#
# Application.get_env(:sync_m, :key)
#
# You can also configure a 3rd-party app:
#
# config :logger, level: :info
#

# It is also possible to import configuration files, relative to this
# directory. For example, you can emulate configuration per environment
# by uncommenting the line below and defining dev.exs, test.exs and such.
# Configuration from the imported file will override the ones defined
# here (which is why it is important to import them last).
#
# import_config "#{Mix.env}.exs"
9 changes: 9 additions & 0 deletions lib/sync_m.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule SyncM do

def start(copy_type \\ :ram_copies)

def start(copy_type) do
GenServer.call(:sync_m, {:check_nodes_and_join, Node.list,copy_type})
end
defdelegate add_table(name, attrs), to: SyncM.Sync
end
19 changes: 19 additions & 0 deletions lib/sync_m/application.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
defmodule SyncM.Application do
# See https://hexdocs.pm/elixir/Application.html
# for more information on OTP Applications
@moduledoc false

use Application

def start(_type, _args) do
# List all child processes to be supervised
children = [
{SyncM.Sync, []}
]

# See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: SyncM.Supervisor]
Supervisor.start_link(children, opts)
end
end
88 changes: 88 additions & 0 deletions lib/sync_m/sync.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
defmodule SyncM.Sync do
@moduledoc false
use GenServer

alias :mnesia, as: Mnesia

def start_link(_) do
GenServer.start_link(__MODULE__, %{}, name: :sync_m)
end

def init(state) do
{:ok, state}
end



def handle_call({:check_nodes_and_join, [],_}, _, state) do
with :ok <- create_schema(node()),
:ok <- start_mnesia()
do
{:reply, {:ok}, state}
else
_ -> {:reply, {:error}, state}
end
end

def handle_call({:check_nodes_and_join, nodes, type}, _, state) do
with :ok <- start_mnesia(),
_ <- GenServer.multi_call([Enum.at(nodes,0)], :sync_m, {:request_join, node(),type})
do
{:reply, {:ok}, state}
else
_ -> {:reply, {:error}, state}
end
end

def handle_call({:request_join, remote_node, copy_type}, _, state) do
with {:ok, _} <- Mnesia.change_config(:extra_db_nodes, [remote_node]),
:ok <- Mnesia.system_info(:tables) |> copy_existing_tables(remote_node,copy_type)
do
{:reply, :ok, state}
else
_ -> {:reply, :ok, state}
end
end

defp copy_existing_tables(table_list,remote_node,type) do
Enum.map(table_list, &(Mnesia.add_table_copy(&1,remote_node,type)))
|> check_for_error()
end

defp create_schema(nodes) do
case Mnesia.create_schema([nodes]) do
{:error, {_, {:already_exists, _}}} -> :ok
:ok -> :ok
{:error, _} -> :error
end
end

defp start_mnesia() do
case Mnesia.start() do
:ok -> :ok
_ -> raise "Error starting Mnesia schema"
end
end

def add_table(name, attrs) do
case Mnesia.create_table(name, attributes: attrs) do
{:atomic, :ok} -> :ok
{:aborted, {:already_exists, _}} -> :ok
{:aborted, {:already_exists, _, _}} -> :ok
_ -> :error
end
end

defp check_for_error([h|t]) do
case h do
{:atomic, :ok} -> check_for_error(t)
{:aborted, {:already_exists, _, _}} -> :ok
{:aborted, {:already_exists, _}} -> check_for_error(t)
_ -> :error
end
end

defp check_for_error([]) do
:ok
end
end
29 changes: 29 additions & 0 deletions mix.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
defmodule SyncM.MixProject do
use Mix.Project

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

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

# Run "mix help deps" to learn about dependencies.
defp deps do
[
# {:dep_from_hexpm, "~> 0.3.0"},
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"},
]
end
end
8 changes: 8 additions & 0 deletions test/sync_m_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
defmodule SyncMTest do
use ExUnit.Case
doctest SyncM

test "greets the world" do
assert SyncM.hello() == :world
end
end
1 change: 1 addition & 0 deletions test/test_helper.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ExUnit.start()

0 comments on commit a37bf83

Please sign in to comment.