lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_tables.rb in knjrbfw-0.0.19 vs lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_tables.rb in knjrbfw-0.0.20
- old
+ new
@@ -1,32 +1,64 @@
+require "#{$knjpath}wref"
+
class KnjDB_sqlite3::Tables
attr_reader :db, :driver
def initialize(args)
@args = args
@db = @args[:db]
@driver = @args[:driver]
+
+ @list_mutex = Mutex.new
+ @list = Knj::Wref_map.new
end
def [](table_name)
- list = self.list
- return list[table_name.to_s] if list[table_name.to_s]
+ table_name = table_name.to_s
+
+ begin
+ return @list[table_name]
+ rescue WeakRef::RefError
+ #ignore.
+ end
+
+ self.list do |table_obj|
+ return table_obj if table_obj.name.to_s == table_name
+ end
+
raise Knj::Errors::NotFound.new("Table was not found: #{table_name}.")
end
def list
- list = {}
- q_tables = @db.select("sqlite_master", {"type" => "table"}, {"orderby" => "name"})
- while d_tables = q_tables.fetch
- list[d_tables[:name]] = KnjDB_sqlite3::Tables::Table.new(
- :db => @db,
- :driver => @driver,
- :data => d_tables
- )
+ ret = {} unless block_given?
+
+ @list_mutex.synchronize do
+ q_tables = @db.select("sqlite_master", {"type" => "table"}, {"orderby" => "name"}) do |d_tables|
+ obj = @list.get!(d_tables[:name])
+
+ if !obj
+ obj = KnjDB_sqlite3::Tables::Table.new(
+ :db => @db,
+ :driver => @driver,
+ :data => d_tables
+ )
+ @list[d_tables[:name]] = obj
+ end
+
+ if block_given?
+ yield(obj)
+ else
+ ret[d_tables[:Name]] = obj
+ end
+ end
end
- return list
+ if block_given?
+ return nil
+ else
+ return ret
+ end
end
def create(name, data)
sql = "CREATE TABLE `#{name}` ("
@@ -52,10 +84,13 @@
class KnjDB_sqlite3::Tables::Table
def initialize(args)
@db = args[:db]
@driver = args[:driver]
@data = args[:data]
+
+ @list = Knj::Wref_map.new
+ @indexes_list = Knj::Wref_map.new
end
def name
return @data[:name]
end
@@ -67,33 +102,49 @@
def optimize
raise "stub!"
end
+ def table
+ return @db.tables[@table_name]
+ end
+
def column(name)
list = self.columns
return list[name] if list[name]
raise Knj::Errors::NotFound.new("Column not found: #{name}.")
end
def columns
- if !@list
- @db.cols
- @list = {}
+ @db.cols
+ ret = {}
+
+ @db.q("PRAGMA table_info(`#{@driver.esc_table(self.name)}`)") do |d_cols|
+ obj = @list.get!(d_cols[:name])
- q_cols = @db.query("PRAGMA table_info(`#{@driver.esc_table(self.name)}`)")
- while d_cols = q_cols.fetch
- @list[d_cols[:name]] = KnjDB_sqlite3::Columns::Column.new(
- :table => self,
+ if !obj
+ obj = KnjDB_sqlite3::Columns::Column.new(
+ :table_name => self.name,
:db => @db,
:driver => @driver,
:data => d_cols
)
+ @list[d_cols[:name]] = obj
end
+
+ if block_given?
+ yield(obj)
+ else
+ ret[d_cols[:name]] = obj
+ end
end
- return @list
+ if block_given?
+ return nil
+ else
+ return ret
+ end
end
def create_columns(col_arr)
col_arr.each do |col_data|
#if col_data.key?("after")
@@ -215,22 +266,45 @@
@db.query(sql)
@db.query("DROP TABLE `#{temp_name}`")
end
def index(name)
- list = self.indexes
- return list[name] if list[name]
+ name = name.to_s
+
+ begin
+ return @indexes_list[name]
+ rescue WeakRef::RefError
+ if @db.opts[:index_append_table_name]
+ tryname = "#{self.name}__#{name}"
+
+ begin
+ return @indexes_list[tryname]
+ rescue WeakRef::RefError
+ #ignore.
+ end
+ else
+ #ignore
+ end
+ end
+
+ self.indexes do |index|
+ return index if index.name.to_s == name
+ end
+
raise Knj::Errors::NotFound.new("Index not found: #{name}.")
end
def indexes
- if !@indexes_list
- @db.indexes
- @indexes_list = {}
+ @db.indexes
+ ret = {}
+
+ @db.q("PRAGMA index_list(`#{@driver.esc_table(self.name)}`)") do |d_indexes|
+ next if d_indexes[:Key_name] == "PRIMARY"
- q_indexes = @db.query("PRAGMA index_list(`#{@driver.esc_table(self.name)}`)")
- while d_indexes = q_indexes.fetch
+ obj = @indexes_list.get!(d_indexes[:name])
+
+ if !obj
if @db.opts[:index_append_table_name]
match_name = d_indexes[:name].match(/__(.+)$/)
if match_name
name = match_name[1]
@@ -239,22 +313,32 @@
end
else
name = d_indexes[:name]
end
- @indexes_list[name] = KnjDB_sqlite3::Indexes::Index.new(
- :table => self,
+ obj = KnjDB_sqlite3::Indexes::Index.new(
+ :table_name => self.name,
:db => @db,
:driver => @driver,
:data => d_indexes
)
-
- @indexes_list[name].columns << name
+ obj.columns << name
+ @indexes_list[d_indexes[:name]] = obj
end
+
+ if block_given?
+ yield(obj)
+ else
+ ret[d_indexes[:name]] = obj
+ end
end
- return @indexes_list
+ if block_given?
+ return nil
+ else
+ return ret
+ end
end
def create_indexes(index_arr)
index_arr.each do |index_data|
raise "No name was given." if !index_data.key?("name") or index_data["name"].strip.length <= 0
@@ -274,10 +358,9 @@
end
sql << ")"
@db.query(sql)
- @indexes_list = nil
end
end
def data
ret = {
\ No newline at end of file