TT#87561 openser/ngcp mr1.0.2 dao db schema

Change-Id: I37a174b71c80bc24d9246eafc20a12e18256d736
mr9.0
Rene Krenn 5 years ago
parent 6ae1d17b67
commit 5010a23968

@ -25,6 +25,7 @@ our @EXPORT_OK = qw(
gettablename gettablename
check_table check_table
findby_resellerid
findby_resellerid_level findby_resellerid_level
findby_resellername_level findby_resellername_level
@ -78,6 +79,23 @@ sub findby_resellerid_level {
} }
sub findby_resellerid {
my ($reseller_id,$load_recursive) = @_;
check_table();
my $db = &$get_db();
my $table = $db->tableidentifier($tablename);
my $stmt = 'SELECT * FROM ' . $table . ' WHERE ' .
$db->columnidentifier('reseller_id') . ' = ?';
my @params = ($reseller_id);
my $rows = $db->db_get_all_arrayref($stmt,@params);
return buildrecords_fromrows($rows,$load_recursive);
}
sub findby_resellername_level { sub findby_resellername_level {
my ($reseller_name,$level,$load_recursive) = @_; my ($reseller_name,$level,$load_recursive) = @_;

@ -69,6 +69,8 @@ our @EXPORT_OK = qw(
$CONTRACT_SOUND_SET_ATTRIBUTE $CONTRACT_SOUND_SET_ATTRIBUTE
$HEADER_RULE_SET_ATTRIBUTE $HEADER_RULE_SET_ATTRIBUTE
$EMERGENCY_PREFIX_ATTRIBUTE
$BOOLEAN_DATA_TYPE $BOOLEAN_DATA_TYPE
); );
#$FORCE_OUTBOUND_CALLS_TO_PEER #$FORCE_OUTBOUND_CALLS_TO_PEER
@ -146,6 +148,8 @@ our $SOUND_SET_ATTRIBUTE = 'sound_set';
our $CONTRACT_SOUND_SET_ATTRIBUTE = 'contract_sound_set'; our $CONTRACT_SOUND_SET_ATTRIBUTE = 'contract_sound_set';
our $HEADER_RULE_SET_ATTRIBUTE = 'header_rule_set'; our $HEADER_RULE_SET_ATTRIBUTE = 'header_rule_set';
our $EMERGENCY_PREFIX_ATTRIBUTE = 'emergency_prefix';
our $BOOLEAN_DATA_TYPE = 'boolean'; our $BOOLEAN_DATA_TYPE = 'boolean';
sub new { sub new {

@ -0,0 +1,248 @@
package NGCP::BulkProcessor::Dao::mr102::billing::contracts;
use strict;
use threads::shared;
## no critic
use NGCP::BulkProcessor::Logging qw(
getlogger
rowinserted
);
use NGCP::BulkProcessor::ConnectorPool qw(
get_billing_db
destroy_dbs
);
use NGCP::BulkProcessor::SqlProcessor qw(
checktableinfo
insert_record
copy_row
process_table
);
use NGCP::BulkProcessor::SqlRecord qw();
use NGCP::BulkProcessor::Dao::mr102::billing::voip_subscribers qw();
require Exporter;
our @ISA = qw(Exporter NGCP::BulkProcessor::SqlRecord);
our @EXPORT_OK = qw(
gettablename
check_table
insert_row
source_process_records
source_findby_id
$ACTIVE_STATE
$TERMINATED_STATE
);
my $tablename = 'contracts';
my $get_db = \&get_billing_db;
my $expected_fieldnames = [
'id',
'customer_id',
'reseller_id',
'contact_id',
'order_id',
'status',
'modify_timestamp',
'create_timestamp',
'activate_timestamp',
'terminate_timestamp',
];
my $indexes = {};
my $insert_unique_fields = [];
our $ACTIVE_STATE = 'active';
our $TERMINATED_STATE = 'terminated';
sub new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new($class,$get_db,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub buildrecords_fromrows {
my ($rows,$load_recursive) = @_;
my @records = ();
my $record;
if (defined $rows and ref $rows eq 'ARRAY') {
foreach my $row (@$rows) {
$record = __PACKAGE__->new($row);
# transformations go here ...
push @records,$record;
}
}
return \@records;
}
sub gettablename {
return $tablename;
}
sub check_table {
return checktableinfo(shift // $get_db,
__PACKAGE__,$tablename,
$expected_fieldnames,
$indexes);
}
sub source_new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new_shared($class,shift,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub source_process_records {
my %params = @_;
my ($source_dbs,
$process_code,
$read_code,
$static_context,
$init_process_context_code,
$uninit_process_context_code,
$destroy_reader_dbs_code,
$multithreading,
$blocksize,
$numofthreads,
$load_recursive) = @params{qw/
source_dbs
process_code
read_code
static_context
init_process_context_code
uninit_process_context_code
destroy_reader_dbs_code
multithreading
blocksize
numofthreads
load_recursive
/};
my $source_db = $source_dbs->{billing_db};
check_table($source_db);
my $db = &$source_db();
my $table = $db->tableidentifier($tablename);
return process_table(
get_db => $source_db,
class => __PACKAGE__,
process_code => sub {
my ($context,$rowblock,$row_offset) = @_;
#return &$process_code($context,buildrecords_fromrows_source($rowblock,$source_db,$load_recursive),$row_offset);
return $process_code->($context,$rowblock,$row_offset);
},
read_code => sub {
my ($rowblock) = @_;
map { &$_()->ping(); } values %$source_dbs; #keep awake.
return source_buildrecords_fromrows($rowblock,$source_dbs,$load_recursive);
},
static_context => $static_context,
blocksize => $blocksize,
init_process_context_code => $init_process_context_code,
uninit_process_context_code => $uninit_process_context_code,
destroy_reader_dbs_code => $destroy_reader_dbs_code,
multithreading => $multithreading,
tableprocessing_threads => $numofthreads,
'select' => 'SELECT c.*,r.name as reseller_name FROM ' . $table . ' c left join billing.resellers r on c.reseller_id = r.id', # and id = 7185',
'selectcount' => 'SELECT COUNT(c.id) FROM ' . $table . ' c', # and id = 7185',
#'select' => 'SELECT c.*,r.name as reseller_name FROM ' . $table . ' c left join billing.resellers r on c.reseller_id = r.id WHERE c.status != "' . $TERMINATED_STATE . '"', # and id = 7185',
#'selectcount' => 'SELECT COUNT(c.id) FROM ' . $table . ' c WHERE c.status != "' . $TERMINATED_STATE . '"', # and id = 7185',
);
}
sub source_findby_id {
my ($source_dbs,$id,$load_recursive) = @_;
my $source_db = $source_dbs->{billing_db};
check_table($source_db);
my $db = &$source_db();
my $table = $db->tableidentifier($tablename);
my $stmt = 'SELECT c.*,r.name as reseller_name FROM ' . $table . ' c join billing.resellers r on c.reseller_id = r.id WHERE ' .
'c.id = ?';
my @params = ($id);
my $rows = $db->db_get_all_arrayref($stmt,@params);
return source_buildrecords_fromrows($rows,$source_dbs,$load_recursive)->[0];
}
sub source_buildrecords_fromrows {
my ($rows,$source_dbs,$load_recursive) = @_;
my @records : shared = ();
my $record;
if (defined $rows and ref $rows eq 'ARRAY') {
foreach my $row (@$rows) {
$record = __PACKAGE__->source_new($source_dbs->{billing_db},$row);
if ('ARRAY' eq ref $row) {
$record->{reseller_name} = pop @$row;
} else {
$record->{reseller_name} = $row->{reseller_name};
}
#$record->{billing_mappings} = NGCP::BulkProcessor::Dao::mr102::billing::billing_mappings::source_findby_contractid($source_dbs,$record->{id});
#$record->{contact} = NGCP::BulkProcessor::Dao::mr102::billing::contacts::source_findby_id($source_dbs,$record->{contact_id});
#$record->{contract_balances} = NGCP::BulkProcessor::Dao::mr102::billing::contract_balances::source_findby_contractid($source_dbs,$record->{id});
#if ($record->{reseller_id}) {
if ($load_recursive
and (('CODE' eq ref $load_recursive->{'contracts.voip_subscribers'} and $load_recursive->{'contracts.voip_subscribers'}->($record))
or (not ref $load_recursive->{'contracts.voip_subscribers'} and $load_recursive->{'contracts.voip_subscribers'}))) {
$record->{voip_subscribers} = NGCP::BulkProcessor::Dao::mr102::billing::voip_subscribers::source_findby_contractid($source_dbs,$record->{id},$load_recursive);
}
#}
#delete $record->{reseller_id};
#
#delete $record->{contact_id};
#delete $record->{customer_id};
#delete $record->{order_id};
#delete $record->{id};
push @records,$record;
}
}
return \@records;
}
1;

@ -0,0 +1,119 @@
package NGCP::BulkProcessor::Dao::mr102::billing::domain_resellers;
use strict;
## no critic
use NGCP::BulkProcessor::ConnectorPool qw(
get_billing_db
);
use NGCP::BulkProcessor::SqlProcessor qw(
checktableinfo
copy_row
);
use NGCP::BulkProcessor::SqlRecord qw();
use NGCP::BulkProcessor::Dao::mr102::billing::domains qw();
require Exporter;
our @ISA = qw(Exporter NGCP::BulkProcessor::SqlRecord);
our @EXPORT_OK = qw(
gettablename
check_table
source_findby_resellerid
);
my $tablename = 'domain_resellers';
my $get_db = \&get_billing_db;
my $expected_fieldnames = [
'id',
'domain_id',
'reseller_id',
];
my $indexes = {};
sub new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new($class,$get_db,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub gettablename {
return $tablename;
}
sub check_table {
return checktableinfo(shift // $get_db,
__PACKAGE__,$tablename,
$expected_fieldnames,
$indexes);
}
sub source_new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new($class,shift,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub source_findby_resellerid {
my ($source_dbs,$id) = @_;
my $source_db = $source_dbs->{billing_db};
check_table($source_db);
my $db = &$source_db();
my $table = $db->tableidentifier($tablename);
my $stmt = 'SELECT * FROM ' . $table . ' WHERE ' .
$db->columnidentifier('reseller_id') . ' = ?';
my @params = ($id);
my $rows = $db->db_get_all_arrayref($stmt,@params);
return source_buildrecords_fromrows($rows,$source_dbs);
}
sub source_buildrecords_fromrows {
my ($rows,$source_dbs) = @_;
my @records = (); # : shared = ();
my $record;
if (defined $rows and ref $rows eq 'ARRAY') {
foreach my $row (@$rows) {
$record = __PACKAGE__->source_new($source_dbs->{billing_db},$row);
$record->{domain} = NGCP::BulkProcessor::Dao::mr102::billing::domains::source_findby_id($source_dbs,$record->{domain_id});
push @records,$record;
}
}
return \@records;
}
1;

@ -0,0 +1,116 @@
package NGCP::BulkProcessor::Dao::mr102::billing::domains;
use strict;
## no critic
use NGCP::BulkProcessor::ConnectorPool qw(
get_billing_db
);
use NGCP::BulkProcessor::SqlProcessor qw(
checktableinfo
copy_row
);
use NGCP::BulkProcessor::SqlRecord qw();
require Exporter;
our @ISA = qw(Exporter NGCP::BulkProcessor::SqlRecord);
our @EXPORT_OK = qw(
gettablename
check_table
);
my $tablename = 'domains';
my $get_db = \&get_billing_db;
my $expected_fieldnames = [
'id',
'domain',
];
my $indexes = {};
sub new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new($class,$get_db,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub gettablename {
return $tablename;
}
sub check_table {
return checktableinfo(shift // $get_db,
__PACKAGE__,$tablename,
$expected_fieldnames,
$indexes);
}
sub source_new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new($class,shift,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub source_findby_id {
my ($source_dbs,$id) = @_;
my $source_db = $source_dbs->{billing_db};
check_table($source_db);
my $db = &$source_db();
my $table = $db->tableidentifier($tablename);
my $stmt = 'SELECT * FROM ' . $table . ' WHERE ' .
$db->columnidentifier('id') . ' = ?';
my @params = ($id);
my $rows = $db->db_get_all_arrayref($stmt,@params);
return source_buildrecords_fromrows($rows,$source_dbs)->[0];
}
sub source_buildrecords_fromrows {
my ($rows,$source_dbs) = @_;
my @records = (); # : shared = ();
my $record;
if (defined $rows and ref $rows eq 'ARRAY') {
foreach my $row (@$rows) {
$record = __PACKAGE__->source_new($source_dbs->{billing_db},$row);
#$record->{voip_dom_preferences} = NGCP::BulkProcessor::Dao::mr102::provisioning::voip_dom_preferences::source_findby_domain($source_dbs,$record->{domain});
push @records,$record;
}
}
return \@records;
}
1;

@ -0,0 +1,130 @@
package NGCP::BulkProcessor::Dao::mr102::billing::resellers;
use strict;
## no critic
use NGCP::BulkProcessor::ConnectorPool qw(
get_billing_db
);
use NGCP::BulkProcessor::SqlProcessor qw(
checktableinfo
copy_row
);
use NGCP::BulkProcessor::SqlRecord qw();
#use NGCP::BulkProcessor::Dao::mr102::billing::contracts qw();
use NGCP::BulkProcessor::Dao::mr102::billing::domain_resellers qw();
require Exporter;
our @ISA = qw(Exporter NGCP::BulkProcessor::SqlRecord);
our @EXPORT_OK = qw(
gettablename
check_table
source_findall
$TERMINATED_STATE
);
my $tablename = 'resellers';
my $get_db = \&get_billing_db;
my $expected_fieldnames = [
'id',
'contract_id',
'name',
'status',
];
my $indexes = {};
our $TERMINATED_STATE = 'terminated';
sub new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new($class,$get_db,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub gettablename {
return $tablename;
}
sub check_table {
return checktableinfo(shift // $get_db,
__PACKAGE__,$tablename,
$expected_fieldnames,
$indexes);
}
sub source_new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new($class,shift,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub source_findall {
my ($source_dbs) = @_;
my $source_db = $source_dbs->{billing_db};
check_table($source_db);
my $db = &$source_db();
my $table = $db->tableidentifier($tablename);
my $stmt = 'SELECT * FROM ' . $table;
my $rows = $db->db_get_all_arrayref($stmt);
return source_buildrecords_fromrows($rows,$source_dbs);
}
sub source_buildrecords_fromrows {
my ($rows,$source_dbs) = @_;
my @records = (); # : shared = ();
my $record;
if (defined $rows and ref $rows eq 'ARRAY') {
foreach my $row (@$rows) {
$record = __PACKAGE__->source_new($source_dbs->{billing_db},$row);
# transformations go here ...
#$record->{contract} = NGCP::BulkProcessor::Dao::mr102::billing::contracts::source_findby_id($source_dbs,$record->{contract_id});
my @domains = ();
foreach my $domain_reseller (@{NGCP::BulkProcessor::Dao::mr102::billing::domain_resellers::source_findby_resellerid($source_dbs,$record->{id})}) {
push(@domains,$domain_reseller->{domain});
}
$record->{domains} = \@domains;
#$record->{ncos_levels} = NGCP::BulkProcessor::Dao::mr102::billing::ncos_levels::source_findby_resellerid($source_dbs,$record->{id});
push @records,$record;
}
}
return \@records;
}
1;

@ -0,0 +1,177 @@
package NGCP::BulkProcessor::Dao::mr102::billing::voip_numbers;
use strict;
## no critic
use threads::shared;
use NGCP::BulkProcessor::Logging qw(
getlogger
);
use NGCP::BulkProcessor::ConnectorPool qw(
get_billing_db
);
use NGCP::BulkProcessor::SqlProcessor qw(
checktableinfo
copy_row
);
use NGCP::BulkProcessor::SqlRecord qw();
require Exporter;
our @ISA = qw(Exporter NGCP::BulkProcessor::SqlRecord);
our @EXPORT_OK = qw(
gettablename
check_table
source_findby_subscriberid
source_findby_id
);
my $tablename = 'voip_numbers';
my $get_db = \&get_billing_db;
my $expected_fieldnames = [
'id',
'cc',
'ac',
'sn',
'reseller_id',
'subscriber_id',
'status',
'ported',
'list_timestamp',
];
my $indexes = {};
our $ACTIVE_STATE = 'active';
sub new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new($class,$get_db,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub buildrecords_fromrows {
my ($rows,$load_recursive) = @_;
my @records = ();
my $record;
if (defined $rows and ref $rows eq 'ARRAY') {
foreach my $row (@$rows) {
$record = __PACKAGE__->new($row);
# transformations go here ...
push @records,$record;
}
}
return \@records;
}
sub gettablename {
return $tablename;
}
sub check_table {
return checktableinfo(shift // $get_db,
__PACKAGE__,$tablename,
$expected_fieldnames,
$indexes);
}
sub source_new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new_shared($class,shift,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub source_findby_subscriberid {
my ($source_dbs,$subscriber_id) = @_;
my $source_db = $source_dbs->{billing_db};
check_table($source_db);
my $db = &$source_db();
my $table = $db->tableidentifier($tablename);
my $stmt = 'SELECT vn.*,r.name as reseller_name FROM ' . $table . ' vn left join billing.resellers r on vn.reseller_id = r.id WHERE ' .
'vn.subscriber_id = ?';
my @params = ($subscriber_id);
my $rows = $db->db_get_all_arrayref($stmt,@params);
return source_buildrecords_fromrows($rows,$source_dbs);
}
sub source_findby_id {
my ($source_dbs,$id) = @_;
my $source_db = $source_dbs->{billing_db};
check_table($source_db);
my $db = &$source_db();
my $table = $db->tableidentifier($tablename);
my $stmt = 'SELECT vn.*,r.name as reseller_name FROM ' . $table . ' vn left join billing.resellers r on vn.reseller_id = r.id WHERE ' .
'vn.id = ?';
my @params = ($id);
my $rows = $db->db_get_all_arrayref($stmt,@params);
return source_buildrecords_fromrows($rows,$source_dbs)->[0];
}
sub source_buildrecords_fromrows {
my ($rows,$source_dbs) = @_;
my @records : shared = ();
my $record;
if (defined $rows and ref $rows eq 'ARRAY') {
foreach my $row (@$rows) {
$record = __PACKAGE__->source_new($source_dbs->{billing_db},$row);
# transformations go here ...
$record->{reseller_name} = $row->{reseller_name};
#delete $record->{id};
#delete $record->{reseller_id};
#delete $record->{subscriber_id};
push @records,$record;
}
}
return \@records;
}
1;

@ -0,0 +1,169 @@
package NGCP::BulkProcessor::Dao::mr102::billing::voip_subscribers;
use strict;
## no critic
use threads::shared;
use NGCP::BulkProcessor::Logging qw(
getlogger
);
use NGCP::BulkProcessor::ConnectorPool qw(
get_billing_db
);
use NGCP::BulkProcessor::SqlProcessor qw(
checktableinfo
copy_row
);
use NGCP::BulkProcessor::SqlRecord qw();
use NGCP::BulkProcessor::Dao::mr102::provisioning::voip_subscribers qw();
use NGCP::BulkProcessor::Dao::mr102::billing::voip_numbers qw();
use NGCP::BulkProcessor::Dao::mr102::billing::domains qw();
require Exporter;
our @ISA = qw(Exporter NGCP::BulkProcessor::SqlRecord);
our @EXPORT_OK = qw(
gettablename
check_table
source_findby_contractid
);
my $tablename = 'voip_subscribers';
my $get_db = \&get_billing_db;
my $expected_fieldnames = [
'id',
'contract_id',
'uuid',
'username',
'domain_id',
'status',
#'primary_number_id',
];
my $indexes = {};
my $insert_unique_fields = [];
our $TERMINATED_STATE = 'terminated';
our $ACTIVE_STATE = 'active';
sub new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new($class,$get_db,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub buildrecords_fromrows {
my ($rows,$load_recursive) = @_;
my @records = ();
my $record;
if (defined $rows and ref $rows eq 'ARRAY') {
foreach my $row (@$rows) {
$record = __PACKAGE__->new($row);
# transformations go here ...
push @records,$record;
}
}
return \@records;
}
sub gettablename {
return $tablename;
}
sub check_table {
return checktableinfo(shift // $get_db,
__PACKAGE__,$tablename,
$expected_fieldnames,
$indexes);
}
sub source_new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new_shared($class,shift,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub source_findby_contractid {
my ($source_dbs,$contract_id,$load_recursive) = @_;
my $source_db = $source_dbs->{billing_db};
check_table($source_db);
my $db = &$source_db();
my $table = $db->tableidentifier($tablename);
my $stmt = 'SELECT s.*,d.domain as domain FROM ' . $table . ' s JOIN billing.domains d ON s.domain_id = d.id WHERE ' .
$db->columnidentifier('contract_id') . ' = ?';
my @params = ($contract_id);
my $rows = $db->db_get_all_arrayref($stmt,@params);
return source_buildrecords_fromrows($rows,$source_dbs,$load_recursive);
}
sub source_buildrecords_fromrows {
my ($rows,$source_dbs,$load_recursive) = @_;
my @records : shared = ();
my $record;
if (defined $rows and ref $rows eq 'ARRAY') {
foreach my $row (@$rows) {
$record = __PACKAGE__->source_new($source_dbs->{billing_db},$row);
$record->{domain} = $row->{domain};
$record->{voip_numbers} = NGCP::BulkProcessor::Dao::mr102::billing::voip_numbers::source_findby_subscriberid($source_dbs,$record->{id});
if ($load_recursive
and (('CODE' eq ref $load_recursive->{'voip_subscribers.provisioning_voip_subscriber'} and $load_recursive->{'voip_subscribers.provisioning_voip_subscriber'}->($record))
or (not ref $load_recursive->{'voip_subscribers.provisioning_voip_subscriber'} and $load_recursive->{'voip_subscribers.provisioning_voip_subscriber'}))) {
$record->{provisioning_voip_subscriber} = NGCP::BulkProcessor::Dao::mr102::provisioning::voip_subscribers::source_findby_uuid($source_dbs,$record->{uuid});
#$record->{primary_number} = NGCP::BulkProcessor::Dao::mr102::billing::voip_numbers::source_findby_id($source_dbs,$record->{primary_number_id});
}
#delete $record->{domain_id};
#delete $record->{primary_number_id};
#delete $record->{contract_id};
#delete $record->{id};
push @records,$record;
}
}
return \@records;
}
1;

@ -0,0 +1,174 @@
package NGCP::BulkProcessor::Dao::mr102::openser::voicemail_users;
use strict;
## no critic
use threads::shared;
use Locale::Recode qw();
use NGCP::BulkProcessor::Logging qw(
getlogger
);
use NGCP::BulkProcessor::ConnectorPool qw(
get_kamailio_db
);
use NGCP::BulkProcessor::SqlProcessor qw(
checktableinfo
copy_row
);
use NGCP::BulkProcessor::SqlRecord qw();
require Exporter;
our @ISA = qw(Exporter NGCP::BulkProcessor::SqlRecord);
our @EXPORT_OK = qw(
gettablename
check_table
source_findby_customerid
);
my $tablename = 'voicemail_users';
my $get_db = \&get_kamailio_db;
my $expected_fieldnames = [
'uniqueid',
'customer_id',
'context',
'mailbox',
'password',
'fullname',
'email',
'pager',
'tz',
'attach',
'saycid',
'dialout',
'callback',
'review',
'operator',
'envelope',
'sayduration',
'saydurationm',
'sendvoicemail',
'delete',
'nextaftercmd',
'forcename',
'forcegreetings',
'hidefromdir',
'stamp',
];
my $indexes = {};
sub new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new($class,$get_db,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub buildrecords_fromrows {
my ($rows,$load_recursive) = @_;
my @records = ();
my $record;
if (defined $rows and ref $rows eq 'ARRAY') {
foreach my $row (@$rows) {
$record = __PACKAGE__->new($row);
# transformations go here ...
push @records,$record;
}
}
return \@records;
}
sub gettablename {
return $tablename;
}
sub check_table {
return checktableinfo(shift // $get_db,
__PACKAGE__,$tablename,
$expected_fieldnames,
$indexes);
}
sub source_new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new_shared($class,shift,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub source_findby_customerid {
my ($source_dbs,$uuid) = @_;
my $source_db = $source_dbs->{openser_db};
check_table($source_db);
my $db = &$source_db();
my $table = $db->tableidentifier($tablename);
my $stmt = 'SELECT * FROM ' . $table . ' WHERE ' .
$db->columnidentifier('customer_id') . ' = ?';
my @params = ($uuid);
my $rows = $db->db_get_all_arrayref($stmt,@params);
return source_buildrecords_fromrows($rows,$source_dbs);
}
sub source_buildrecords_fromrows {
my ($rows,$source_dbs) = @_;
my @records : shared = ();
my $record;
my $recoder = Locale::Recode->new( from => 'ISO-8859-1', to => 'UTF-8' );
if (defined $rows and ref $rows eq 'ARRAY') {
foreach my $row (@$rows) {
$record = __PACKAGE__->source_new($source_dbs->{openser_db},$row);
# transformations go here ...
foreach my $field (keys %$record) {
$record->{$field} = $recoder->recode($record->{$field}) if $record->{field};
}
push @records,$record;
}
}
return \@records;
}
1;

@ -0,0 +1,119 @@
package NGCP::BulkProcessor::Dao::mr102::provisioning::voip_allowed_ip_groups;
use strict;
## no critic
use threads::shared;
use NGCP::BulkProcessor::ConnectorPool qw(
get_provisioning_db
);
use NGCP::BulkProcessor::SqlProcessor qw(
checktableinfo
copy_row
);
use NGCP::BulkProcessor::SqlRecord qw();
require Exporter;
our @ISA = qw(Exporter NGCP::BulkProcessor::SqlRecord);
our @EXPORT_OK = qw(
gettablename
check_table
source_findby_group_id
);
my $tablename = 'voip_allowed_ip_groups';
my $get_db = \&get_provisioning_db;
my $expected_fieldnames = [
'id',
'group_id',
'ipnet',
];
my $indexes = {};
sub new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new($class,$get_db,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub gettablename {
return $tablename;
}
sub check_table {
return checktableinfo(shift // $get_db,
__PACKAGE__,$tablename,
$expected_fieldnames,
$indexes);
}
sub source_new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new_shared($class,shift,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub source_findby_group_id {
my ($source_dbs,$group_id) = @_;
my $source_db = $source_dbs->{provisioning_db};
check_table($source_db);
my $db = &$source_db();
my $table = $db->tableidentifier($tablename);
my $stmt = 'SELECT * FROM ' . $table . ' WHERE ' .
$db->columnidentifier('group_id') . ' = ?';
my @params = ($group_id);
my $rows = $db->db_get_all_arrayref($stmt,@params);
return source_buildrecords_fromrows($rows,$source_dbs);
}
sub source_buildrecords_fromrows {
my ($rows,$source_dbs) = @_;
my @records : shared = ();
my $record;
if (defined $rows and ref $rows eq 'ARRAY') {
foreach my $row (@$rows) {
$record = __PACKAGE__->source_new($source_dbs->{provisioning_db},$row);
# transformations go here ...
push @records,$record;
}
}
return \@records;
}
1;

@ -0,0 +1,128 @@
package NGCP::BulkProcessor::Dao::mr102::provisioning::voip_dbaliases;
use strict;
## no critic
use threads::shared;
use NGCP::BulkProcessor::Logging qw(
getlogger
);
use NGCP::BulkProcessor::ConnectorPool qw(
get_provisioning_db
);
use NGCP::BulkProcessor::SqlProcessor qw(
checktableinfo
copy_row
);
use NGCP::BulkProcessor::SqlRecord qw();
require Exporter;
our @ISA = qw(Exporter NGCP::BulkProcessor::SqlRecord);
our @EXPORT_OK = qw(
gettablename
check_table
source_findby_subscriberid
);
my $tablename = 'voip_dbaliases';
my $get_db = \&get_provisioning_db;
my $expected_fieldnames = [
'id',
'username',
'domain_id',
'subscriber_id',
];
my $indexes = {};
sub new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new($class,$get_db,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub gettablename {
return $tablename;
}
sub check_table {
return checktableinfo(shift // $get_db,
__PACKAGE__,$tablename,
$expected_fieldnames,
$indexes);
}
sub source_new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new_shared($class,shift,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub source_findby_subscriberid {
my ($source_dbs,$subscriber_id) = @_;
my $source_db = $source_dbs->{provisioning_db};
check_table($source_db);
my $db = &$source_db();
my $table = $db->tableidentifier($tablename);
my $stmt = 'SELECT * FROM ' . $table . ' WHERE ' .
$db->columnidentifier('subscriber_id') . ' = ?';
my @params = ($subscriber_id);
my $rows = $db->db_get_all_arrayref($stmt,@params);
return source_buildrecords_fromrows($rows,$source_dbs);
}
sub source_buildrecords_fromrows {
my ($rows,$source_dbs) = @_;
my @records : shared = ();
my $record;
if (defined $rows and ref $rows eq 'ARRAY') {
foreach my $row (@$rows) {
$record = __PACKAGE__->source_new($source_dbs->{provisioning_db},$row);
# transformations go here ...
#delete $record->{domain_id};
#delete $record->{subscriber_id};
#delete $record->{id};
push @records,$record;
}
}
return \@records;
}
1;

@ -0,0 +1,132 @@
package NGCP::BulkProcessor::Dao::mr102::provisioning::voip_fax_destinations;
use strict;
## no critic
use threads::shared;
use NGCP::BulkProcessor::Logging qw(
getlogger
);
use NGCP::BulkProcessor::ConnectorPool qw(
get_provisioning_db
);
use NGCP::BulkProcessor::SqlProcessor qw(
checktableinfo
copy_row
);
use NGCP::BulkProcessor::SqlRecord qw();
require Exporter;
our @ISA = qw(Exporter NGCP::BulkProcessor::SqlRecord);
our @EXPORT_OK = qw(
gettablename
check_table
source_findby_subscriberid
);
my $tablename = 'voip_fax_destinations';
my $get_db = \&get_provisioning_db;
my $expected_fieldnames = [
'id',
'subscriber_id',
'destination',
'filetype',
'cc',
'incoming',
'outgoing',
'status',
];
my $indexes = {};
sub new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new($class,$get_db,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub gettablename {
return $tablename;
}
sub check_table {
return checktableinfo(shift // $get_db,
__PACKAGE__,$tablename,
$expected_fieldnames,
$indexes);
}
sub source_new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new_shared($class,shift,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub source_findby_subscriberid {
my ($source_dbs,$subscriber_id) = @_;
my $source_db = $source_dbs->{provisioning_db};
check_table($source_db);
my $db = &$source_db();
my $table = $db->tableidentifier($tablename);
my $stmt = 'SELECT * FROM ' . $table . ' WHERE ' .
$db->columnidentifier('subscriber_id') . ' = ?';
my @params = ($subscriber_id);
my $rows = $db->db_get_all_arrayref($stmt,@params);
return source_buildrecords_fromrows($rows,$source_dbs);
}
sub source_buildrecords_fromrows {
my ($rows,$source_dbs) = @_;
my @records : shared = ();
my $record;
if (defined $rows and ref $rows eq 'ARRAY') {
foreach my $row (@$rows) {
$record = __PACKAGE__->source_new($source_dbs->{provisioning_db},$row);
# transformations go here ...
#delete $record->{subscriber_id};
#delete $record->{id};
push @records,$record;
}
}
return \@records;
}
1;

@ -0,0 +1,131 @@
package NGCP::BulkProcessor::Dao::mr102::provisioning::voip_fax_preferences;
use strict;
## no critic
use threads::shared;
use NGCP::BulkProcessor::Logging qw(
getlogger
);
use NGCP::BulkProcessor::ConnectorPool qw(
get_provisioning_db
);
use NGCP::BulkProcessor::SqlProcessor qw(
checktableinfo
copy_row
);
use NGCP::BulkProcessor::SqlRecord qw();
require Exporter;
our @ISA = qw(Exporter NGCP::BulkProcessor::SqlRecord);
our @EXPORT_OK = qw(
gettablename
check_table
source_findby_subscriberid
);
my $tablename = 'voip_fax_preferences';
my $get_db = \&get_provisioning_db;
my $expected_fieldnames = [
'id',
'subscriber_id',
'password',
'name',
'active',
'send_status',
'send_copy',
];
my $indexes = {};
sub new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new($class,$get_db,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub gettablename {
return $tablename;
}
sub check_table {
return checktableinfo(shift // $get_db,
__PACKAGE__,$tablename,
$expected_fieldnames,
$indexes);
}
sub source_new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new_shared($class,shift,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub source_findby_subscriberid {
my ($source_dbs,$subscriber_id) = @_;
my $source_db = $source_dbs->{provisioning_db};
check_table($source_db);
my $db = &$source_db();
my $table = $db->tableidentifier($tablename);
my $stmt = 'SELECT * FROM ' . $table . ' WHERE ' .
$db->columnidentifier('subscriber_id') . ' = ?';
my @params = ($subscriber_id);
my $rows = $db->db_get_all_arrayref($stmt,@params);
return source_buildrecords_fromrows($rows,$source_dbs)->[0];
}
sub source_buildrecords_fromrows {
my ($rows,$source_dbs) = @_;
my @records : shared = ();
my $record;
if (defined $rows and ref $rows eq 'ARRAY') {
foreach my $row (@$rows) {
$record = __PACKAGE__->source_new($source_dbs->{provisioning_db},$row);
# transformations go here ...
#delete $record->{subscriber_id};
#delete $record->{id};
push @records,$record;
}
}
return \@records;
}
1;

@ -0,0 +1,83 @@
package NGCP::BulkProcessor::Dao::mr102::provisioning::voip_preferences;
use strict;
## no critic
use NGCP::BulkProcessor::ConnectorPool qw(
get_provisioning_db
);
use NGCP::BulkProcessor::SqlProcessor qw(
checktableinfo
copy_row
);
use NGCP::BulkProcessor::SqlRecord qw();
require Exporter;
our @ISA = qw(Exporter NGCP::BulkProcessor::SqlRecord);
our @EXPORT_OK = qw(
gettablename
check_table
$ALLOWED_IPS_GRP_ATTRIBUTE
$MAN_ALLOWED_IPS_GRP_ATTRIBUTE
$EMERG_AC_ATTRIBUTE
@CF_ATTRIBUTES
$BLOCK_OUT_MODE_ATTRIBUTE
$BLOCK_OUT_LIST_ATTRIBUTE
);
my $tablename = 'voip_preferences';
my $get_db = \&get_provisioning_db;
my $expected_fieldnames = [
'id',
'attribute',
'type',
'max_occur',
'modify_timestamp',
'internal',
];
my $indexes = {};
our $ALLOWED_IPS_GRP_ATTRIBUTE = 'allowed_ips_grp';
our $MAN_ALLOWED_IPS_GRP_ATTRIBUTE = 'man_allowed_ips_grp';
our $EMERG_AC_ATTRIBUTE = 'emerg_ac';
our @CF_ATTRIBUTES = qw(cfu cft cfna cfb);
our $BLOCK_OUT_MODE_ATTRIBUTE = 'block_out_mode';
our $BLOCK_OUT_LIST_ATTRIBUTE = 'block_out_list';
sub new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new($class,$get_db,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub gettablename {
return $tablename;
}
sub check_table {
return checktableinfo(shift // $get_db,
__PACKAGE__,$tablename,
$expected_fieldnames,
$indexes);
}
1;

@ -0,0 +1,157 @@
package NGCP::BulkProcessor::Dao::mr102::provisioning::voip_subscribers;
use strict;
## no critic
use threads::shared;
use NGCP::BulkProcessor::Logging qw(
getlogger
rowinserted
);
use NGCP::BulkProcessor::ConnectorPool qw(
get_provisioning_db
);
use NGCP::BulkProcessor::SqlProcessor qw(
checktableinfo
copy_row
);
use NGCP::BulkProcessor::SqlRecord qw();
use NGCP::BulkProcessor::Dao::mr102::provisioning::voip_dbaliases qw();
use NGCP::BulkProcessor::Dao::mr102::provisioning::voip_usr_preferences qw();
use NGCP::BulkProcessor::Dao::mr102::openser::voicemail_users qw();
use NGCP::BulkProcessor::Dao::mr102::provisioning::voip_fax_preferences qw();
use NGCP::BulkProcessor::Dao::mr102::provisioning::voip_fax_destinations qw();
require Exporter;
our @ISA = qw(Exporter NGCP::BulkProcessor::SqlRecord);
our @EXPORT_OK = qw(
gettablename
check_table
source_findby_uuid
);
my $tablename = 'voip_subscribers';
my $get_db = \&get_provisioning_db;
my $expected_fieldnames = [
'id',
'username',
'domain_id',
'uuid',
'password',
'timezone',
'admin',
'account_id',
'webusername',
'webpassword',
'autoconf_displayname',
'autoconf_group_id',
'modify_timestamp',
'create_timestamp',
];
my $indexes = {};
my $insert_unique_fields = [];
sub new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new($class,$get_db,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub gettablename {
return $tablename;
}
sub check_table {
return checktableinfo(shift // $get_db,
__PACKAGE__,$tablename,
$expected_fieldnames,
$indexes);
}
sub source_new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new_shared($class,shift,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub source_findby_uuid {
my ($source_dbs,$uuid) = @_;
my $source_db = $source_dbs->{provisioning_db};
check_table($source_db);
my $db = &$source_db();
my $table = $db->tableidentifier($tablename);
my $stmt = 'SELECT * FROM ' . $table . ' WHERE ' .
$db->columnidentifier('uuid') . ' = ?';
my @params = ($uuid);
my $rows = $db->db_get_all_arrayref($stmt,@params);
return source_buildrecords_fromrows($rows,$source_dbs)->[0];
}
sub source_buildrecords_fromrows {
my ($rows,$source_dbs) = @_;
my @records : shared = ();
my $record;
if (defined $rows and ref $rows eq 'ARRAY') {
foreach my $row (@$rows) {
$record = __PACKAGE__->source_new($source_dbs->{provisioning_db},$row);
# transformations go here ...
$record->{voip_dbaliases} = NGCP::BulkProcessor::Dao::mr102::provisioning::voip_dbaliases::source_findby_subscriberid($source_dbs,$record->{id});
$record->{voip_usr_preferences} = NGCP::BulkProcessor::Dao::mr102::provisioning::voip_usr_preferences::source_findby_subscriberid($source_dbs,$record->{id});
$record->{voicemail_users} = NGCP::BulkProcessor::Dao::mr102::openser::voicemail_users::source_findby_customerid($source_dbs,$record->{uuid});
$record->{voip_fax_preferences} = NGCP::BulkProcessor::Dao::mr102::provisioning::voip_fax_preferences::source_findby_subscriberid($source_dbs,$record->{id});
$record->{voip_fax_destinations} = NGCP::BulkProcessor::Dao::mr102::provisioning::voip_fax_destinations::source_findby_subscriberid($source_dbs,$record->{id});
#delete $record->{account_id};
#delete $record->{autoconf_displayname};
#delete $record->{autoconf_group_id};
#delete $record->{domain_id};
#delete $record->{id};
push @records,$record;
}
}
return \@records;
}
1;

@ -0,0 +1,154 @@
package NGCP::BulkProcessor::Dao::mr102::provisioning::voip_usr_preferences;
use strict;
## no critic
use threads::shared;
use NGCP::BulkProcessor::Logging qw(
getlogger
);
use NGCP::BulkProcessor::ConnectorPool qw(
get_provisioning_db
);
use NGCP::BulkProcessor::SqlProcessor qw(
checktableinfo
copy_row
);
use NGCP::BulkProcessor::SqlRecord qw();
use NGCP::BulkProcessor::Dao::mr102::provisioning::voip_allowed_ip_groups qw();
use NGCP::BulkProcessor::Dao::mr102::provisioning::voip_preferences qw();
require Exporter;
our @ISA = qw(Exporter NGCP::BulkProcessor::SqlRecord);
our @EXPORT_OK = qw(
gettablename
check_table
source_findby_subscriberid
$TRUE
$FALSE
);
#source_findby_attributesused
my $tablename = 'voip_usr_preferences';
my $get_db = \&get_provisioning_db;
my $expected_fieldnames = [
'id',
'subscriber_id',
'attribute_id',
'value',
'modify_timestamp',
];
my $indexes = {};
my $insert_unique_fields = [];
our $TRUE = 1;
our $FALSE = undef;
sub new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new($class,$get_db,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub gettablename {
return $tablename;
}
sub check_table {
return checktableinfo(shift // $get_db,
__PACKAGE__,$tablename,
$expected_fieldnames,
$indexes);
}
sub source_new {
my $class = shift;
my $self = NGCP::BulkProcessor::SqlRecord->new_shared($class,shift,
$tablename,$expected_fieldnames,$indexes);
copy_row($self,shift,$expected_fieldnames);
return $self;
}
sub source_findby_subscriberid {
my ($source_dbs,$subscriber_id) = @_;
my $source_db = $source_dbs->{provisioning_db};
check_table($source_db);
my $db = &$source_db();
my $table = $db->tableidentifier($tablename);
my $stmt = 'SELECT v.*,a.attribute FROM ' . $table . ' v JOIN ' .
$db->tableidentifier('voip_preferences') . ' a ON v.attribute_id = a.id WHERE ' .
'v.subscriber_id = ?';
my @params = ($subscriber_id);
my $rows = $db->db_get_all_arrayref($stmt,@params);
return source_buildrecords_fromrows($rows,$source_dbs);
}
sub source_buildrecords_fromrows {
my ($rows,$source_dbs) = @_;
my @records : shared = ();
my $record;
if (defined $rows and ref $rows eq 'ARRAY') {
foreach my $row (@$rows) {
$record = __PACKAGE__->source_new($source_dbs->{provisioning_db},$row);
# transformations go here ...
$record->{attribute} = $row->{attribute};
if ($record->{attribute} eq $NGCP::BulkProcessor::Dao::mr102::provisioning::voip_preferences::ALLOWED_IPS_GRP_ATTRIBUTE) {
my @allowed_ip_groups : shared = map { $_->{ipnet}; } @{NGCP::BulkProcessor::Dao::mr102::provisioning::voip_allowed_ip_groups::source_findby_group_id(
$source_dbs,$record->{value})};
$record->{allowed_ip_groups} = \@allowed_ip_groups;
#delete $record->{value};
}
if ($record->{attribute} eq $NGCP::BulkProcessor::Dao::mr102::provisioning::voip_preferences::MAN_ALLOWED_IPS_GRP_ATTRIBUTE) {
my @allowed_ip_groups : shared = map { $_->{ipnet}; } @{NGCP::BulkProcessor::Dao::mr102::provisioning::voip_allowed_ip_groups::source_findby_group_id(
$source_dbs,$record->{value})};
$record->{man_allowed_ip_groups} = \@allowed_ip_groups;
#delete $record->{value};
}
#delete $record->{attribute_id};
#delete $record->{subscriber_id};
#delete $record->{id};
push @records,$record;
}
}
return \@records;
}
1;

@ -164,6 +164,7 @@ sub source_process_records {
}, },
read_code => sub { read_code => sub {
my ($rowblock) = @_; my ($rowblock) = @_;
map { &$_()->ping(); } values %$source_dbs; #keep awake.
return source_buildrecords_fromrows($rowblock,$source_dbs); return source_buildrecords_fromrows($rowblock,$source_dbs);
}, },
static_context => $static_context, static_context => $static_context,

@ -22,6 +22,8 @@ our @EXPORT_OK = qw(
$ALLOWED_IPS_GRP_ATTRIBUTE $ALLOWED_IPS_GRP_ATTRIBUTE
$MAN_ALLOWED_IPS_GRP_ATTRIBUTE $MAN_ALLOWED_IPS_GRP_ATTRIBUTE
$NCOS_ID_ATTRIBUTE $NCOS_ID_ATTRIBUTE
@CF_ATTRIBUTES
); );
my $tablename = 'voip_preferences'; my $tablename = 'voip_preferences';
@ -42,6 +44,8 @@ our $ALLOWED_IPS_GRP_ATTRIBUTE = 'allowed_ips_grp';
our $MAN_ALLOWED_IPS_GRP_ATTRIBUTE = 'man_allowed_ips_grp'; our $MAN_ALLOWED_IPS_GRP_ATTRIBUTE = 'man_allowed_ips_grp';
our $NCOS_ID_ATTRIBUTE = 'ncos_id'; our $NCOS_ID_ATTRIBUTE = 'ncos_id';
our @CF_ATTRIBUTES = qw(cfu cft cfna cfb);
sub new { sub new {
my $class = shift; my $class = shift;

Loading…
Cancel
Save