Skip to content

Instantly share code, notes, and snippets.

@lenileiro
Last active January 14, 2024 11:05
Show Gist options
  • Select an option

  • Save lenileiro/c3f08fb81ab78c0750ffb3eea2468b6e to your computer and use it in GitHub Desktop.

Select an option

Save lenileiro/c3f08fb81ab78c0750ffb3eea2468b6e to your computer and use it in GitHub Desktop.
defmodule App.Datalog do
use DatalogBuilder
import_rules(App.Account.Rules)
import_rules(App.Document.Rules)
end
## Examples
# Query all fields of all rules within the "account" namespace
{:ok, results} = App.Datalog.query(%{rule_namespace: "account", rule: "*", select: "*"})
# Query specific fields of the "admin" rule across all namespaces
{:ok, results} = App.Datalog.query(%{rule_namespace: "*", rule: "admin", select: [:object_id, :object_relation]})
# Query all fields for a specific rule and namespace
{:ok, results} = App.Datalog.query(%{rule_namespace: "account", rule: "admin", select: "*"})
# Find all admins for a specific department
{:ok, results} = App.Datalog.query(%{rule: "admin", where: %{subject_id: "Department1"}})
namespace account {
# Entity: Department
# Relations:
# - manages: Users who manage the department
# - projects: Projects under the department
entity department {
relation managers [user]
relation projects [project]
}
# Entity: Project
# Relations:
# - leads: Users who lead the project
# - contributors: Users who contribute to the project
# - part_of: The department to which the project belongs
entity project {
relation leads [user]
relation contributors [user]
relation part_of [department]
}
# Entity: Group
# Relations:
# - owns_account: Accounts owned by the group
entity group {
relation owns_account [account]
}
# Entity: User
# Relations:
# - works_in: Departments where the user works
# - member_of: Groups the user is a member of
entity user {
relation works_in [department]
relation member_of [group]
}
# Entity: Account
# No direct relations, but involved in permissions and rules
entity account {}
# Permissions/Rules
# - admin: Assigned based on department management or project leadership
# - owner: Assigned based on group membership and account ownership
permission admin {
managers in [department] grants [user]
leads in [project] grants [user]
}
permission owner {
member_of in [group] and owns_account in [group] grants [user]
}
}
defmodule App.Account.Rules do
alias Datalog.Fact
use DatalogBuilder.Rules, namespace: "account"
def build("admin", %Fact{object_id: admin, object_relation: "manages", subject_id: department}, %Fact{
object_id: employee,
subject_id: department,
object_relation: "works_in"
}) do
%Fact{object_id: admin, object_relation: "admin_of", subject_id: employee}
end
def build("admin", %Fact{object_id: admin, object_relation: "leads", subject_id: project}, %Fact{
object_id: employee,
subject_id: project,
object_relation: "contributes_to"
}) do
%Fact{object_id: admin, object_relation: "leader_of", subject_id: employee}
end
def build("owner", %Fact{object_id: user, object_relation: "admin", subject_id: group}, %Fact{
object_id: group,
subject_id: account,
object_relation: "owner"
}) do
%Fact{object_id: user, object_relation: "owner_of", subject_id: account}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment