# SPDX-License-Identifier: Apache-2.0 # Copyright (C) 2021-2022 OKTET Labs Ltd. All rights reserved. # # Class DataMapper for Diary Management Application. # require 'mysql2' class DataMapper @@mapper = Hash.new @@database = nil def initialize(table, key = "id") @key = key @table = table @@mapper[@table] = self @cache = Hash.new @columns = @@database.query("select column_name from information_schema.columns where table_name='%s'" % @table).collect{ |col| col["column_name"] } - [@key] end def self.setup(args) raise "Database parameters is not a hash" unless args.is_a? Hash @@database = Mysql2::Client.new(:host => args[:host], :username => args[:username], :password => args[:password], :database => args[:database]) 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.query("select * from #{@table} where #{@key} = '%s' LIMIT 1" % id).first return nil unless row pick(row) end def where(clause, *args) cmd = "select * from #{@table} where " + clause % args @@database.query(cmd).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 {"'%s'"}.join(",")})" query_args = query_args + value end elsif value.is_a?(Range) query_clause << "#{tag.to_s} >= '%s' AND #{tag.to_s} <= '%s'" query_args << value.first << value.last else query_clause << "#{tag.to_s} = '%s'" query_args << value end end # raise "#{MyCGI.dump(query_clause)} : #{MyCGI.dump(query_args)}" cmd = "select * from #{@table}" + (query_clause.empty? ? "" : " where " + query_clause.join(" and ")) % query_args @@database.query(cmd).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.query("select last_insert_id() as id").first["id"] @@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