Changed SQL queries for mysql2 ruby driver

Signed-off-by: Sergey Bogdanov <sergey.bogdanov@oktetlabs.ru>
master
Sergey Bogdanov 2022-02-02 14:21:36 +00:00
parent 3a172adb84
commit 5da583412b
6 changed files with 120 additions and 101 deletions

View File

@ -1,5 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright (C) 2021 OKTET Labs Ltd. All rights reserved.
# Copyright (C) 2021-2022 OKTET Labs Ltd. All rights reserved.
#
# Class Diary for Diary Management Application.
@ -220,16 +220,18 @@ class Diary
not policy.can_approve?(project, who)) or
DiaryState.valid(@attributes["state"].to_i)
@approval_note = DataMapper.database.select_all(
"select * from approval_note where id = ?", @id
).collect { |row| row.to_h }
@approval_note = DataMapper.database.query("select * from approval_note where id = '%s'" % @id).collect { |row| row.to_h }
return @approval_note
end
def self.approve_all(prj, who)
DataMapper.database.do("update diary set state = ? where prj_id = ? " +
"AND who = ? AND state IN (?,?)", DiaryState::APPROVED,
prj.id, who, DiaryState::REQ_APPROVAL, DiaryState::REJECTED)
DataMapper.database.query("update diary set state = '%s' where prj_id = '%s' AND who = '%s' AND state IN ('%s','%s')" %
[
DiaryState::APPROVED,
DataMapper.database.escape(prj.id.to_s),
DataMapper.database.escape(who.to_s),
DiaryState::REQ_APPROVAL, DiaryState::REJECTED
])
end
def destroy
@ -245,11 +247,8 @@ class Diary
def self.predict_project(who)
# TODO: select the most used of N last entries
last_diary = DataMapper.database.select_one(
"SELECT prj_id FROM diary " +
"WHERE who=? ORDER BY ddate DESC " +
"LIMIT 1", who.uid)
return last_diary ? last_diary[0].to_i : nil
last_diary = DataMapper.database.query("SELECT prj_id FROM diary WHERE who='%s' ORDER BY ddate DESC LIMIT 1" % who.uid ).first
return last_diary ? last_diary["prj_id"].to_i : nil
end
def self.find(args)
@ -260,7 +259,7 @@ class Diary
dates = args[:ddate]
raise ArgumentError unless dates.is_a? Range
query_clause = " where ddate >= ? and ddate <= ?"
query_clause = " where ddate >= '%s' and ddate <= '%s'"
query_args = [dates.first, dates.last]
if policy.restriction.include?(:project)
@ -268,10 +267,10 @@ class Diary
prj_list = prj_list & [prj_id] if prj_id
return [] if prj_list.empty?
query_clause += " AND prj_id IN (" +
prj_list.collect { "?" }.join(",") + ")"
prj_list.collect { "'%s'" }.join(",") + ")"
query_args += prj_list
elsif prj_id
query_clause += " AND prj_id = ?"
query_clause += " AND prj_id = '%s'"
query_args = query_args << prj_id
end
@ -280,45 +279,48 @@ class Diary
eng_list = eng_list & [who] if who
return [] if eng_list.empty?
query_clause += " AND who IN (" +
eng_list.collect { "?" }.join(",") + ")"
eng_list.collect { "'%s'" }.join(",") + ")"
query_args += eng_list
elsif who
query_clause += " AND who = ?"
query_clause += " AND who = '%s'"
query_args = query_args << who
end
if customer
query_clause += " AND customer = ?"
query_clause += " AND customer = '%s'"
query_args = query_args << customer
end
DataMapper.database.select_all("select diary.*, project.customer, " +
DataMapper.database.query("select diary.*, project.customer, " +
" project.leader, project.manager, diary.id as id" +
", diary.state as state" +
" from diary left join project on diary.prj_id = project.id" +
query_clause + " order by ddate, prj_id, who",
*query_args).collect do |row|
query_clause % (query_args) + " order by ddate, prj_id, who"
).collect do |row|
self.new(row["id"], row.to_h)
end
end
def self.for_approve(who)
DataMapper.database.select_all("select *, diary.id as id from" +
DataMapper.database.query("select *, diary.id as id from" +
" diary inner join approval on approval.who = diary.who and" +
" approval.prj_id = diary.prj_id left join project on" +
" diary.prj_id = project.id where approval.approver = ?" +
" and diary.state = ? order by diary.ddate",
who.uid, DiaryState::REQ_APPROVAL).collect do |row|
" diary.prj_id = project.id where approval.approver = '%s'" % who.uid +
" and diary.state = '%s' order by diary.ddate" % DiaryState::REQ_APPROVAL
).collect do |row|
self.new(row["id"], row.to_h)
end
end
def self.add_approval_note(id, message)
if message.is_a?(String) and message.length > 0
DataMapper.database.do(
"insert into approval_note(id,created,author,note) " +
"values (?,?,?,?)", id, DbTime.now,
DiaryEnv.instance.user.uid, message)
DataMapper.database.query("insert into approval_note(id,created,author,note) values ('%s',%s,'%s','%s')" %
[
DataMapper.database.escape(id.to_s),
"STR_TO_DATE('%s'," % DbTime.now + " '%Y-%m-%dT%h:%i:%s+00:00')",
DataMapper.database.escape(DiaryEnv.instance.user.uid),
DataMapper.database.escape(message)
])
end
end
end
@ -697,12 +699,12 @@ class DiaryUI
data["descr"].length < 10
# Check total hours
total = DataMapper.database.select_one(
"SELECT SUM(hours) FROM diary " +
"WHERE who=? AND ddate=?" +
(data.include?("id") ?
" AND id<>#{data["id"]}" : ""),
*([data["who"], data["ddate"]]))[0].to_i +
total = DataMapper.database.query("SELECT SUM(hours) as sum FROM diary WHERE who='%s' AND ddate='%s'" %
[
data["who"],
data["ddate"]
] + (data.include?("id") ? " AND id<>#{data["id"]}" : "")
).first["sum"].to_i +
data["hours"]
raise "You have more than 24 hours " +
"for #{data["ddate"]}" if total > 24
@ -753,12 +755,16 @@ class DiaryUI
else
raise "You should specify at least 1 hour" if data["hours"] < 1
raise "You are inserting a duplicate diary record!" if
DataMapper.database.select_one(
"SELECT COUNT(*) FROM diary WHERE " +
"who = ? and descr = ? and hours = ? " +
"and ddate =?",
*([data["who"], data["descr"],
data["hours"], data["ddate"]]))[0].to_i > 0
DataMapper.database.query(
"SELECT COUNT(*) as count FROM diary WHERE " +
"who = '%s' and descr = '%s' and hours = '%s' and ddate = '%s'" %
[
DataMapper.database.escape(data["who"].to_s),
DataMapper.database.escape(data["descr"].to_s),
DataMapper.database.escape(data["hours"].to_s),
DataMapper.database.escape(data["ddate"].to_s)
]
).first["count"].to_i > 0
data["created"] = data["modified"]
@diary_table.create(data)
end

View File

@ -1,11 +1,11 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright (C) 2021 OKTET Labs Ltd. All rights reserved.
# Copyright (C) 2021-2022 OKTET Labs Ltd. All rights reserved.
#
# Class DataMapper for Diary Management Application.
#
require 'dbi'
require 'mysql2'
class DataMapper
@@mapper = Hash.new
@ -16,13 +16,11 @@ class DataMapper
@table = table
@@mapper[@table] = self
@cache = Hash.new
@columns = @@database.columns(@table).collect { |col| col["name"] } - [@key]
@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 = DBI.connect("dbi:#{args[:adapter]}:#{args[:database]}:" +
"#{args[:host]}",
args[:username], args[:password])
@@database = Mysql2::Client.new(:host => args[:host], :username => args[:username], :password => args[:password], :database => args[:database])
end
def self.database
@@database
@ -37,14 +35,14 @@ class DataMapper
def find(id)
return @cache[id] if @cache.has_key?(id)
row = @@database.select_one("select * from #{@table} where #{@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)
@@database.select_all("select * from #{@table} where " + clause,
*args).collect { |row| pick(row) }
cmd = "select * from #{@table} where " + clause % args
@@database.query(cmd).collect { |row| pick(row) }
end
def all(args)
@ -57,22 +55,20 @@ class DataMapper
if value.is_a?(Array)
if value.length > 0
query_clause << "#{tag.to_s} " +
"IN (#{value.collect {"?"}.join(",")})"
"IN (#{value.collect {"'%s'"}.join(",")})"
query_args = query_args + value
end
elsif value.is_a?(Range)
query_clause << "#{tag.to_s} >= ? AND #{tag.to_s} <= ?"
query_clause << "#{tag.to_s} >= '%s' AND #{tag.to_s} <= '%s'"
query_args << value.first << value.last
else
query_clause << "#{tag.to_s} = ?"
query_clause << "#{tag.to_s} = '%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) }
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)
@ -81,7 +77,7 @@ class DataMapper
@@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]
obj.id = @@database.query("select last_insert_id() as id").first["id"]
@@cache[obj.id] = obj
end

View File

@ -42,15 +42,17 @@ class DiaryEnv
:bindpw => LDAP_BIND_PW,
:key => "uid")
Person.set_local(HOME_ORGANIZATION, HOME_OU)
DataMapper.setup(:adapter => "Mysql",
DataMapper.setup(:adapter => "Mysql2",
:database => DB_DATABASE,
:host => DB_HOST,
:username => DB_USERNAME,
:password => DB_PASSWORD)
DataMapper.database.execute("SELECT nick FROM director") do |q|
cmd = "SELECT nick FROM director"
@director = []
DataMapper.database.query(cmd, as: :hash, symbolize_keys: false).each do |q|
raise "'Director' table is not filled" unless
q and name = q.fetch[0]
@director = [ Person.new('director') ]
q and name = q.fetch['nick']
@director.push(Person.new(name))
end
end

View File

@ -1,5 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright (C) 2021 OKTET Labs Ltd. All rights reserved.
# Copyright (C) 2021-2022 OKTET Labs Ltd. All rights reserved.
#
# Class Policy for Diary Management Application.
@ -95,7 +95,7 @@ class CustomerPolicy
end
def project_list
(Project.where("customer=? AND extra_rights IS NULL",
(Project.where("customer='%s' AND extra_rights IS NULL",
@user.organization.uid) +
extra_project_list).uniq.sort
end

View File

@ -1,5 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright (C) 2021 OKTET Labs Ltd. All rights reserved.
# Copyright (C) 2021-2022 OKTET Labs Ltd. All rights reserved.
#
# Class Project for Diary Management Application.
@ -100,16 +100,17 @@ class ProjectMapper < DataMapper
def find_approvals(id)
app = Hash.new
@@database.select_all("select * from approval where prj_id = ?",
id) { |row| app[row["who"]] = row["approver"] }
@@database.query("select * from approval where prj_id = '%s'" % id).collect { |row| app[row["who"]] = row["approver"] }
app
end
def save_approvals(id, app)
@@database.do("delete from approval where prj_id = ?", id)
cmd = "delete from approval where prj_id = '%s'" % id.to_s
@@database.query(cmd)
app.each do |who, approver|
@@database.do("insert into approval (prj_id, who, approver) " +
"values (?, ?, ?)", id, who, approver)
cmd = "insert into approval (prj_id, who, approver) values ('%s', '%s', '%s')" %
[@@database.escape(id.to_s), @@database.escape(who.to_s), @@database.escape(approver.to_s)]
@@database.query(cmd)
end
end
end
@ -131,7 +132,7 @@ class ProjectUI < Hash
@id = id
self.clear
if @id
DataMapper.database.execute("select * from project where id = #{@id}") do |q|
DataMapper.database.query("select * from project where id = #{@id}") do |q|
### For some reason MySQL driver always returns 0 in q.rows
# if q.rows != 1
# raise "Project #{@id} has #{q.rows} instances"
@ -142,8 +143,8 @@ class ProjectUI < Hash
self.delete("id")
end
self["cc"] = Array.new
DataMapper.database.select_all("select person from cc_list where " +
"prj_id = #{@id}") do |row|
DataMapper.database.query("select person from cc_list where " +
"prj_id = #{@id}").collect do |row|
self["cc"].push(row["person"])
end
end
@ -162,11 +163,10 @@ class ProjectUI < Hash
#raise "Create project #{data["name"]}"
inst = data.keys
inst -= ["cc"]
DataMapper.database.do("insert into project (" + inst.join(", ") +
") values (" + (inst.collect do "?" end).join(", ") +
")",
*(inst.collect do |field| data[field] end))
@id = DataMapper.database.select_one("select last_insert_id()")[0]
cmd = ("insert into project (" + inst.join(", ") + ") values (" + (inst.collect do "'%s'" end).join(", ") + ")") %
(inst.collect do |field| DataMapper.database.escape(data[field]) end)
DataMapper.database.query(cmd)
@id = DataMapper.database.query("select last_insert_id() as id").first["id"]
if data["cc"].length > 0
DataMapper.database.do("insert into cc_list (prj_id, person) values " +
(["(#{@id}, ?)"] * data["cc"].length).join(", "),
@ -184,12 +184,16 @@ class ProjectUI < Hash
end
end
if (changes - ["cc"]).length > 0
DataMapper.database.do("update project set " +
(changes.collect do
|field| field + " = ?" if field != "cc"
end).join(", ") +
" where id = #{@id}",
*(changes.collect do |field| data[field] end));
cmd = ("update project set " + (changes.collect do |field| field + " = %s" if field != "cc" 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'" % DataMapper.database.escape(data[field].to_s)
end
t
end)
DataMapper.database.query(cmd);
end
if (current["cc"] - data["cc"]).length > 0
DataMapper.database.do("delete from cc_list where " +
@ -422,7 +426,7 @@ class ProjectUI < Hash
if @cgi.tree_params["prj"].include?("edit")
attrs = @cgi.tree_params["prj"]["edit"]
attrs["hide_hrs"] = [attrs.include?("hide_hrs") ? 1 : 0]
attrs["hide_hrs"] = attrs.include?("hide_hrs") ? "1" : "0"
if attrs.include?("id")
update(attrs["id"])
attrs.delete("id")

View File

@ -1,5 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright (C) 2021 OKTET Labs Ltd. All rights reserved.
# Copyright (C) 2021-2022 OKTET Labs Ltd. All rights reserved.
#
# SQL class for Diary Management Application
@ -11,7 +11,8 @@ class SQL_Cache < Hash
@name = table
@string_expr = string_expr
@lists = Hash.new
@fields = @sql.columns(@name).collect { |col| col["name"] }
@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
@ -20,7 +21,8 @@ class SQL_Cache < Hash
def search(where)
list = Array.new
@sql.select_all("select * from #{@name} where #{where} order by id") do |row|
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
@ -53,12 +55,17 @@ class SQL_Cache < Hash
def create(data)
fields = data.keys & @fields
@sql.do("insert into #{@name} (" +
fields.join(", ") +
") values (" + fields.collect do "?" end.join(", ") +
")",
*(fields.collect do |field| data[field] end))
@sql.select_one("select last_insert_id()")[0]
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)
@ -70,16 +77,20 @@ class SQL_Cache < Hash
ch
end
end
@sql.do("update #{@name} set " +
changes.collect do |field|
field + " = ?"
end.join(", ") + " where id = #{id}",
*(changes.collect do |field| data[field] end)
) if changes.length > 0
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.do("delete from #{@name} where id = #{id}")
@sql.query("delete from #{@name} where id = #{id}")
super(id)
end
end