2013-03-05 61 views
3

我的問題是,第一個返回的字符串匹配中可以使用它之前,它將丟棄$ sub1,所以腳本不會繼續。我已經嘗試在第一次設置的回報中包含腳本的其餘部分,並且它可以工作,但是...我向用戶獲取了多條消息,而其他2個設置返回了該通道。Mysqltcl foreach循環tcl

無論如何修復它,以便它不會將多條消息發送給用戶和頻道 ,因爲「foreach子」中的每個子項都爲pm用戶和pm通道生成一行,根據數據庫中有多少匹配,將1條或2條消息發送到200條消息。

bind pubm - * bind_pubm 
    proc bind_pubm {nick uhost handle channel text} { 
     global SQL; sql:start 

     set regexp {^!sub (.*) *$} 
     if {[regexp -nocase -- $regexp $text -> subscription]} { 
      if {[string match -nocase *HDTV* $subscription] || [string match -nocase *S??E??* $subscription]} { 

      set return [mysqlsel $SQL(conn) "select sub from DB_Subs where category='TV'" -list] 
      foreach {sub} $return {  ; # Lists all the subs in the DB for matching. 
      regsub -all -- {%} $sub "*" sub1 ; # Replaces % in SQL to * for the String match later. 
      } 

      if {[string match -nocase $sub1* $subscription]} { ; # Matches if a sub in the previous list matches the regexp subscription fromthe beginging of proc. 
       set return [mysqlsel $SQL(conn) "select user from DB_Subs where sub LIKE '[mysqlescape $sub]%' AND category='TV'" -list] 
        foreach line $return { 
         foreach {user} $line break 
          if {[onchan $user $beta]} {  ; # If the user is on the channel it PM each user. 
           putnow "PRIVMSG $nick : Subscription found matching your request." 
          } else { 
         } 
        } 

      set return [mysqlsel $SQL(conn) "select count(DISTINCT user) from DB_Subs where sub LIKE '[mysqlescape $sub]%' AND category='TV'" -flatlist] ; # Counts the users for the Channel message. 
       foreach {users} $return break 
        putnow "PRIVMSG $beta :SUBSCRIPTION: $users Users With Subscriptions for $subscription" 
      } else { 
      } 
     } else { 
     } 
    } 
} 

它很難解釋什麼是試圖完成。

最終的結果我嘗試達到是...

  • 從正則表達式,設置$認購
  • 列出所有潛艇的DB
  • 隱蔽內的所有%子的內數據庫爲*爲符合以下
  • 嘗試匹配子到$認購
  • 如果他們匹配,則繼續下一個SELECT
  • 從DB中選擇所有的「USERS」,其中子是%sub%
  • 然後向每個用戶發送與選擇相匹配的消息
  • 上次設置的返回數計數匹配選擇和發送消息通道

使用Donal提出的解決方案後。一切似乎都像一個小問題一樣表現出來。代碼中的[字符串匹配-nocase [get_subscription $ SQL(conn)] * $ subscription]部分不會將每個值都保存爲要檢查的變量。首先使用哪一行代替,然後停止而不是完成列表以查看是否有更多匹配。某些條目以不同方式添加,但應提供相同的結果。例如一些條目被添加爲The.TV.Show.S01或%TV%顯示%S01 這意味着它應該匹配兩個部分並獲得準確的數量和用戶。

+0

如果很難解釋你想要完成什麼,請發佈幾個不同的*短*問題,每個問題都只涉及一個可理解的問題。在目前的形式下,我不確定如何處理您的問題。 – kostix 2013-03-05 09:45:03

回答

1

這可能很困難,因爲你有太多的一塊。嘗試將代碼分解成更小的部分,以完成明確定義的任務。這被稱爲重構,這是讓你的代碼易於理解的重要部分。

這裏有幾個建議重構:

proc get_subscription {conn} { 
    set return [mysqlsel $conn "select sub from DB_Subs where category='TV'" -list] 
    foreach {sub} $return { 
     regsub -all -- {%} $sub "*" sub1 
    } 
    return $sub1 
} 

proc notify_subscription_user {conn nick sub beta} { 
    set return [mysqlsel $conn "select user from DB_Subs where sub LIKE '[mysqlescape $sub]%' AND category='TV'" -list] 
    foreach line $return { 
     lassign $line user 
     if {[onchan $user $beta]} { 
      putnow "PRIVMSG $nick : Subscription found matching your request." 
     } 
    } 
} 

proc send_subscription_message {conn sub beta subscription_text} { 
    set return [mysqlsel $conn "select count(DISTINCT user) from DB_Subs where sub LIKE '[mysqlescape $sub]%' AND category='TV'" -flatlist] 
    lassign $return users 
    putnow "PRIVMSG $beta :SUBSCRIPTION: $users Users With Subscriptions for $subscription_text" 
} 

有了這些,我們就可以重新編寫代碼的其餘部分是這樣的(除去空else條款,在線路分裂表達,結合嵌套if測試;所有基本的東西):

bind pubm - * bind_pubm 
proc bind_pubm {nick uhost handle channel text} { 
    global SQL; sql:start 

    if { 
     [regexp -nocase -- {^!sub (.*) *$} $text -> subscription] 
     && ([string match -nocase *HDTV* $subscription] 
      || [string match -nocase *S??E??* $subscription]) 
     && [string match -nocase [get_subscription $SQL(conn)]* $subscription] 
    } then { 
     notify_subscription_user $SQL(conn) $nick $sub $beta 
     send_subscription_message $SQL(conn) $sub $beta $subscription 
    } 
} 

這是否解決問題了嗎?我不知道,但它應該給你一個更好的基礎從開始。

+0

看起來像這個過程將工作,但即時通訊有問題與$ sub不會停留設置它在notify_subscription_user和send_subscription_message – Maphex 2013-03-07 04:16:02

+0

其他問題是訂閱以各種格式保存在數據庫中有些可能是%電視%show或the.tv.show,所以我需要它來匹配兩個不只是一個 – Maphex 2013-03-07 04:43:45