DBD-Sys
view release on metacpan or search on metacpan
lib/DBD/Sys/CompositeTable.pm view on Meta::CPAN
package DBD::Sys::CompositeTable;
use strict;
use warnings;
use vars qw(@ISA $VERSION);
require SQL::Eval;
require DBI::DBD::SqlEngine;
use Scalar::Util qw(blessed weaken);
use Clone qw(clone);
use Carp qw(croak);
@ISA = qw(DBD::Sys::Table);
$VERSION = "0.102";
=pod
=head1 NAME
DBD::Sys::CompositeTable - Table implementation to compose different sources into one table
=head1 ISA
DBD::Sys::CompositeTable
ISA DBD::Sys::Table
ISA DBI::DBD::SqlEngine::Table
=head1 DESCRIPTION
DBD::Sys::CompositeTable provides a table which composes the data from
several sources in one data table.
While constructing this table, the columns of the embedded tables are
collected and a heading and a merge plan for the composed result table
is generated.
Simplified example of table procs:
$alltables = $dbh->selectall_hashref("select * from procs", "pid");
# calls
# DBD::Sys::CompositeTable( [ 'DBD::Sys::Plugin::Any::Procs',
# 'DBD::Sys::Plugin::Win32::Procs' ],
# $attr );
This will fetch the column names from both embedded tables and get (simplfied):
# %colNames = (
# 'DBD::Sys::Plugin::Any::Procs' => [
# 'pid', 'ppid', 'uid', 'gid', 'cmndline', 'sess', 'priority', 'ttynum', 'start', 'run', 'status',
# ],
# 'DBD::Sys::Plugin::Win32::Procs' => [
# 'pid', 'ppid', 'uid', 'gid', 'cmndline', 'sess', 'priority', 'thread', 'start', 'run', 'status',
# ]
# );
# @colNames = (
# 'pid', 'ppid', 'uid', 'gid', 'cmndline', 'sess', 'priority', 'ttynum', 'start', 'run', 'status', 'threads',
# );
# %mergeCols = (
# 'DBD::Sys::Plugin::Any::Procs' => [
# 0 .. 10,
# ],
# 'DBD::Sys::Plugin::Win32::Procs' => [
# 7,
# ]
# );
# $primaryKey = 'pid';
The merge phase in C<collect_data()> finally does (let's assume running
in a cygwin environment, where Proc::ProcessTable and Win32::Process::Info
both are working):
+-----+------+-----+-----+----------+------+----------+---------+-------+-----+---------+
| pid | ppid | uid | gid | cmndline | sess | priority | ttynum | start | run | status |
+-----+------+-----+-----+----------+------+----------+---------+-------+-----+---------+
| 0 | 0 | 0 | 0 | 'init' | 0 | 4 | <undef> | 0 | 999 | 'ioblk' |
| 100 | 0 | 200 | 20 | 'bash' | 1 | 8 | pty/1 | 10000 | 200 | 'wait' |
+-----+------+-----+-----+----------+------+----------+---------+-------+-----+---------+
+-----+------+-----+-----+----------+------+----------+-------+-----+---------+---------+
| pid | ppid | uid | gid | cmndline | sess | priority | start | run | status | threads |
+-----+------+-----+-----+----------+------+----------+-------+-----+---------+---------+
| 782 | 241 | 501 | 501 | 'cygwin' | 0 | 4 | 0 | 999 | 'ioblk' | 2 |
| 100 | 0 | 501 | 501 | 'bash' | 1 | 8 | 10000 | 200 | 'wait' | 8 |
+-----+------+-----+-----+----------+------+----------+-------+-----+---------+---------+
The resulting table would be:
+-----+------+-----+-----+----------+------+----------+---------+-------+-----+---------+---------+
| pid | ppid | uid | gid | cmndline | sess | priority | ttynum | start | run | status | threads |
+-----+------+-----+-----+----------+------+----------+---------+-------+-----+---------+---------+
| 0 | 0 | 0 | 0 | 'init' | 0 | 4 | <undef> | 0 | 999 | 'ioblk' | <undef> |
| 100 | 0 | 200 | 20 | 'bash' | 1 | 8 | pty/1 | 10000 | 200 | 'wait' | 8 |
| 782 | 241 | 501 | 501 | 'cygwin' | 0 | 4 | <undef> | 0 | 999 | 'ioblk' | 8 |
+-----+------+-----+-----+----------+------+----------+---------+-------+-----+---------+---------+
In the real world, it's a bit more complicated and especially the process
table is a bit larger, but it illustrates the most important points:
=over 4
=item *
missing columns are attached right
=item *
missing rows are appended at the end of the first table (and are
constructed as good as possible from the data we have)
=item *
once existing data are neither verified nor overwritten (see the difference
in the cygwin uid (root => uid 0) and win32 uid (Administrator => uid 501).
=back
This is a fictive example - it's not verified how DBD::Sys behaves in
I<cygwin>! Maybe the user mapping works fine - maybe there will be no
problem at all. Maybe you will get duplicated lines for each process
with completely different data.
This is an experimental feature. Use with caution!
=head1 METHODS
=head2 new
sub new( $proto, $tableInfo, $attrs ) { ... }
Creates a new composite table based on the tables in C<$tableInfo>,
analyses the result view and create a merge plan for extending rows and
appending rows.
The order of the embedded tables is primarily influenced by the priority
of the table and secondarily by the alphabetic order of their package
names.
In L</DESCRIPTION|above> example, C<DBD::Sys::Plugin::Any::Procs> has
a priority of 100 and C<DBD::Sys::Plugin::Win32::Procs> has a priority
of 500. So C<D::S::P::Any::Procs> dominates.
=cut
my %compositedInfo;
sub _pk_cmp_fail
{
my ( $pk, $epk ) = @_;
ref($pk) eq ref($epk)
( run in 1.694 second using v1.01-cache-2.11-cpan-5735350b133 )