Last active
October 5, 2024 18:56
-
-
Save fguillen/57ef5af51c574076c0aa5930f430ebd9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "sqlite3" | |
module ActiveRecord | |
class Mini | |
attr_reader :attributes | |
def initialize(attributes = {}) | |
@attributes = attributes | |
end | |
def save | |
if id.nil? | |
sql = <<~SQL | |
insert into | |
#{self.class.table_name} | |
(#{@attributes.keys.join(", ")}) | |
values | |
(#{@attributes.size.times.map { |_| "?" }.join(", ")}) | |
SQL | |
self.class.execute(sql, @attributes.values) | |
@attributes["id"] = self.class.connection.last_insert_row_id | |
else | |
sql = <<~SQL | |
update | |
#{self.class.table_name} | |
set #{@attributes.keys.map { |key| "#{key} = ?" }.join(", ")} | |
where id = ? | |
SQL | |
self.class.execute( | |
sql, | |
@attributes.values, | |
id | |
) | |
end | |
end | |
def reload | |
@attributes = self.class.find(id).attributes | |
end | |
def delete | |
self.class.execute("delete from #{self.class.table_name} where id = ?", id) | |
end | |
def self.table_name | |
"#{name.downcase}s" | |
end | |
def self.column_names | |
columns.map { |column| column["name"] } | |
end | |
def self.columns | |
@columns ||= self.execute("pragma table_info(#{table_name});") | |
end | |
def self.connection | |
@connection ||= | |
begin | |
connection = SQLite3::Database.new "#{__dir__}/data.db" | |
connection.results_as_hash = true | |
connection | |
end | |
end | |
def self.find(id) | |
data = self.execute("select * from #{table_name} where id = ?", id).first | |
return nil if data.nil? | |
self.new(data) | |
end | |
def self.execute(*args) | |
puts "SQL: #{args}" | |
if args.size > 1 | |
connection.prepare(args[0]).execute(args[1..]) | |
else | |
connection.execute(args[0]) | |
end | |
end | |
def self.inherited(subclass) | |
subclass.class_eval do | |
column_names.each do |column_name| | |
define_method(column_name) do | |
@attributes[column_name] | |
end | |
define_method("#{column_name}=") do |value| | |
@attributes[column_name] = value | |
end | |
end | |
end | |
end | |
end | |
end | |
class User < ActiveRecord::Mini | |
end | |
p User.table_name # => "users" | |
p User.column_names # => ["id", "name"] | |
user = User.new(name: "John") | |
user.save | |
p user.id # => 1 | |
user.reload | |
p user.name # => "John" | |
user.name = "Jane" | |
user.save | |
user.reload | |
p user.name # => "Jane" | |
user = User.find(1) | |
p user.name # => "Jane" | |
user.delete | |
p User.find(1) # => nil |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment