2013-03-05 3 views
3

Моя проблема в том, что первый возвращаемый набор возвращает $ sub1, прежде чем он может использоваться в совпадении строк, чтобы сценарий не продолжался. Я попытался включить остальную часть скрипта в первый возвращаемый набор, и он работает, но ... Я получаю несколько сообщений пользователю, а канал - для остальных 2 возвратов.Mysqltcl foreach loop tcl

В любом случае, чтобы исправить это, чтобы он не отправлял несколько сообщений пользователям и каналу , потому что для каждого юга в «foreach sub» создается строка для пользователей 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 { 
     } 
    } 
} 

Его трудно объяснить, что именно им пытается достичь.

В конце концов результат им пытаются достичь это ...

  • Установить $ подписку из регулярных выражений
  • Список всех подлодок в БД
  • Covert все% в суб в БД до * на следующий матч
  • Try, чтобы соответствовать подлодку к $ подписки
  • Если они совпадают, то переходите к следующему SELECT,
  • Выберите все «ПОЛЬЗОВАТЕЛИ» из БД, где субполяция похожа на% sub%
  • Затем отправьте каждому пользователю сообщение, которое соответствует выбранному
  • Последний установленный возврат подсчитывает количество пользователей, которые соответствуют выбранному и отправляют сообщение на канал

После использования решения, предложенного Доналом. Кажется, что все работает так, как нужно, с одной маленькой проблемой. [String match -nocase [get_subscription $ SQL (conn)] * $ subscription] часть кода не сохраняет каждую в качестве переменной, подлежащей проверке. Какая бы ни была строка, сначала она использует вместо нее и останавливается, а не заканчивает список, чтобы увидеть, есть ли больше совпадений. Некоторые из записей добавляются по-разному, но должны обеспечивать одинаковые результаты. например, некоторые записи добавляются как The.TV.Show.S01 или% TV% Show% S01 Это означает, что он должен совпадать с обоими разделами и получать точное количество и пользователей.

+0

Если вам сложно объяснить, что вы пытаетесь выполнить, напишите несколько разных * коротких * вопросов, каждый из которых касается только одной понятной проблемы. В его нынешнем виде я не уверен, как подойти к вашему вопросу. – kostix

ответ

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

+0

, другие проблемы заключаются в том, что подписки сохраняются в разных форматах в БД, а некоторые могут быть% tv % show или the.tv.show, поэтому мне нужно, чтобы он соответствовал не только одному – Maphex