2016-11-29 5 views
3

jquery/ajax/jsonからDBIx :: Classを使用して実行するperlスクリプトに渡そうとしているクエリがあります。結果を返します。私は基本的なクエリをうまく動作するようにすることができますが、私はスカラー参照を含める必要があるときに問題に走っています。私がここでやっていることのすべてのコンセプトについての私の把握は、少しゆったりとしているので、どんな不正確なことも許してください。 、ここでPerl:ajax/jsonで渡されたDBIx :: Classクエリ情報のスカラー参照を含める方法

var jsonData = $.ajax({ 
    url: 'cgi-bin/getdata.cgi', 
    data: JSON.stringify({ 
    table: 'Processes', 
    search: { 
     query_server:'SERVER1', 
     query_time: { 
     '>=':'now() - INTERVAL 1 DAY' 
     } 
    }, 
    attrib: { 
     select: [ 
     'query_time', 
     {avg:'bytes_processed'} 
     ], 
     order_by: 'query_time', 
     group_by: 'query_time' 
    } 
    }), 
    contentType: "application/json", 
    dataType: 'json', 
    method: 'POST', 
    async: false 
}).responseText; 

は標準を読み込むperlスクリプトの一部であるJSONから変換し、クエリを実行します:ここで

は、私はperlスクリプトに渡すクエリパラメータを定義する場所です

while (<STDIN>) 
{ 
    $json .= $_; 
} 

my $query = from_json($json); 

my $table = $query->{'table'}; 
my $search = $query->{'search'}; 
my $attrib= $query->{'attrib'}; 

print "Table:\n" . Dumper($table) . "\n"; 
print "Search:\n" . Dumper($search) . "\n"; 
print "Attrib:\n" . Dumper($attrib) . "\n"; 

my $retSet = $schema->resultset($table)->search($search, $attrib); 
my $retRow = $retSet->next; 

そして、ここで私は(DBIC_TRACEを有効にして)を取得出力されます:

Table: 
$VAR1 = 'Processes'; 

Search: 
$VAR1 = { 
      'query_time' => { 
          '>=' => 'now() - INTERVAL 1 DAY' 
          }, 
      'query_server' => 'SERVER1' 
     }; 

Attrib: 
$VAR1 = { 
      'order_by' => 'query_time', 
      'group_by' => 'query_time', 
      'select' => [ 
         'query_time', 
         { 
          'avg' => 'bytes_processed' 
         } 
         ] 
     }; 

SELECT me.query_time, AVG(bytes_processed) FROM processes me WHERE ((query_server = ? AND query_time >= ?)) GROUP BY query_time ORDER BY query_time: 'TSMCORP6', 'now() - INTERVAL 1 DAY' 

プロクエリーを正しく実行するには、'now() - INTERVAL 1 DAY'の値をスカラー参照にする必要があります。私はそうのように(代わりに、htmlファイルからから渡す)perlスクリプト内のクエリを構築する場合:

​​ :

my $search = { 
    query_server => 'SERVER1', 
    query_time => { 
    '>=' => \'now() - INTERVAL 1 DAY' 
    } 
}; 

その後、データは次のようになり、私はそれを好きな方法を実行し、検索

私の理解に基づいて、値を参照として渡すことは意味をなさないと思うので、私はperlスクリプトの中でそれを "変換"する方法を理解しようとしています。私はfrom_jsonで処理される前にバックスラッシュを投げてみましたが、うまくいかなかったのです。助けてくれてありがとう!

更新:次のコードで値を参照に変換できました。しかし、私は参照に変換する必要がある値を知っていたので、これはうまくいった。通常の状況下では、値はデータ構造内のどこにでも置くことができます。 !ref!のような値でフラグを立てて、データ構造全体を検索し、見つけたものをそれぞれ変換できますか?どのように見えるだろうか?

my $cond = $query->{'search'}->{'query_time'}->{'>='}; 
$query->{'search'}->{'query_time'}->{'>='}=\$cond; 

答えて

1

問題は、JSONには単なるデータなので参照型に完全にマップするものがないことです。しかし、私はあなたが着信データを前処理し、リテラルSQLをDBICが期待する参照に変換することが正しいと思います。送信側では特別な処理が必要なオブジェクトにliteral_sqlフラグを追加し、filter_json_objectを使用してこれらのキーを見つけ出し、削除してスカラー文字列参照を作成することができます。

use strict; 
use warnings; 

use Data::Dump; 
use JSON; 

my $json = <<'EOF'; 
{ 
    "table": "Processes", 
    "search": { 
     "query_server": "SERVER1", 
     "query_time": { 
      ">=": "now() - INTERVAL 1 DAY", 
      "literal_sql": true 
     } 
    }, 
    "attrib": { 
     "select": [ 
      "query_time", { 
       "avg": "bytes_processed" 
      } 
     ], 
     "order_by": "query_time", 
     "group_by": "query_time" 
    } 
} 
EOF 

my $query = JSON 
    ->new 
    ->filter_json_object (sub { 
     my $obj = shift; 
     return unless $obj->{literal_sql}; 
     delete($obj->{literal_sql}); 

     my ($key, $val) = each(%$obj); 
     $obj->{$key} = \"$val"; 
     return $obj; 
    }) 
    ->decode($json); 

dd($query); 

出力:

{ 
    attrib => { 
       group_by => "query_time", 
       order_by => "query_time", 
       select => ["query_time", { avg => "bytes_processed" }], 
      }, 
    search => { 
       query_server => "SERVER1", 
       query_time => { ">=" => \"now() - INTERVAL 1 DAY" }, 
      }, 
    table => "Processes", 
} 
+0

ナイス!私はデータ構造をたどり、タグを検索する方法を探していました。私はJSONモジュールがこのフィルタ機能を持っていることに気づいていませんでした。それは素晴らしい作品です。ありがとうございました。 – pvarney

関連する問題