Skip to content
Open

Misc #94

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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ erl_crash.dump
_build
Mnesia.*
/doc

.idea/
amnesia.iml
projectFilesBackup/
5 changes: 5 additions & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
erlang 26.1.2
elixir 1.15.7
nodejs 20.0.0
direnv 2.32.2
yarn 1.22.19
9 changes: 1 addition & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,14 +166,7 @@ Amnesia.transaction do
which runs wget and mails the page back to me. It is very efficient use of my
time, but it is slow in real time.
"""

richard |> User.add_message %S"""
I am skeptical of the claim that voluntarily pedophilia harms children. The
arguments that it causes harm seem to be based on cases which aren't
voluntary, which are then stretched by parents who are horrified by the idea
that their little baby is maturing.
"""


linus |> User.add_message %S"""
Portability is for people who cannot write new programs.
"""
Expand Down
16 changes: 14 additions & 2 deletions lib/amnesia.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,28 @@ defmodule Amnesia do
end
end


@rock_extension Code.ensure_compiled?(:mnesia_rocksdb)

require Amnesia.Helper

@doc """
Start the database, see `mnesia:start`.
"""
@spec start :: :ok | { :error, any }
def start do
:mnesia.start
if @rock_extension do
def start do
:mnesia.start
:mnesia_rocksdb.register()
end
else
def start do
:mnesia.start
end
end



@doc """
Stop the database, see `mnesia:stop`.
"""
Expand Down
51 changes: 51 additions & 0 deletions lib/amnesia/emulator/amnesia/database.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
# Version 2, December 2004
#
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
#
# 0. You just DO WHAT THE FUCK YOU WANT TO.

defmodule Amnesia.Emulator.Database do
defstruct [
tables: %{},
history: []
]

defmacro mockdatabase(name, options \\ [], [do: block]) do
quote do
db = unquote(options[:database] || name)
parent = __MODULE__
defmodule unquote(name) do
@base parent
require Amnesia.Emulator.Records
import Amnesia.Emulator.Records
require Elixir.Amnesia.Emulator.Table
import Elixir.Amnesia.Emulator.Table
@database db
Module.register_attribute(__MODULE__, :tables, accumulate: true)


def mock(scenario \\ :default) do
{@database, [:passthrough], __mock_methods__(scenario)}
end

def __mock_methods__(scenario \\ :current) do
scenario = cond do
scenario == :current -> apply(@base, :scenario, [])
:else -> scenario
end
settings = apply(@base, :session, [scenario])
[
tables: fn() -> tables(settings) end
]
end

unquote(block)

def tables(_settings), do: tables()
def tables(), do: @tables
end
end
end
end
12 changes: 12 additions & 0 deletions lib/amnesia/emulator/amnesia/records.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
# Version 2, December 2004
#
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
#
# 0. You just DO WHAT THE FUCK YOU WANT TO.

defmodule Amnesia.Emulator.Records do
require Record
Record.defrecord(:emulator_session, [emulator: nil, table: nil, scenario: nil, slice: nil, settings: nil, table_settings: nil])
end
138 changes: 138 additions & 0 deletions lib/amnesia/emulator/amnesia/table.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
# Version 2, December 2004
#
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
#
# 0. You just DO WHAT THE FUCK YOU WANT TO.

defmodule Amnesia.Emulator.Table do
defstruct [
records: %{},
history: [],
state: :online
]

defmodule Record do
defstruct [
record: nil,
exists?: true,
history: []
]
end

defmacro default_scenario([do: block]) do
quote do
def initial_data(:default) do
unquote(block)
end
end
end
defmacro scenario(name, [do: block]) do
quote do
def initial_data(unquote(name)) do
unquote(block)
end
end
end

defmacro mocktable(name, [do: block]) do
quote location: :keep do
table = Module.concat([@database, unquote(name)])
@tables table
parent = @base
defmodule unquote(name) do
@table table
@base parent
def mock(scenario \\ :current, settings \\ []) do
scenario = cond do
scenario == :current -> apply(@base, :scenario, [])
:else -> scenario
end
mock_configuration = emulator_session(
apply(@base, :session, [scenario]),
table: @table,
table_settings: settings
)

# Set Data
load_table(mock_configuration)

{@table, [:passthrough], __mock_methods__(mock_configuration)}
end

defp load_table(config = emulator_session(table: table, table_settings: settings, scenario: scenario)) do
key_field = (settings[:key] || List.first(table.info(:attributes)))
data = initial_data(scenario)
|> Enum.map(
fn(record) ->
{
get_in(record, [Access.key(key_field)]),
%Amnesia.Emulator.Table.Record{record: record}
}
end
)
|> Map.new()
init = %Amnesia.Emulator.Table{
records: data,
state: settings[:state] || :online,
history: []
}

apply(@base, :__init_table__, [config, init])
end

def __mock_methods__(mock_configuration) do
[
keys: fn() -> keys(mock_configuration) end,
keys!: fn() -> keys!(mock_configuration) end,
read: fn(key) -> read(mock_configuration, key) end,
read!: fn(key) -> read!(mock_configuration, key) end,
write: fn(record) -> write(mock_configuration, record) end,
write!: fn(record) -> write!(mock_configuration, record) end,
delete: fn(record) -> delete(mock_configuration, record) end,
delete!: fn(record) -> delete!(mock_configuration, record) end,
match: fn(selector) -> match(mock_configuration, selector) end,
match!: fn(selector) -> match!(mock_configuration, selector) end,
]
end

defdelegate keys(settings), to: Amnesia.Emulator.Table.Mock
defdelegate keys!(settings), to: Amnesia.Emulator.Table.Mock
defdelegate read(settings, key), to: Amnesia.Emulator.Table.Mock
defdelegate read!(settings, key), to: Amnesia.Emulator.Table.Mock
defdelegate write(settings, key), to: Amnesia.Emulator.Table.Mock
defdelegate write!(settings, key), to: Amnesia.Emulator.Table.Mock
defdelegate delete(settings, key), to: Amnesia.Emulator.Table.Mock
defdelegate delete!(settings, key), to: Amnesia.Emulator.Table.Mock
defdelegate match(settings, key), to: Amnesia.Emulator.Table.Mock
defdelegate match!(settings, key), to: Amnesia.Emulator.Table.Mock


defoverridable [
__mock_methods__: 1,
keys: 1,
keys!: 1,
read: 2,
read!: 2,
write: 2,
write!: 2,
delete: 2,
delete!: 2,
match: 2,
match!: 2,
]

unquote(block)

def initial_data(scenario) when scenario not in [:default] do
initial_data(:default)
end
def initial_data(_) do
[]
end

end
end
end
end
Loading