# SPDX-License-Identifier: Apache-2.0 # Copyright (C) 2021-2022 OKTET Labs Ltd. All rights reserved. # # SQL class for Diary Management Application # class SQL_Cache < Hash def initialize(sql, table, string_expr) @sql = sql @name = table @string_expr = string_expr @lists = Hash.new @fields = @sql.query("select column_name from information_schema.columns where table_name='%s'" % @sql.escape(@name)).collect { |col| col["column_name"] } super(0) end attr_reader :sql, :name attr_accessor :string_expr def search(where) list = Array.new cmd = "select * from #{@name} where #{where} order by id" @sql.query(cmd).collect do |row| self[row["id"]] = row.to_h list.push(self[row["id"]]) end list end private :search def list(where) if not @lists[where] @lists[where] = search(where).collect do |entry| string = @string_expr.dup entry.each do |field, value| string.gsub!(/#\{#{field}\}/, value.to_s) if value end [entry["id"].to_s, string] end end @lists[where] end def [](id) id = id.to_i if super(id) == 0 if search("id = #{id}").length != 1 self[id] = nil end end super(id) end def create(data) fields = data.keys & @fields cmd = ("insert into #{@name} (" + fields.join(", ") + ") values (" + fields.collect do "%s" end.join(", ") + ")") % (fields.collect do |field| if data[field].class == DateTime t = "STR_TO_DATE('%s'" % data[field] + ", '%Y-%m-%dT%H:%i:%s+00:00')" else t = "'%s'" % @sql.escape(data[field].to_s) end t end) @sql.query(cmd) @sql.query("select last_insert_id() as id").first["id"] end def modify(id, data) fields = (@fields & self[id].keys) - ["id"] changes = fields.inject([]) do |ch, field| if data.has_key?(field) and data[field] != self[id][field] ch.push(field) else ch end end cmd = ("update #{@name} set " + changes.collect do |field| field + " = %s" end.join(", ") + " where id = #{id}") % (changes.collect do |field| if data[field].class == DateTime t = "STR_TO_DATE('%s'" % data[field] + ", '%Y-%m-%dT%H:%i:%s+00:00')" else t = "'%s'" % @sql.escape(data[field].to_s) end t end) @sql.query(cmd) if changes.length > 0 end def delete(id) @sql.query("delete from #{@name} where id = #{id}") super(id) end end