[Title] Changed DB access approach for "Project"
authordonghee yang <donghee.yang@samsung.com>
Thu, 25 Oct 2012 06:25:30 +0000 (15:25 +0900)
committerdonghee yang <donghee.yang@samsung.com>
Thu, 25 Oct 2012 06:25:30 +0000 (15:25 +0900)
src/build_server/BinaryUploadProject.rb
src/build_server/BuildServer.rb
src/build_server/BuildServerController.rb
src/build_server/CommonProject.rb
src/build_server/DistributionManager.rb
src/build_server/GitBuildProject.rb
src/build_server/PackageSync.rb
src/build_server/ProjectManager.rb
src/build_server/SocketJobRequestListener.rb

index b6db0de0899af7984d753f99a92ec009993c4c27..e0d6ee6eb9308d3d59e451a589c73f3e02098e3b 100644 (file)
@@ -152,4 +152,33 @@ class BinaryUploadProject < CommonProject
                @pkg_name = pkg_name
                return true
        end
+
+
+       def self.load(name, dist_name, server, db)
+               row, prj_os_list = load_row(name, dist_name, db)
+               prj_id = row['id']
+               prj_name = row['name']
+               prj_passwd = row['password']
+               prj_dist = row['dist_name']
+
+               new_project = BinaryUploadProject.new(prj_name, server, prj_os_list, prj_dist)
+
+               if not prj_passwd.empty? then new_project.passwd = prj_passwd end
+
+               if not new_project.load_db() then raise RuntimeError, "Project DB load failed!" end
+
+               return new_project
+       end
+
+
+       def save(db)
+               save_common(db)
+               init()
+               if not save_db() then raise RuntimeError, "Project DB load failed!" end
+       end
+
+
+       def unload(db)
+               unload_common(db)
+       end
 end
index a230ca62f874d8ffd4b613a5395b8a0e1a82f639..ea4fa8d2725792f88008ec956184c472e45f21df 100644 (file)
@@ -244,19 +244,19 @@ class BuildServer
                        db['AutoCommit'] = false
                        db.transaction do |dbh|
                                row = dbh.select_one("SELECT * FROM remote_build_servers WHERE svr_addr='#{saddr}'")
-                               if not row.nil? then
-                                       db['AutoCommit'] = true
-                                       return false
-                               end
+                               if not row.nil? then return false end
+
                                dbh.do "INSERT INTO remote_build_servers (svr_addr) VALUES ('#{saddr}')"
                        end
-                       db['AutoCommit'] = true
 
                rescue DBI::DatabaseError => e
                        @log.error "DB failed!"
                        @log.error e.errstr
                        @log.error e.backtrace.inspect
                        return false
+
+               ensure
+                       db['AutoCommit'] = true if not db.nil?
                end
 
                return true
@@ -271,13 +271,10 @@ class BuildServer
                        db['AutoCommit'] = false
                        db.transaction do |dbh|
                                row = dbh.select_one("SELECT * FROM remote_build_servers WHERE svr_addr='#{svr_addr}'")
-                               if row.nil? then
-                                       db['AutoCommit'] = true
-                                       return false
-                               end
+                               if row.nil? then return false end
+
                                dbh.do("DELETE FROM remote_build_servers WHERE svr_addr='#{svr_addr}'")
                        end
-                       db['AutoCommit'] = true
 
                rescue DBI::DatabaseError => e
                        @log.error "DB failed!"
@@ -285,6 +282,9 @@ class BuildServer
                        @log.error e.backtrace.inspect
 
                        return false
+
+               ensure
+                       db['AutoCommit'] = true if not db.nil?
                end
 
                return true
@@ -318,19 +318,19 @@ class BuildServer
                        db['AutoCommit'] = false
                        db.transaction do |dbh|
                                row = dbh.select_one("SELECT * FROM sync_pkg_servers WHERE pkgsvr_url='#{url}' and dist_name='#{dist}'")
-                               if not row.nil? then
-                                       db['AutoCommit'] = true
-                                       return false
-                               end
+                               if not row.nil? then return false end
+
                                db.do "INSERT INTO sync_pkg_servers (pkgsvr_url,period,dist_name) VALUES('#{url}','#{@pkg_sync_period}','#{dist}')"
                        end
-                       db['AutoCommit'] = true
 
                rescue DBI::DatabaseError => e
                        @log.error "DB failed!"
                        @log.error e.errstr
                        @log.error e.backtrace.inspect
                        return false
+
+               ensure
+                       db['AutoCommit'] = true if not db.nil?
                end
 
                return true
@@ -344,13 +344,10 @@ class BuildServer
                        db['AutoCommit'] = false
                        db.transaction do |dbh|
                                row = dbh.select_one("SELECT * FROM sync_pkg_servers WHERE pkgsvr_url='#{url}' and dist_name='#{dist}'")
-                               if row.nil? then
-                                       db['AutoCommit'] = true
-                                       return false
-                               end
+                               if row.nil? then return false end
+
                                dbh.do("DELETE FROM sync_pkg_servers WHERE pkgsvr_url='#{url}' and dist_name='#{dist}'")
                        end
-                       db['AutoCommit'] = true
 
                rescue DBI::DatabaseError => e
                        @log.error "DB failed!"
@@ -358,6 +355,9 @@ class BuildServer
                        @log.error e.backtrace.inspect
 
                        return false
+
+               ensure
+                       db['AutoCommit'] = true if not db.nil?
                end
 
                return true
@@ -392,19 +392,19 @@ class BuildServer
                        db['AutoCommit'] = false
                        db.transaction do |dbh|
                                row = dbh.select_one("SELECT * FROM supported_os WHERE name='#{os_name}'")
-                               if not row.nil? then
-                                       db['AutoCommit'] = true
-                                       return false
-                               end
+                               if not row.nil? then return false end
+
                                dbh.do "INSERT OR REPLACE INTO supported_os VALUES ('#{os_name}')"
                        end
-                       db['AutoCommit'] = true
 
                rescue DBI::DatabaseError => e
                        @log.error "DB failed!"
                        @log.error e.errstr
                        @log.error e.backtrace.inspect
                        return false
+
+               ensure
+                       db['AutoCommit'] = true if not db.nil?
                end
 
                return true
@@ -419,13 +419,10 @@ class BuildServer
                        db['AutoCommit'] = false
                        db.transaction do |dbh|
                                row = dbh.select_one("SELECT * FROM supported_os WHERE name='#{os_name}'")
-                               if row.nil? then
-                                       db['AutoCommit'] = true
-                                       return false
-                               end
+                               if row.nil? then return false end
+
                                dbh.do("DELETE FROM supported_os WHERE name='#{os_name}'")
                        end
-                       db['AutoCommit'] = true
 
                rescue DBI::DatabaseError => e
                        @log.error "DB failed!"
@@ -433,6 +430,9 @@ class BuildServer
                        @log.error e.backtrace.inspect
 
                        return false
+
+               ensure
+                       db['AutoCommit'] = true if not db.nil?
                end
 
                return true
@@ -539,7 +539,7 @@ class BuildServer
                # create DB
                begin
                        #DB open
-                       db = DBI.connect("DBI:#{@db_dsn}", @db_user, @db_passwd)
+                       db = get_db_connection()
                        case @db_dsn
                        when /^SQLite3:/ then inc="AUTOINCREMENT"
                        when /^Mysql:/ then inc="AUTO_INCREMENT"
@@ -561,9 +561,8 @@ class BuildServer
                        puts e.errstr
                        @log.error e.backtrace.inspect
                        result = false
-               ensure
-                       db.disconnect if db
                end
+
                return result
        end
 
index c3c7675106c33c3908d702a58d1c04f178e694fb..180d0bf523aa288c16d59b23ffb5e6973a58c057 100644 (file)
@@ -664,7 +664,7 @@ class BuildServerController
                puts ""
 
                puts "* PROJECT(S) *"
-               server.prjmgr.projects.each do  |p|
+               server.prjmgr.get_all_projects().each do  |p|
                        puts " * [#{p.dist_name}]  #{p.name}"
                end
        end
index 54254e9680ca9123d59babda990a9e57dff52d2e..9e2406c336551988cf1fffa3ed0e7801f80d757b 100644 (file)
@@ -52,6 +52,11 @@ class CommonProject
        end
 
 
+       def ==(y)
+               @name == y.name and @dist_name = y.dist_name
+       end
+
+
        def init()
                # create project directory if not exist
                if not File.exist? @path then FileUtils.mkdir_p @path end
@@ -112,4 +117,53 @@ class CommonProject
                end
                return nil
        end
+
+
+       def self.load_row(name, dist_name, db)
+               row = db.select_one("SELECT * FROM projects WHERE name='#{name}' and dist_name='#{dist_name}'")
+               if row.nil? then return nil end
+
+               # get supported_os
+               prj_id = row['id']
+               os_list = []
+               rows = db.select_all("SELECT os_name FROM project_os WHERE prj_id=#{prj_id}")
+               rows.each do |r|
+                       os_list.push r['os_name']
+               end
+
+               return row, os_list
+       end
+
+
+       protected
+       def save_common(db)
+               row = db.select_one("SELECT * FROM projects WHERE name='#{@name}' and dist_name='#{@dist_name}'")
+               if row.nil? then
+                       db.do "INSERT INTO projects (name,type,password,dist_name) VALUES ('#{@name}','#{@type}','#{@passwd}','#{@dist_name}')"
+                       case @server.db_dsn
+                       when /^SQLite3:/ then prj_id = db.select_one("select last_insert_rowid()")[0]
+                       when /^Mysql:/ then prj_id = db.func(:insert_id)
+                       else prj_id = db.select_one("select last_insert_rowid()")[0]
+                       end
+                       @os_list.each do |os|
+                               db.do "INSERT INTO project_os VALUES('#{prj_id}','#{os}')"
+                       end
+               else
+                       db.do "UPDATE projects SET type='#{@type}',password='#{@passwd}' WHERE name='#{@name}' and dist_name='#{@dist_name}')"
+                       db.do "DELETE FROM project_os WHERE prj_id=#{row['prj_id']}"
+                       prj_id = row['prj_id']
+                       @os_list.each do |os|
+                               db.do "INSERT INTO project_os VALUES('#{prj_id}','#{os}')"
+                       end
+               end
+       end
+       
+
+       protected
+       def unload_common(db)
+               row = db.select_one("SELECT * FROM projects WHERE name='#{@name}' and dist_name='#{@dist_name}'")
+               if row.nil? then return end
+               db.do("DELETE FROM projects WHERE name='#{@name}' and dist_name='#{@dist_name}'")
+               db.do "DELETE FROM project_os WHERE prj_id=#{row['id']}"
+       end
 end
index 7ccccc1e3dc540ebe0823f641528c675621c6a49..c5d1504bb3f75325e2f37b70beac758b763de44a 100644 (file)
@@ -57,8 +57,8 @@ class PackageDistribution
        end
 
 
-       def self.unload(name, db)
-               db.do("DELETE FROM distributions WHERE name='#{name}'")
+       def unload(db)
+               db.do("DELETE FROM distributions WHERE name='#{@name}'")
        end
 
 
@@ -131,47 +131,51 @@ class DistributionManager
        def get_distribution(name)
                # conntect DB
                begin
-                       db = DBI.connect("DBI:#{@server.db_dsn}", @server.db_user, @server.db_passwd)
-                       begin
-                               db.do('ALTER TABLE distributions ADD COLUMN status VARCHAR(32) DEFAULT "OPEN"') 
-                       rescue DBI::DatabaseError => e
-                               # do nothing
+                       db = @server.get_db_connection()
+                       db['AutoCommit'] = false
+                       db.transaction do |dbh|
+                               return get_distribution_internal(name, dbh)
                        end
 
-                       return PackageDistribution.load(name, db)
-
                rescue DBI::DatabaseError => e
                        @server.log.error "DB loading failed!"
                        @server.log.error e.errstr
                        @server.log.error e.backtrace.inspect
+
                ensure
-                       db.disconnect if db
+                       db['AutoCommit'] = true if not db.nil?
                end
 
                return nil
        end
 
 
-       # check exist?
-       def distribution_exist?(name)
-               return get_distribution(name).nil? ? false : true
+       def get_distribution_internal(name, db)
+               begin
+                       db.do('ALTER TABLE distributions ADD COLUMN status VARCHAR(32) DEFAULT "OPEN"') 
+               rescue DBI::DatabaseError => e
+                               # do nothing
+               end
+
+               return PackageDistribution.load(name, db)
        end
 
 
        # add
        def add_distribution(name, pkgsvr_url, pkgsvr_ip, pkgsvr_port)
-               # check already exist
-               if distribution_exist?(name) then
-                       @server.log.info "The distribution \"#{name}\" already exists on server"
-                       @server.log.error "Adding distribution failed!"
-                       return false
-               end
-
                begin
                        # open DB
-                       db = DBI.connect("DBI:#{@server.db_dsn}", @server.db_user, @server.db_passwd)
-                       new_dist = PackageDistribution.new(name, pkgsvr_url, pkgsvr_ip, pkgsvr_port, "OPEN")
-                       new_dist.save(db)
+                       db = @server.get_db_connection()
+                       db['AutoCommit'] = false
+                       db.transaction do |dbh|
+                               if not get_distribution_internal(name, dbh).nil? then
+                                       @server.log.info "The distribution \"#{name}\" already exists on server"
+                                       @server.log.error "Adding distribution failed!"
+                                       return false
+                               end
+                               new_dist = PackageDistribution.new(name, pkgsvr_url, pkgsvr_ip, pkgsvr_port, "OPEN")
+                               new_dist.save(dbh)
+                       end
 
                rescue DBI::DatabaseError => e
                        @server.log.error "DB update failed!"
@@ -180,7 +184,7 @@ class DistributionManager
                        return false
 
                ensure
-                       db.disconnect if db
+                       db['AutoCommit'] = true if not db.nil?
                end
                
                @server.log.info "Added a new distribution \"#{name}\""
@@ -190,16 +194,20 @@ class DistributionManager
 
        # remove
        def remove_distribution(name)
-               if not distribution_exist?(name) then
-                       @server.log.error "The distribution \"#{name}\" does not exists on server"
-                       @server.log.error "Removing distribution failed!"
-                       return false
-               end
 
                begin
                        # open DB
-                       db = DBI.connect("DBI:#{@server.db_dsn}", @server.db_user, @server.db_passwd)
-                       PackageDistribution.unload(name, db)
+                       db = @server.get_db_connection()
+                       db['AutoCommit'] = false
+                       db.transaction do |dbh|
+                               dist = get_distribution_internal(name, dbh)
+                               if dist.nil? then
+                                       @server.log.error "The distribution \"#{name}\" does not exists on server"
+                                       @server.log.error "Removing distribution failed!"
+                                       return false
+                               end
+                               dist.unload(dbh)
+                       end
 
                rescue DBI::DatabaseError => e
                        @server.log.error "DB update failed!"
@@ -208,7 +216,7 @@ class DistributionManager
                        return false
 
                ensure
-                       db.disconnect if db
+                       db['AutoCommit'] = true if not db.nil?
                end
 
                @server.log.info "Removed the distribution \"#{name}\""
@@ -219,21 +227,25 @@ class DistributionManager
        def get_first_distribution()
                begin
                        # open DB
-                       db = DBI.connect("DBI:#{@server.db_dsn}", @server.db_user, @server.db_passwd)
-                       begin
-                               db.do('ALTER TABLE distributions ADD COLUMN status VARCHAR(32) DEFAULT "OPEN"') 
-                       rescue DBI::DatabaseError => e
-                               # do nothing
+                       db = @server.get_db_connection()
+                       db['AutoCommit'] = false
+                       db.transaction do |dbh|
+                               begin
+                                       dbh.do('ALTER TABLE distributions ADD COLUMN status VARCHAR(32) DEFAULT "OPEN"') 
+                               rescue DBI::DatabaseError => e
+                                       # do nothing
+                               end
+
+                               return PackageDistribution.load_first(dbh)
                        end
 
-                       return PackageDistribution.load_first(db)
-
                rescue DBI::DatabaseError => e
                        @server.log.error "DB loading failed!"
                        @server.log.error e.errstr
                        @server.log.error e.backtrace.inspect
+
                ensure
-                       db.disconnect if db
+                       db['AutoCommit'] = true if not db.nil?
                end
 
                return nil
@@ -243,20 +255,24 @@ class DistributionManager
        def get_all_distributions()
                begin
                        # open DB
-                       db = DBI.connect("DBI:#{@server.db_dsn}", @server.db_user, @server.db_passwd)
-                       begin
-                               db.do('ALTER TABLE distributions ADD COLUMN status VARCHAR(32) DEFAULT "OPEN"') 
-                       rescue DBI::DatabaseError => e
-                               # do nothing
+                       db = @server.get_db_connection()
+                       db['AutoCommit'] = false
+                       db.transaction do |dbh|
+                               begin
+                                       dbh.do('ALTER TABLE distributions ADD COLUMN status VARCHAR(32) DEFAULT "OPEN"') 
+                               rescue DBI::DatabaseError => e
+                                       # do nothing
+                               end
+                               return PackageDistribution.load_all(dbh)
                        end
-                       return PackageDistribution.load_all(db)
 
                rescue DBI::DatabaseError => e
                        @server.log.error "DB loading failed!"
                        @server.log.error e.errstr
                        @server.log.error e.backtrace.inspect
+
                ensure
-                       db.disconnect if db
+                       db['AutoCommit'] = true if not db.nil?
                end
 
                return []
@@ -264,17 +280,18 @@ class DistributionManager
 
 
        def set_distribution_lock(name, value=true)
-               # check already exist
-               dist = get_distribution(name)
-               if dist.nil? then
-                       return false
-               end
-
                begin
                        # open DB
-                       db = DBI.connect("DBI:#{@server.db_dsn}", @server.db_user, @server.db_passwd)
-                       dist.status = value ? "LOCKED" : "OPEN"
-                       dist.save(db)
+                       db = @server.get_db_connection()
+                       db['AutoCommit'] = false
+                       db.transaction do |dbh|
+                               # check already exist
+                               dist = get_distribution_internal(name, dbh)
+                               if dist.nil? then return false end
+
+                               dist.status = value ? "LOCKED" : "OPEN"
+                               dist.save(dbh)
+                       end
 
                rescue DBI::DatabaseError => e
                        @server.log.error "DB update failed!"
@@ -283,7 +300,7 @@ class DistributionManager
                        return false
 
                ensure
-                       db.disconnect if db
+                       db['AutoCommit'] = true if not db.nil?
                end
        
                if value then   
index 0e0e85be9c4807a2098d009c0980ac0260025f06..18db1e5157d9a2bb562ad1a1ac5c2e69c5159da1 100644 (file)
@@ -235,4 +235,35 @@ class GitBuildProject < CommonProject
                end
                return true
        end
+
+
+       def self.load(name, dist_name, server, db)
+               row, prj_os_list = load_row(name, dist_name, db)
+               if row.nil? then return nil end
+
+               prj_id = row['id']
+               prj_name = row['name']
+               prj_passwd = row['password']
+               prj_dist = row['dist_name']
+
+               new_project = GitBuildProject.new(prj_name, server, prj_os_list, prj_dist)
+
+               if not prj_passwd.empty? then new_project.passwd = prj_passwd end
+
+               if not new_project.load_db() then raise RuntimeError, "Project DB load failed!" end
+
+               return new_project
+       end
+
+       
+       def save(db)
+               save_common(db)
+               init()
+               if not save_db() then raise RuntimeError, "Project DB load failed!" end
+       end
+
+
+       def unload(db)
+               unload_common(db)
+       end
 end
index a0c29b2a5ec578b5646491336a29cc92270eca02..c3498dab17574f1f77ef58168ba1ba553e9d9541 100644 (file)
@@ -142,7 +142,7 @@ class PackageSyncAction < Action
                @main_client.update()
 
                # for all BINARY project
-               bin_prjs = @server.prjmgr.projects.select { |p| (p.type == "BINARY") }
+               bin_prjs = @server.prjmgr.get_all_projects().select { |p| (p.type == "BINARY") }
                bin_prjs.each do  |p|
                        pkg_name = p.pkg_name
                        p.os_list.each do  |os|
index 3f825032e3e5f5ba694346b6c3c23739201f32b0..a952756fc008235fef08813ac0e62f57e29696a2 100644 (file)
@@ -36,12 +36,10 @@ require "PackageManifest.rb"
 require "package.rb"
 
 class ProjectManager
-       attr_accessor :projects
 
        # initialize
        def initialize( server )
                @server = server
-               @projects = []
                @project_root = "#{@server.path}/projects"
        end
 
@@ -52,85 +50,174 @@ class ProjectManager
                if not File.exist? @project_root then
                        FileUtils.mkdir_p @project_root
                end
-
-               # load_data base
-               load_db()
        end
 
 
        # get_project of the name
-       def get_project ( name, dist_name )
-               @projects.each do |prj|
-                       if prj.name == name and prj.dist_name == dist_name then return prj end
+       def get_project(name, dist_name)
+               begin
+                       db = @server.get_db_connection()
+                       db['AutoCommit'] = false
+                       db.transaction do |dbh|
+                               return get_project_internal(name, dist_name, dbh)
+                       end
+
+               rescue DBI::DatabaseError => e
+                       @server.log.error "DB failed!"
+                       @server.log.error e.errstr
+                       @server.log.error e.backtrace.inspect
+
+               ensure
+                       db['AutoCommit'] = true if not db.nil?
                end
 
                return nil
        end
 
 
-       def add_git_project(name , repos, branch, passwd, os_list, dist_name)
-               load_db()
+       def get_all_projects()
+               result = []
 
-               prj = get_project(name, dist_name)
-               if not prj.nil? then return false end
+               begin
+                       db = @server.get_db_connection()
+                       db['AutoCommit'] = false
+
+                       db.transaction do |dbh|
+                               rows = dbh.select_all("SELECT * FROM projects")
+                               rows.each do |row|
+                                       prj_name = row['name']
+                                       prj_dist = row['dist_name']
+                                       prj_type = row['type']
+                                       if prj_type == "GIT" then
+                                               result.push GitBuildProject.load(prj_name, prj_dist, @server, dbh)
+                                       else
+                                               result.push BinaryUploadProject.load(prj_name, prj_dist, @server, dbh)
+                                       end
+                               end
+                       end
+                       
+                       return result
+       
+               rescue DBI::DatabaseError => e
+                       @server.log.error "DB failed!"
+                       @server.log.error e.errstr
+                       @server.log.error e.backtrace.inspect
 
-               new_prj = GitBuildProject.new(name, @server, os_list, dist_name, repos, branch)
-               if not passwd.nil? and not passwd.empty? then
-                       new_prj.passwd = passwd
+               ensure
+                       db['AutoCommit'] = true if not db.nil?
                end
-               new_prj.dist_name = dist_name
-               new_prj.repository = repos
-               new_prj.branch = branch
 
-               new_prj.init()
+               return result
+       end
 
-               @projects.push new_prj
 
-               # write configuration
-               save_db()
+       def add_git_project(name, repos, branch, passwd, os_list, dist_name)
+               begin
+                       db = @server.get_db_connection()
+                       db['AutoCommit'] = false
+                       db.transaction do |dbh|
+                               prj = get_project_internal(name, dist_name, dbh)
+                               if not prj.nil? then
+                                       @server.log.error "Adding project failed!: the project \"#{name}\"(#{dist_name}) already exists"
+                                       return false
+                               end
+                               
+                               # create new object
+                               new_prj = GitBuildProject.new(name, @server, os_list, dist_name, repos, branch)
+                               if not passwd.nil? and not passwd.empty? then
+                                       new_prj.passwd = passwd
+                               end
 
+                               # save to db
+                               new_prj.save(dbh)
+                       end
+       
+               rescue DBI::DatabaseError => e
+                       @server.log.error "DB failed!"
+                       @server.log.error e.errstr
+                       @server.log.error e.backtrace.inspect
+
+                       return false
+               ensure
+                       db['AutoCommit'] = true if not db.nil?
+               end
+
+               @server.log.info "Added new GIT project \"#{name}\"(#{dist_name})"
                return true
        end
 
 
        def add_binary_project(name, pkg_name, passwd, os_list, dist_name)
-               load_db()
-
-               prj = get_project(name, dist_name)
-               if not prj.nil? then return false end
-
-               new_prj = BinaryUploadProject.new(name, @server, os_list, dist_name, pkg_name)
-               if not passwd.nil? and not passwd.empty? then
-                       new_prj.passwd = passwd
-               end
-               new_prj.dist_name = dist_name
-               new_prj.pkg_name = pkg_name
+               begin
+                       db = @server.get_db_connection()
+                       db['AutoCommit'] = false
+                       db.transaction do |dbh|
+                               prj = get_project_internal(name, dist_name, dbh)
+                               if not prj.nil? then
+                                       @server.log.error "Adding project failed!: the project \"#{name}\"(#{dist_name}) already exists"
+                                       return false
+                               end
+                               
+                               # create new object
+                               new_prj = BinaryUploadProject.new(name, @server, os_list, dist_name, pkg_name)
+                               if not passwd.nil? and not passwd.empty? then
+                                       new_prj.passwd = passwd
+                               end
 
-               new_prj.init()
+                               # save to db
+                               new_prj.save(dbh)
 
-               @projects.push new_prj
+                               # init
+                               new_prj.init()
+                       end
+       
+               rescue DBI::DatabaseError => e
+                       @server.log.error "DB failed!"
+                       @server.log.error e.errstr
+                       @server.log.error e.backtrace.inspect
 
-               save_db()
+                       return false
+               ensure
+                       db['AutoCommit'] = true if not db.nil?
+               end
 
+               @server.log.info "Added new BINARY project \"#{name}\"(#{dist_name})"
                return true
        end
 
 
        def remove_project( name, dist_name )
-               load_db()
 
-               # check project exist?
-               prj = get_project(name, dist_name)
-               if prj.nil? then return false end
+               begin
+                       # open DB
+                       db = @server.get_db_connection()
+                       db['AutoCommit'] = false
+                       db.transaction do |dbh|
+                               prj = get_project_internal(name, dist_name, dbh)
+                               if prj.nil? then
+                                       @server.log.error "The project \"#{name}\"(#{dist_name}) does not exists on server"
+                                       @server.log.error "Removing project failed!"
+                                       return false
+                               end
+                               # unload from DB
+                               prj.unload(dbh)
 
-               # remove project directory
-               FileUtils.rm_rf prj.path
+                               # remove project directory
+                               FileUtils.rm_rf prj.path
+                       end
 
-               # remove it from list
-               @projects.delete prj
 
-               save_db()
+               rescue DBI::DatabaseError => e
+                       @server.log.error "DB update failed!"
+                       @server.log.error e.errstr
+                       @server.log.error e.backtrace.inspect
+                       return false
 
+               ensure
+                       db['AutoCommit'] = true if not db.nil?
+               end
+
+               @server.log.info "Removed the project \"#{name}\"(#{dist_name})"
                return true
        end
 
@@ -139,7 +226,9 @@ class ProjectManager
        # if cannot create, return nil
        def create_new_job( name, os, dist_name )
                prj = get_project( name, dist_name )
-               if prj.nil? then return nil end
+               if prj.nil? then
+                       @server.log.error "Cannot get project info \"#{name}\"(#{dist_name})"
+               end
 
                return prj.create_new_job( os )
        end
@@ -163,7 +252,7 @@ class ProjectManager
                result = MultiBuildJob.new( @server )
 
                # create sub jobs
-               @projects.each do |prj|
+               get_all_projects().each do |prj|
                        if prj.type != "GIT" then next end
                        if prj.dist_name != dist_name then next end
 
@@ -190,7 +279,7 @@ class ProjectManager
        # will return [project,os,ver] list
        def get_projects_from_pkgs(pkgs, dist_name="BASE")
                result = []
-               @projects.each do |prj|
+               get_all_projects().each do |prj|
                        # check distribution name
                        if prj.dist_name != dist_name then next end
 
@@ -212,7 +301,7 @@ class ProjectManager
 
 
        def get_project_from_package_name(pkg_name, dist_name="BASE")
-               @projects.each do |prj|
+               get_all_projects().each do |prj|
                        # check project's distribution
                        if prj.dist_name != dist_name then next end
                        # check project provide target package
@@ -227,7 +316,7 @@ class ProjectManager
 
        # get project from git repository
        def get_git_project( repos, dist_name )
-               @projects.each do |prj|
+               get_all_projects().each do |prj|
                        # check project's distribution
                        if prj.dist_name != dist_name then next end
                        if prj.type == "GIT" and prj.repository == repos then
@@ -240,7 +329,7 @@ class ProjectManager
 
 
        def create_unnamed_git_project(repos, dist_name)
-               name = "UNNAMED_PRJ_#{@projects.count}"
+               name = "UNNAMED_PRJ_#{get_all_projects().count}"
                branch = "master"
                passwd = nil
                os_list = Utils.get_all_OSs()
@@ -251,98 +340,6 @@ class ProjectManager
        end
 
 
-       # save
-       def save_db()
-               result = true
-               begin
-                       # open #
-                       db = DBI.connect("DBI:#{@server.db_dsn}", @server.db_user, @server.db_passwd)
-
-                       # delete all rows
-                       db.do "DELETE FROM projects"
-                       db.do "DELETE FROM project_os"
-
-                       # insert  project info
-                       @projects.each do |prj|
-                               # COMMON
-                               db.do "INSERT INTO projects (name,type,password,dist_name) VALUES('#{prj.name}', '#{prj.type}', '#{prj.passwd}', '#{prj.dist_name}')"
-
-                               # OS
-                               case @server.db_dsn
-                               when /^SQLite3:/ then prj_id = db.select_one("select last_insert_rowid()")[0]
-                               when /^Mysql:/ then prj_id = db.func(:insert_id)
-                               else prj_id = db.select_one("select last_insert_rowid()")[0]
-                               end
-
-                               prj.os_list.each do |os|
-                                       db.do "INSERT INTO project_os VALUES('#{prj_id}','#{os}')"
-                               end
-
-                               if not prj.save_db() then raise RuntimeError ,"Save project DB is failed!" end
-                       end
-               rescue DBI::DatabaseError => e
-                       puts "DB update failed!"
-                       puts e.errstr
-                       result = false
-               ensure
-                       db.disconnect if db
-               end
-               return result
-       end
-
-
-       # load
-       def load_db()
-               result = true
-               @projects = []
-
-               begin
-                       # open DB
-                       db = DBI.connect("DBI:#{@server.db_dsn}", @server.db_user, @server.db_passwd)
-
-                       # distributions
-                       rs = db.execute "SELECT * FROM projects"
-                       rs.fetch_hash do |row|
-                               prj_id = row['id']
-                               prj_name = row['name']
-                               prj_type = row['type']
-                               prj_passwd = row['password']
-                               prj_dist = row['dist_name']
-
-                               @server.log.info "Loading project : #{prj_name}"
-                               # os
-                               prj_os_list = []
-                               rs2 = db.execute "SELECT os_name FROM project_os WHERE prj_id = #{prj_id}"
-                               rs2.fetch do |row2|
-                                       prj_os_list.push row2[0]
-                               end
-                               rs2.finish
-                               if prj_type == "GIT" then
-                                       new_project = GitBuildProject.new(prj_name, @server, prj_os_list, prj_dist)
-                               else
-                                       new_project = BinaryUploadProject.new(prj_name, @server, prj_os_list, prj_dist)
-                               end
-
-                               if not prj_passwd.empty? then
-                                       new_project.passwd = prj_passwd
-                               end
-
-                               if not new_project.load_db() then raise RuntimeError, "Project DB load failed!" end
-                               @projects.push new_project
-                       end
-                       rs.finish
-               rescue DBI::DatabaseError => e
-                       puts "DB loading failed!"
-                       puts e.errstr
-                       result = false
-               ensure
-                       rs.finish if not rs.finished?
-                       db.disconnect if db
-               end
-               return result
-       end
-
-
        # write configuration
        def write_configuration(name, repos, branch, passwd, os_list  )
                config_file = "#{@project_root}/#{name}/build"
@@ -371,4 +368,18 @@ class ProjectManager
                end
        end
 
+
+       private
+       def get_project_internal(name, dist_name, db)
+               row = db.select_one("SELECT * FROM projects WHERE name='#{name}' and dist_name='#{dist_name}'")
+               if row.nil? then return nil end
+               prj_type = row['type']
+
+               if prj_type == "GIT" then
+                       return GitBuildProject.load(name, dist_name, @server, db)
+               else
+                       return BinaryUploadProject.load(name, dist_name, @server, db)
+               end
+       end
+
 end
index bb9b7471b93acfd2794c85ef27e6cc6457fe79e4..57bb66f3bacfdee93c19b37ce54d410576cdd672 100644 (file)
@@ -473,7 +473,7 @@ class SocketJobRequestListener
                when "PROJECT"
                        BuildCommServer.send_begin(req)
                        # print GIT projects
-                       sorted_list = @parent_server.prjmgr.projects.sort { |x,y| x.name <=> y.name }
+                       sorted_list = @parent_server.prjmgr.get_all_projects().sort { |x,y| x.name <=> y.name }
                        sorted_list.each do |prj|
                                if prj.type != "GIT" then next end
                                BuildCommServer.send(req,"G,#{prj.name},#{prj.repository},#{prj.branch}")
@@ -639,12 +639,6 @@ class SocketJobRequestListener
                        BuildCommServer.send_end(req)
                        BuildCommServer.disconnect(req)
                        return
-               elsif not @parent_server.distmgr.distribution_exist?(dist_name) then
-                       BuildCommServer.send_begin(req)
-                       BuildCommServer.send(req,"Distribution not found!")
-                       BuildCommServer.send_end(req)
-                       BuildCommServer.disconnect(req)
-                       return
                end
 
                # create full build job