⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbm.pm

📁 网页留言本,比一般的留言簿管用
💻 PM
📖 第 1 页 / 共 2 页
字号:
        if ($terms) {            unless ($args->{'sort'}) {                my $rec = ${ $driver->{serializer}->unserialize($val) };                my $matched = 1;                for my $col (keys %$terms) {                    $matched = 0, last                        unless defined($rec->{$col}) &&                            $terms->{$col} eq $rec->{$col};                }                push(@matched_ids, $join_col ? $rec->{$join_col} : $key)                    if $matched;            } else {                for my $id (@these_ids) {                    my $rec = $db->{$id} or next;                    $rec = ${ $driver->{serializer}->unserialize($rec) };                    my $matched = 1;                    for my $col (keys %$terms) {                        $matched = 0, last                            unless defined($rec->{$col}) &&                                $terms->{$col} eq $rec->{$col};                    }                    push(@matched_ids, $join_col ? $rec->{$join_col} : $id)                        if $matched;                }            }        }        ## Otherwise we can just add these records to the list of        ## matches.        else {            for my $id (@these_ids) {                ## We could let the conditional below handle this, but                ## it is faster if we handle it here: this way, if we                ## are using $join_col, we don't have to pull out the                ## record and unserialize it.                if ($offset && $j < $offset) {                    $j++;                    next;                }                if ($join_col) {                    my $rec = $db->{$id} or next;                    $rec = ${ $driver->{serializer}->unserialize($rec) };                    push @matched_ids, $rec->{$join_col};                } else {                    push @matched_ids, $id;                }            }        }        ## Now, loop over all of the matching IDs. If an offset is specified,        ## and we have not yet reached that offset, we skip the ID; otherwise        ## we add the ID to the final list.        for my $id (@matched_ids) {            if ($offset && $j < $offset) {                $j++;            } else {                if (!$uniq || !exists $ids{$id}) {                    push @ids, $id;                    $ids{$id}++;                    $i++;                }            }        }    }    if ($args->{'sort'}) {        undef $this_db;        untie %$idx;        $unlock->();    }    @ids;}sub load_iter {    my $driver = shift;    $driver->run_callbacks($_[0] . '::pre_load', \@_);    my($class, $terms, $args) = @_;    my $db_file = _db_data($driver, $class);    my($DB, $db, $unlock) = $driver->_tie_db_file($db_file, $DB_BTREE, 'r')        or return sub { };    my @ids = $driver->_get_ids($DB, $db, $class, $terms, $args);    return $driver->error($driver->errstr())	if (!defined($ids[0])) && ($#ids == 0);    my $idx = 0;    sub {        if ($idx > $#ids) {            undef $DB;            untie %$db;            $unlock->();            return;        }        my $rec = $db->{ $ids[$idx++] } or return;        $rec = $driver->{serializer}->unserialize($rec);        my $obj = $class->new;        $obj->set_values($$rec);	$driver->run_callbacks($class . '::post_load', \@_, $obj);        $obj;    };}sub load {    my $driver = shift;    $driver->run_callbacks($_[0] . '::pre_load', \@_);    my($class, $terms, $args) = @_;    my $_terms;    if (ref $terms && $terms->{id}) {	$_terms = $terms;	$terms = $terms->{id};    }    my $db_file = _db_data($driver, $class);    my($DB, $db, $unlock) = $driver->_tie_db_file($db_file, $DB_BTREE, 'r')        or return;    my @ids = $driver->_get_ids($DB, $db, $class, $terms, $args);    my @objs;  OBJECT:    for my $id (@ids) {        my $rec = $db->{$id} or return;        $rec = $driver->{serializer}->unserialize($rec);        my $obj = $class->new;        $obj->set_values($$rec);	foreach (keys %$_terms) {	    next OBJECT if ($_terms->{$_} ne $obj->column($_));	}	$driver->run_callbacks($class . '::post_load', \@_, $obj);        $unlock->(), return($obj) unless wantarray;        push @objs, $obj;    }    undef $DB;    untie %$db;    $unlock->();    @objs;}sub count {    my $driver = shift;    my($class, $terms, $args) = @_;    my $db_file = _db_data($driver, $class);    my($DB, $db, $unlock) = $driver->_tie_db_file($db_file, $DB_BTREE, 'r')        or return 0;    my @ids = $driver->_get_ids($DB, $db, $class, $terms, $args);    undef $DB;    untie %$db;    $unlock->();    scalar @ids;}sub count_group_by {    my $driver = shift;    my($class, $terms, $args) = @_;    my $db_file = _db_data($driver, $class);    my($DB, $db, $unlock) = $driver->_tie_db_file($db_file, $DB_BTREE, 'r')        or return 0;    die "count_group_by is unimplemented in DBM";    my @ids = ();        undef $DB;    untie %$db;    $unlock->();}sub exists {    my $driver = shift;    my($obj) = @_;    return unless $obj->id;    my $db_file = _db_data($driver, $obj);    my($DB, $db, $unlock) = $driver->_tie_db_file($db_file, $DB_BTREE, 'r')        or return 0;    my $exists = exists $db->{$obj->id};    undef $DB;    untie %$db;    $unlock->();    $exists;}sub save {    my $driver = shift;    my($obj) = @_;    my $original;    ($original, $obj) = ($obj, $obj->clone());    $driver->run_callbacks((ref$obj) . "::pre_save", $obj, $original);    my $db_file = _db_data($driver, $obj);    my($DB, $db, $unlock) = $driver->_tie_db_file($db_file, $DB_BTREE, 'rw')        or return $driver->error(MT->translate(            "Tie '[_1]' failed: [_2]", $db_file, "$!" ));    unless ($obj->id || ($obj->id($driver->generate_id($obj)))) {        return $driver->error(MT->translate(            "Failed to generate unique ID: [_1]", $driver->errstr ));    }    my $id = $obj->id;    $original->id($id);    if ($obj->properties->{audit}) {        my $blog_id = $obj->blog_id;        my @ts = offset_time_list(time, $blog_id);        my $ts = sprintf "%04d%02d%02d%02d%02d%02d",            $ts[5]+1900, $ts[4]+1, @ts[3,2,1,0];        $obj->created_on($ts)            unless CORE::exists($db->{$id}) || $obj->created_on;        $obj->modified_on($ts);        $original->created_on($obj->created_on);        $original->modified_on($obj->modified_on);    }    ## Grab old values so that we can update indexes on changed columns    my $old = $db->{$id};    $old = ${ $driver->{serializer}->unserialize($old) } if $old;    $db->{$id} = $driver->{serializer}->serialize(\$obj->column_values);    undef $DB;    untie %$db;    $unlock->();    if (!$no_build_indexes) {        $driver->rebuild_index_for_item($obj, $old);    }    $driver->run_callbacks((ref $obj) . "::post_save", $obj, $original);    1;}sub no_build_indexes {    my $class = shift;    if (@_) {        $no_build_indexes = $_[0];    }    $no_build_indexes;}sub rebuild_indexes {    my $driver = shift;    my $class = shift;    my $props = $class->properties;    my $indexes = $props->{indexes};    return unless ($indexes && keys %$indexes);    my %idx;    for my $idx_col (keys %$indexes) {        my $idx_file = File::Spec->catfile($driver->cfg->DataSource,                                           $class->datasource                                           . '.' . $idx_col . '.idx');        tie %{ $idx{$idx_col} }, 'DB_File', $idx_file, O_RDWR|O_CREAT,        0666, $DB_BTREE or die "Tie to '$idx_file' failed: $!";        %{ $idx{$idx_col} } = ();    }    my $iter = $class->load_iter;    while (my $obj = $iter->()) {        my $id = $obj->id;        for my $idx_col (keys %$indexes) {            my $idx = $idx{$idx_col};            my $col_value = $obj->$idx_col() || '';            my @cur = split /$;/, $idx->{$col_value} || '';            my %ids = map { $_ => 1 } @cur;            next if exists $ids{$id};            $idx->{$col_value} = join $;, keys %ids, $id;        }    }    for my $idx_col (keys %$indexes) {        untie %{ $idx{$idx_col} };    }}sub rebuild_index_for_item {    my $driver = shift;    my ($obj, $old) = @_;    my $id = $obj->id;    my $indexes = $obj->properties->{indexes};    for my $col (keys %$indexes) {        my $idx_file = _db_index($driver, $obj, $col);        my($DB, $idx, $unlock) =            $driver->_tie_db_file($idx_file, $DB_BTREE, 'rw')            or return $driver->error(MT->translate(                                     "Tie '[_1]' failed: [_2]", $idx_file, "$!" ));        my $col_value = $obj->$col();        $col_value = '' unless defined $col_value;        my %ids = map { $_ => 1 } split /$;/, $idx->{$col_value} || '';        $unlock->(), next if exists $ids{$id};        $idx->{$col_value} = join $;, keys %ids, $id;        $old->{$col} = '' unless !$old || defined $old->{$col};        if ($old && $old->{$col} ne $col_value) {            _drop_from_index($idx, $id, $old->{$col});        }        undef $DB;        untie %$idx;        $unlock->();    }}sub remove {    my $driver = shift;    my($obj) = @_;    $driver->run_callbacks((ref $obj) . "::pre_remove", @_);    my $id = $obj->id;    return unless $id;    my $indexes = $obj->properties->{indexes};    for my $col (keys %$indexes) {        my $idx_file = _db_index($driver, $obj, $col);        my($DB, $idx, $unlock) =            $driver->_tie_db_file($idx_file, $DB_BTREE, 'rw')            or return $driver->error(MT->translate(                "Tie '[_1]' failed: [_2]", $idx_file, "$!" ));        my $col_value = $obj->$col();        _drop_from_index($idx, $id, $col_value);        undef $DB;        untie %$idx;        $unlock->();    }    my $db_file = _db_data($driver, $obj);    my($DB, $db, $unlock) = $driver->_tie_db_file($db_file, $DB_BTREE, 'rw')        or return $driver->error(MT->translate(            "Tie '[_1]' failed: [_2]", $db_file, "$!" ));    delete $db->{$obj->id};    undef $DB;    untie %$db;    $unlock->();    $driver->run_callbacks((ref $obj) . "::post_remove", @_);    1;}sub remove_all {    my $driver = shift;    my($class) = @_;    $driver->run_callbacks($class . "::pre_remove_all", @_);    my $indexes = $class->properties->{indexes};    for my $col (keys %$indexes) {        my $idx_file = _db_index($driver, $class, $col);        next unless -e $idx_file;        unlink $idx_file or            return $driver->error(MT->translate(                "Unlink of '[_1]' failed: [_2]", $idx_file, "$!" ));    }    my $db_file = _db_data($driver, $class);    if (-e $db_file) {        unlink $db_file or            return $driver->error(MT->translate(                "Unlink of '[_1]' failed: [_2]", $db_file, "$!" ));    }    $driver->run_callbacks($class . "::post_remove_all", @_);    1;}sub _drop_from_index {    my($idx, $obj_id, $col_val) = @_;    $col_val = '' unless defined $col_val;    return unless exists $idx->{$col_val};    my $idx_val = $idx->{$col_val};    $idx_val = '' unless defined $idx_val;    my %ids = map { $_ => 1 } split /$;/, $idx_val;    delete $ids{$obj_id};    if (%ids) {        $idx->{$col_val} = join $;, keys %ids;    } else {        delete $idx->{$col_val};    }}sub generate_id {    my $driver = shift;    my($this) = @_;    my $class = ref($this) || $this;    my $id_file = File::Spec->catfile(        $driver->cfg->DataSource, "ids.db");    my($DB, $db, $unlock) = $driver->_tie_db_file($id_file, $DB_HASH, 'rw')        or return $driver->error(MT->translate(            "Tie '[_1]' failed: [_2]", $id_file, "$!" ));    $db->{$class} = 0 unless exists $db->{$class};    my $id = ++$db->{$class};    undef $DB;    untie %$db;    $unlock->();    $id;}1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -