Skip to content

Instantly share code, notes, and snippets.

@dsalahutdinov
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dsalahutdinov/5dabd8a45992207b0c53 to your computer and use it in GitHub Desktop.
Save dsalahutdinov/5dabd8a45992207b0c53 to your computer and use it in GitHub Desktop.
poor orm (ruby+mysql2)
require 'mysql2'
client = Mysql2::Client.new(:host => "localhost", :username => "root", :password => "password", :database => "ar_sample")
results = client.query('DROP TABLE if exists pet')
results = client.query('CREATE TABLE pet (id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, name CHAR(30), owner_name CHAR(20), age SMALLINT(6));')
class String
def to_sql; "\"#{self.to_s}\""; end
end
class Numeric
def to_sql; self.to_s; end
end
module Model
module ClassMethods
attr_reader :connection
def setup(mysql)
@connection = mysql
custom_field_names = connection.query("SHOW COLUMNS FROM #{table_name};").collect{|row| row["Field"] } - ["id"]
custom_field_names.each do |field_name|
define_method(field_name) do
instance_variable_get("@#{field_name}")
end
define_method("#{field_name}=") do |new_value|
old_value = instance_variable_get("@#{field_name}")
instance_variable_set("@#{field_name}", new_value)
@changed_attributes << field_name if old_value != new_value && !@changed_attributes.include?(field_name)
end
end
end
def table_name
self.name.downcase
end
def all
connection.query("select * from #{table_name}").collect {|row| materialize(row) }
end
def find(search_id)
results = connection.query("select * from #{table_name} where id = #{search_id}").to_a
results.size > 0 ? materialize(results.first) : nil
end
private
def materialize(hash_data)
model_instance = self.new
model_instance.each do |k, v|
model_instance.instance_variable_set("@#{k}", v)
end
model_instance
end
end
class Base
extend(ClassMethods)
attr_reader :id
def initialize()
@changed_attributes = []
end
def new_record?
@id.nil?
end
def save
return true if @changed_attributes.size == 0
if (new_record?)
self.class.connection.query("INSERT INTO #{self.class.table_name} (#{@changed_attributes.sort.join(", ")}) VALUES (#{@changed_attributes.sort.collect{|a| "#{instance_variable_get("@#{a}").to_sql}" }.join(", ")})")
@id = self.class.connection.last_id
else
query = "UPDATE #{self.class.table_name} set #{@changed_attributes.sort.collect{|a| "#{a} = #{instance_variable_get("@#{a}").to_sql}"}.join(", ")} where id = #{@id};"
r = self.class.connection.query(query)
end
@changed_attributes = []
end
end
end
class Pet < Model::Base
end
Pet.setup(client)
p = Pet.new
p.name = "Bobik"
p.owner_name = "Dmitry"
p.age = 10
p.save
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment