2017-11-03 4 views
1

Perlを使用してデータベースに読み書きするための非常に単純な構文を実装しようとしています。基本的に最終的な目標は、単純なPerlハッシュのようにデータベース内のフィールドにアクセスできるようにすることです。データベースへの読み書きのためのハッシュアクセスのオーバーロード

は、残念ながら、ちょうどデータベース名が十分であると仮定し、私がアクセスしようとしているデータベースの種類とそのAPIは独自のものので、私は実際にデータを読み書きする方法について多くの詳細に入ることはできません接続する情報。この作業を行うためにPerlで行う必要があるのはかなり汎用的なので、API情報は関係してはいけません。

私は、単純なデータベースオブジェクトを作成しています起動するには:

my $database = Database->new('NAME'); 

その後、私は私が読みたいフィールド名を指定してデータベースから読みたい:

# Read from the database 
my $value = $database{'field_name'}; 

# Write to the database 
$database{'field_name'} = $value; 

データがハッシュから読み取られるたびに、データベースにクエリを実行して値を取得する関数を呼び出す必要があります。

データがハッシュに書き込まれるたびに、データをデータベースに書き込む関数を呼び出す必要があります。


これは私がこれまで持っているものです。

Database.pm

package Database; 

use overload '%{}' => \&access_data; 

sub new { 
    my $class = shift; 
    my $name = shift; 

    my $self = bless { 
     name => $name 
    }, $class; 

    return $self; 
} 

sub access_data { 
    my $self = shift; 
    my $field = shift; 
    my $data = shift; 

    if (defined $data) { 
     # Write data to the database using the database API 
    } 
    else { 
     # Read data from the database using the database API 
    } 

    # Not sure what to return to make this work 
} 

test.pl

use Database; 

my $database = Database->new('TESTDB'); 

# Overloaded to read the actual value from the database 
print $database{'field_name'}; 

私はドキュメントを検索されていますoverloading hash accessしかし、私はそれがどのように機能するかを正確に理解するのに苦労しています。

このようなオーバーロードを、私が望むように動作させるにはどうすればよいですか?

+0

デザインでは、通常のSQLデータベースの構成方法は考慮されていません。単一のデータベースには複数の*表*があり、それぞれに複数の*列*と複数の*行*がある場合があります。テーブルを選択する方法や、指定された列の複数の行を返す方法は提供されていません。 – Borodin

+0

これはSQLデータベースではありません。データベースから値を取得するために必要なすべての情報は、フィールド名とサブスクリプトです。私は物事を簡素化するためにこの質問のために添え字部分を残しました。最終目標は '$ val = $ db {'field_name'} [1]'のような構文を持つことです。ここで '1'は目的のレコードの添え字です。 – tjwrona1992

答えて

5

オーバーロードを見たくない場合は、連結変数を調べる必要があります。束縛された変数を使うと標準のPerl変数の振る舞いを変えることができるので、変数にアクセスすることで標準変数ではできないことができます。

答えで説明するのは少し難しいですが、perltieのドキュメントはかなり明確です。

基本的には、独自のパッケージ(Tie :: Hash :: Databaseと呼ばれる)を定義します。変更する操作に対して、TIEHASH()メソッド(コンストラクターに相当)とメソッド(FETCH()など)を定義する必要があります。擬似コード(私はあなたのデータベースがどのように動作するかわからないので)では、このようなビットに見えるかもしれません:

package Tie::Hash::Database; 

use strict; 
use warnings; 

use Database; 

sub TIEHASH { 
    my $class = shift; 
    my ($db_name) = @_; 

    my $self = { 
    db => Database->new($db_name); 
    }; 

    return bless $self, $class; 
} 

# Store value in the hash 
sub STORE { 
    my $self = shift; 
    my ($key, $val) = @_; 

    # code to store the key/value pair in the database; 
    $self->{db}->store($key, $value); 
} 

# Get value from hash 
sub FETCH { 
    my $self = shift; 
    my ($key) = @_; 

    # code to get value from the database 
    return $self->{db}->get($key); 
} 

# ... etc ... 

をそして、あなたはこのようにそれを使用したい:

use Tie::Hash::Database; 

my %db_hash; 
tie %db_hash, 'Tie::Hash::Database', 'name_of_database'; 

$db_hash{some_key} = 'some value'; 

print $db_hash{some_key}; 

何年も前に私はarticle that explains all of thisを書きました。それが役に立つかもしれません。

アップデート:標準のPerlディストリビューションには、tied hash support for various DBM files(効果的には永続ハッシュの格納用のバイナリファイル)が付属していることも指摘する価値があります。

関連する問題