diary/sql_cache.rb

98 lines
2.9 KiB
Ruby
Raw Normal View History

# 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