Skip to content

Commit

Permalink
Replace ActiveRecord with Sequel
Browse files Browse the repository at this point in the history
  • Loading branch information
0x1eef committed Mar 28, 2024
1 parent 689b650 commit 5922626
Show file tree
Hide file tree
Showing 16 changed files with 97 additions and 87 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ within your local network. It is both easy to use, and easy to install.
* The server is powered by [rack](https://github.com/rack/rack) and [puma](https://github.com/puma/puma):
- Accepts GraphQL requests at `/graphql`.
- Serves client (HTML, JS, CSS).
- Dependencies: ActiveRecord, SQLite3, ruby-graphql.
- Dependencies: Sequel, SQLite3, ruby-graphql.
* The client is a statically compiled [nanoc](https://github.com/nanoc/nanoc) website:
- Dependencies: webpack, typescript, react.
* The CLI controls the web server:
Expand Down
2 changes: 2 additions & 0 deletions twenty-cli/lib/twenty-cli/command/mixin/sqlite_mixin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ module Twenty::Command::SQLiteMixin
def run_command(options)
path = options.database || Twenty.default_database
Twenty.establish_connection(path:)
require "twenty-server/migration"
require "twenty-server/model"
super(options)
end
end
36 changes: 17 additions & 19 deletions twenty-server/lib/twenty-server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,8 @@

module Twenty
require "fileutils"
require "active_record"
require "sequel"
require_relative "twenty-server/path"
require_relative "twenty-server/graphql"
require_relative "twenty-server/rack"
require_relative "twenty-server/migration"
require_relative "twenty-server/model"
extend FileUtils
extend Path

##
Expand All @@ -26,24 +21,27 @@ def self.default_database
#
# @return [void]
def self.establish_connection(path:)
ActiveRecord::Base.establish_connection(
adapter: "sqlite3",
database: path,
pool: 16
@connection = Sequel.connect(
adapter: "sqlite",
database: path
)
end

##
# Prepares the parent directory of the database.
# @return [void]
# @api private
def self.prepare_dir
mkdir_p(datadir)
mkdir_p(tmpdir)
touch(default_database)
# @return [Sequel::SQLite::Database]
# Returns an instance of Sequel::SQLite::Database.
def self.connection
establish_connection unless @connection
@connection
end

begin
FileUtils.mkdir_p(datadir)
FileUtils.mkdir_p(tmpdir)
FileUtils.touch(default_database)
rescue => ex
warn "prepare_dir error: #{ex.message} (#{ex.class})"
end
private_class_method :prepare_dir
prepare_dir
require_relative "twenty-server/graphql"
require_relative "twenty-server/rack"
end
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class CreateTask < GraphQL::Schema::Mutation
argument :input, Twenty::GraphQL::Input::TaskInput

def resolve(input:)
Twenty::Task.new(input.to_h).save!
Twenty::Task.create(input.to_h)
{"errors" => []}
rescue => ex
{"errors" => [ex.message]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ class UpdateTask < GraphQL::Schema::Mutation
argument :input, Twenty::GraphQL::Input::TaskInput

def resolve(task_id:, input:)
task = Twenty::Task.find_by(id: task_id)
task.update!(input.to_h)
task = Twenty::Task[task_id]
task.update(input.to_h)
{"errors" => []}
rescue => ex
{"errors" => [ex.message]}
Expand Down
9 changes: 5 additions & 4 deletions twenty-server/lib/twenty-server/graphql/type/query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@ class Query < GraphQL::Schema::Object
end
field :projects, [Project], null: false


def find_task(task_id:)
Twenty::Task.find_by(id: task_id)
Twenty::Task[task_id]
end

def tasks(status:, project_id: nil)
tasks = Twenty::Task
.where(status:)
.order(updated_at: :desc)
project_id ? tasks.where(project_id:) : tasks
.by_status(status)
.order("updated_at DESC")
(project_id ? tasks.where(project_id:) : tasks).all
end

def projects
Expand Down
17 changes: 4 additions & 13 deletions twenty-server/lib/twenty-server/migration.rb
Original file line number Diff line number Diff line change
@@ -1,34 +1,25 @@
# frozen_string_literal: true

module Twenty::Migration
require "sequel/extensions/migration"
##
# @return [String]
# Returns the path to twenty's migrations.
def self.migrations_path
[File.join(__dir__, "migration")]
File.join(__dir__, "migration")
end

##
# Runs migrations (if neccessary).
# @return [void]
def self.run!
context.migrate
Sequel::Migrator.run(Twenty.connection, migrations_path)
end
ActiveRecord.timestamped_migrations = false

##
# @return [Boolean]
# Returns true when there are pending migrations.
def self.pending_migrations?
context.open.pending_migrations.any?
Sequel::Migrator.is_current?(Twenty.connection, migrations_path)
end

##
# @return [ActiveRecord::MigrationContext]
# Returns an instance of
# {ActiveRecord::MigrationContext ActiveRecord::MigrationContext}.
def self.context
@context ||= ActiveRecord::MigrationContext.new(migrations_path)
end
private_class_method :context
end
18 changes: 9 additions & 9 deletions twenty-server/lib/twenty-server/migration/1_create_projects.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# frozen_string_literal: true

class CreateProjects < ActiveRecord::Migration[7.1]
def up
create_table(:projects) do |t|
t.string :name, null: false
t.string :path, null: false
t.timestamps
Sequel.migration do
up do
create_table(:projects) do
primary_key :id
String :name, null: false
String :path, null: false
DateTime :created_at
DateTime :updated_at
end
add_index :projects, [:name, :path], unique: true
end

def down
down do
drop_table(:projects)
end
end
18 changes: 10 additions & 8 deletions twenty-server/lib/twenty-server/migration/2_create_tasks.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
# frozen_string_literal: true

class CreateTasks < ActiveRecord::Migration[7.1]
def up
Sequel.migration do
up do
create_table(:tasks) do |t|
t.string :title, null: false
t.text :content, null: false
t.integer :status, null: false, default: 0
t.belongs_to :project, null: false
t.timestamps
primary_key :id
String :title, null: false
Text :content, null: false
Integer :status, null: false, default: 0
DateTime :created_at
DateTime :updated_at
foreign_key :project_id, :projects, null: false
end
end

def down
down do
drop_table(:tasks)
end
end
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# frozen_string_literal: true

class AddColorToProjects < ActiveRecord::Migration[7.1]
def up
Sequel.migration do
up do
default = Twenty::ColorableMixin.random_color
add_column :projects, :color, :string, null: false, default:
end

def down
down do
drop_column :projects, :color
end
end
7 changes: 6 additions & 1 deletion twenty-server/lib/twenty-server/model.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# frozen_string_literal: true

class Twenty::Model < ActiveRecord::Base
module Twenty::Model
def self.included(model)
model.plugin(:validation_class_methods)
model.plugin(:timestamps, update_on_create: true)
end

require_relative "model/mixin/colorable_mixin"
require_relative "model/project"
require_relative "model/task"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ module Twenty::ColorableMixin
"#993366", "#2200AA", "#557788", "#998877", "#BB4400"
]

def self.included(klass)
klass.before_validation :set_random_color, on: :create
def before_validation
super if defined?(super)
set_random_color
end

def random_color
Expand All @@ -25,6 +26,7 @@ def random_color
private

def set_random_color
return if id
self.color = random_color
end
end
15 changes: 5 additions & 10 deletions twenty-server/lib/twenty-server/model/project.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
# frozen_string_literal: true

class Twenty::Project < Twenty::Model
class Twenty::Project < Sequel::Model
include Twenty::Model
include Twenty::ColorableMixin
self.table_name = "projects"

##
# Validations
validates :name, presence: true
validates :path, presence: true

##
# Associations
has_many :tasks, class_name: "Twenty::Task"
validates_presence_of :name
validates_presence_of :path
one_to_many :tasks, class_name: "Twenty::Task"

##
# @return [String]
Expand Down
38 changes: 26 additions & 12 deletions twenty-server/lib/twenty-server/model/task.rb
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
# frozen_string_literal: true

class Twenty::Task < Twenty::Model
self.table_name = "tasks"
class Twenty::Task < Sequel::Model
include Twenty::Model

STATUS = {backlog: 0, ready: 1, in_progress: 2, complete: 3}
enum :status, STATUS, default: :backlog
plugin(:enum)
STATUS_MAP = {backlog: 0, ready: 1, in_progress: 2, complete: 3}
STATUS_KEYS = STATUS_MAP.keys
enum :status, STATUS_MAP

##
# Validations
validates :title, presence: true
validates :content, presence: true
validates :project, presence: true
def self.by_status(status)
if STATUS_KEYS.any? { _1.to_s == status.to_s }
public_send(status)
else
where(id: nil)
end
end

##
# Associations
belongs_to :project, class_name: "Twenty::Project"
validates_presence_of :title
validates_presence_of :content
validates_presence_of :project
validates_inclusion_of :status, in: [STATUS_KEYS, *STATUS_KEYS.map(&:to_s)]
many_to_one :project, class_name: "Twenty::Project"

def status=(v)
super(v.to_sym)
end

def status
super.to_s
end
end
2 changes: 1 addition & 1 deletion twenty-server/twenty-server.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Gem::Specification.new do |gem|
gem.require_paths = ["lib"]
gem.summary = "twenty: server-side component"
gem.description = gem.summary
gem.add_runtime_dependency "activerecord", "~> 7.1"
gem.add_runtime_dependency "sequel", "~> 5.78"
gem.add_runtime_dependency "sqlite3", "~> 1.6"
gem.add_runtime_dependency "graphql", "~> 2.2"
gem.add_runtime_dependency "server.rb", "~> 0.1"
Expand Down
2 changes: 1 addition & 1 deletion twenty-server/twenty-server.gemspec.erb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Gem::Specification.new do |gem|
gem.require_paths = ["lib"]
gem.summary = "twenty: server-side component"
gem.description = gem.summary
gem.add_runtime_dependency "activerecord", "~> 7.1"
gem.add_runtime_dependency "sequel", "~> 5.78"
gem.add_runtime_dependency "sqlite3", "~> 1.6"
gem.add_runtime_dependency "graphql", "~> 2.2"
gem.add_runtime_dependency "server.rb", "~> 0.1"
Expand Down

0 comments on commit 5922626

Please sign in to comment.