diary/diary_datamapper.rb

109 lines
3.5 KiB
Ruby

# SPDX-License-Identifier: Apache-2.0
# Copyright (C) 2021 OKTET Labs Ltd. All rights reserved.
#
# Class DataMapper for Diary Management Application.
#
require 'dbi'
class DataMapper
@@mapper = Hash.new
@@database = nil
def initialize(table, key = "id")
@key = key
@table = table
@@mapper[@table] = self
@cache = Hash.new
@columns = @@database.columns(@table).collect { |col| col["name"] } - [@key]
end
def self.setup(args)
raise "Database parameters is not a hash" unless args.is_a? Hash
@@database = DBI.connect("dbi:#{args[:adapter]}:#{args[:database]}:" +
"#{args[:host]}",
args[:username], args[:password])
end
def self.database
@@database
end
def pick(row)
row_data = row.to_h
id = row_data[@key]
return @cache[id] if @cache.has_key?(id)
@cache[id] = instantiate(id, row_data)
end
def find(id)
return @cache[id] if @cache.has_key?(id)
row = @@database.select_one("select * from #{@table} where #{@key} = ?", id)
return nil unless row
pick(row)
end
def where(clause, *args)
@@database.select_all("select * from #{@table} where " + clause,
*args).collect { |row| pick(row) }
end
def all(args)
# TODO: args == nil
raise ArgumentError unless args.is_a?(Hash)
query_clause = Array.new
query_args = Array.new
args.each do |tag, value|
next unless @columns.include?(tag.to_s) or tag.to_s == @key
if value.is_a?(Array)
if value.length > 0
query_clause << "#{tag.to_s} " +
"IN (#{value.collect {"?"}.join(",")})"
query_args = query_args + value
end
elsif value.is_a?(Range)
query_clause << "#{tag.to_s} >= ? AND #{tag.to_s} <= ?"
query_args << value.first << value.last
else
query_clause << "#{tag.to_s} = ?"
query_args << value
end
end
# raise "#{MyCGI.dump(query_clause)} : #{MyCGI.dump(query_args)}"
@@database.select_all("select * from #{@table}" +
(query_clause.empty? ? "" :
" where " + query_clause.join(" and ")),
*query_args).collect { |row| pick(row) }
end
def insert(obj)
raise ArgumentError unless obj.id.nil?
fields = @columns & obj.attributes.keys
@@database.do("insert into #{@table} (" + fields.join(",") +
") values (" + fields.collect {"?"}.join(",") + ")",
*(fields.collect {|field| obj[field]}))
obj.id = @@database.select_one("select last_insert_id()")[0]
@@cache[obj.id] = obj
end
def update(obj)
raise ArgumentError if obj.id.nil?
fields = @columns & obj.attributes.keys
@@database.do("update #{@table} set " +
fields.collect {|field| field + " = ?"}.join(",") +
" where #{@key} = ?",
*(fields.collect {|field| obj[field]} << obj.id))
end
def delete(obj)
raise ArgumentError if obj.id.nil?
@@database.do("delete from #{@table} where #{@key} = ?", obj.id)
@@cache.delete(obj.id)
obj.id = nil
end
def self.[](table)
@@mapper[table]
end
end