2012-12-01 33 views
0

我的數據文件:由空格分隔的每個條目導入日誌文件數據到應用程序

VOTE 1168241980 Campaign:ssss_uk_01B Validity:during 
Choice:Tupele CONN:MIG00VU MSISDN:00088866655598 
GUID:A34-FDS87-FHDHDH-DHDHDHD0 Shortcode:63334 

:votes.txt與行相同地形成。我目前有19行的樣本。

領域:

CONN:MIG00VU MSISDN:00088866655598 
GUID:A34-FDS87-FHDHDH-DHDHDHD0 Shortcode:63334 

不被用於這項工作。

#!/usr/bin/perl 

use warnings; 
use strict; 
use Switch; 
use DBI(); 

# 
# _voting.pl 
# 

# Connect to the database. 
my $dbh = DBI->connect("DBI:mysql:database=sms_voting;host=localhost", 
        "sisisi", "*********", 
        {'RaiseError' => 1}); 

my $sth = $dbh->prepare("INSERT INTO voting 
(epoch, validity, choice, campaigns_id, candidates_id) VALUES (?,?,?,?,?)"); 

open (LOGFILE, '/var/www/voting/votes.txt') or die("Could not open log file."); 

my $errors = 0; 
my $campaign_id = 0; 
my $candidate_id = 0; 

foreach my $line (<LOGFILE>) { 

    my ($vote, $epoch, $campaign, $validity, 
$choice, $CONN, $MSISDN, $GUID, $Shortcode) = split(' ', $line); 

# parse the field:value entries... 
$campaign = substr $campaign, 8, 11, ''; 
$validity = substr $validity, 9, 6, ''; # during 
$choice = substr $choice, 7, 10, ''; # Brown 

# case statements to define correct foreign keys... 
switch ($campaign) { 
     case ("ssss_uk_01B") { $campaign_id = 1 } 
     case ("ssss_uk_01C") { $campaign_id = 2 } 
     case ("ssss_uk_01D") { $campaign_id = 3 } 
     case ("ssss_uk_01E") { $campaign_id = 4 } 
     case ("ssss_uk_01F") { $campaign_id = 5 } 
     case ("ssss_uk_01G") { $campaign_id = 6 } 
} 

switch ($choice) { 
     case ("Brown")  { $candidate_id = 1 } 
     case ("Cameron") { $candidate_id = 2 } 
     case ("Balls")  { $candidate_id = 3 } 
     case ("Green")  { $candidate_id = 4 } 
     case ("Boring")  { $candidate_id = 5 } 
     case ("Tupele")  { $candidate_id = 6 } 
} 

if ($epoch && $validity && $choice && $campaign_id && $candidate_id) { 

    $sth->execute($epoch, $validity, $choice, $campaign_id, $candidate_id); 
    # debug 
    print "$epoch $validity $choice \n"; # 1161048980 during Green 
    next; 
} 

$errors++; 
} 

close (LOGFILE); 

# debug 
print qq(errors=$errors\n); 

對foreach,在$活動和$選擇變量的各回路通過switch語句,以便確定candidate_id & CAMPAIGN_ID號運行。這些外鍵將映射到候選人&廣告系列表。

查看:http://acookson.org/wp-content/themes/cookie_23112012/img/sms_voting.png爲數據庫模型。

INSERT INTO voting (epoch, validity, choice, campaigns_id, candidates_id) 
VALUES (1161048980,'during','Brown', 1, 1), 
(1161048980,'during','Tupele', 3, 5), ... etc 

任何空在votes.txt檢測值將導致$誤差變量被遞增。

該腳本似乎成功地通過votes.txt循環但未能初始化:$ campaign_id & $ candidate_id variables resp。完成後,錯誤= 19被打印到終端;我的示例數據votes.txt中的總行數;含義 此文件中的每一行未能插入到數據庫中。

mysql> select * from voting; 
Empty set (0.00 sec) 

證實了這一點。

腳本報告沒有語法錯誤;因此它更低一些。沒有開關就能正常工作;因此這有所縮小。但我無法看到交換機的問題,所以我在這裏尋找建議。

+0

據我所知,'Switch'模塊在perl v5.10.1中已被棄用,並由'given/when'功能取代。參見[perldoc perlsyn](http://perldoc.perl.org/perlsyn.html#Switch-Statements)。但是,我會建議您使用散列來代替該查找。 – TLP

回答

0

不知道你的問題是什麼,但是這裏有一些關於你的Switch語句和其他代碼的指針。

據我所知,use Switch功能/模塊已在perl v5.10.1中被替換爲given/when功能,現在已被棄用。就我個人而言,我一直認爲這些陳述有點奇怪和不可靠。由於perl是一種非常靈活的語言,因此無論如何都無法替代。

在你的情況,我建議哈希查找來代替:

my %camp = ("ssss_uk_01B" => 1, 
      "ssss_uk_01C" => 2, 
      ...); 
my %cand = ("Brown"  => 1, 
      "Cameron"  => 2, 
      ...); 

$campaign_id = $camp{$campaign}; 
$candidate_id = $cand{$choice} 

如果您需要提供默認值,你可以使用defined-or賦值運算符:

$campaign_id //= "default value here"; 

substr分配是有點不對。首先,您使用的所有四個參數,這是的perldoc這樣描述:

substr EXPR,OFFSET,LENGTH,REPLACEMENT 

這意味着你與''空字符串替換你的對手。這會影響變量本身,並會刪除您想要的數據,如果自己留下的話。你的情況下的長度也是不需要的,因爲它是你之後字符串的結尾。最後,通過使用substr聲明的返回值,可以節省您的時間。

最後,當我試用您的作業時,我的第一個作業($campaign)出現一次性錯誤。輸出是:ssss_uk_01,並且您期望ssss_uk_01

要正確使用substr功能,您應該使用:

$campaign = substr $campaign, 9; 
$validity = substr $validity, 9; 
$choice = substr $choice, 7; 
+0

非常豐富,謝謝。 – cookie

+0

不客氣。 – TLP

0

我同意TLP的使用哈希值的查找表的建議。但是在實際的應用程序中,這些查找表應該填充數據庫查找,以避免在其他表中的數據更改時需要更改應用程序。

我也傾向於不太相信日誌中數據的格式。使用分割減輕了需要知道標籤的確切長度+結腸大小。除此之外,我還建議在將數據用作查找哈希中的鍵之前對數據進行規範化。在這個例子中,我只是把它全部寫成小寫。

當您使用警告時,您不妨使用warn函數來發出有關錯誤條件的警告。在實際的應用程序中,您可以在電子郵件警報系統中點擊警告,以便隨時瞭解您的無人值守軟件何時出現問題。

or + die成語在做文件操作時是非常好的做法。但是,如果包含$ OS_ERROR(a.k.a. $!!),即使是打印,這些死亡也會更多。通過這種方式,您將知道拒絕的權限,不存在的或磁盤已滿的差異等。

這些建議涉及編寫可維護和有彈性的程序問題。但我個人認爲,代碼的美學也有助於可維護性。有意義的命名約定和代碼格式可以在您從現在起的一兩年內打開此程序進行改進或修復錯誤時產生重大影響。我更喜歡創建缺乏不必要混亂的代碼,例如說明明顯的註釋或使用註釋來移除代碼塊。

保持良好的工作。世界需要更多的軟件自動化。

#!/usr/bin/perl 

use strict; 
use warnings; 
use DBI; 

# 
# _voting.pl 
# 
my $logfile = '/var/www/voting/votes.txt'; 

my $errors = 0; 

my %campaign_id_for = (
    'ssss_uk_01b' => 1, 
    'ssss_uk_01c' => 2, 
    'ssss_uk_01d' => 3, 
    'ssss_uk_01e' => 4, 
    'ssss_uk_01f' => 5, 
    'ssss_uk_01g' => 6, 
); 

my %candidate_id_for = (
    'brown' => 1, 
    'cameron' => 2, 
    'balls' => 3, 
    'green' => 4, 
    'boring' => 5, 
    'tupele' => 6, 
); 

my $dbh = DBI->connect( 
    'DBI:mysql:database=sms_voting;host=localhost', 
    'sisisi', 
    '*********', 
    { 'RaiseError' => 1 } 
); 

my $sth = $dbh->prepare(q{ 
    INSERT INTO voting (
     epoch, 
     validity, 
     choice, 
     campaigns_id, 
     candidates_id 
    ) VALUES (
     ?, 
     ?, 
     ?, 
     ?, 
     ? 
    ) 
}); 

my $fh; 

open $fh, '<', $logfile 
    or die "open $logfile: $!"; 

LINE: 
for my $line (<$fh>) { 

    my ($vote, $epoch, $campaign, $validity, $choice, 
     $CONN, $MSISDN, $GUID,  $Shortcode 
    ) = split /\s+/, $line; 

    ($campaign) = reverse split /:/, $campaign; 
    ($validity) = reverse split /:/, $validity; 
    ($choice) = reverse split /:/, $choice; 

    my $campaign_id = $campaign_id_for{ lc $campaign }; 
    my $candidate_id = $candidate_id_for{ lc $choice }; 

    if ($epoch && $validity && $choice && $campaign_id && $candidate_id) { 

     $sth->execute(
      $epoch, 
      $validity, 
      $choice, 
      $campaign_id, 
      $candidate_id 
     ); 

     print "$epoch $validity $choice\n" 
      or die "print: $!"; 

     next LINE; 
    } 
    else { 

     warn "failed to parse: $line\n"; 
     $errors++; 
    } 
} 

close $fh 
    or die "close $logfile: $!"; 

# debug 
print "error count: $errors\n" 
    or die "print: $!"; 
+1

事實上,並且引用:'凡被賦予智慧的人都被賦予了許多善。 – cookie

相關問題