1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-08 17:02:21 +03:00
Files
mariadb/ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Database.pm
tomas@poseidon.(none) 8327a68438 neww ndb automake
2004-05-26 15:36:55 +00:00

322 lines
7.2 KiB
Perl

package NDB::Net::Database;
use strict;
use Carp;
use Symbol;
require NDB::Net::Base;
use vars qw(@ISA);
@ISA = qw(NDB::Net::Base);
# constructors
my $log;
sub initmodule {
$log = NDB::Util::Log->instance;
}
my %dbcache = ();
NDB::Net::Database->attributes(
name => sub { s/^\s+|\s+$//g; /^\S+$/ && ! m!/! },
comment => sub { defined },
version => sub { /^\d+(\.\d+)*$/ },
base => sub { $^O eq 'MSWin32' || m!^/\S+$! },
home => sub { $^O eq 'MSWin32' || m!^/\S+$! },
nodeport => sub { $_ > 0 },
);
sub desc {
my $db = shift;
return $db->getname;
}
sub new {
my $class = shift;
@_ % 2 == 0 or confess 0+@_;
my(%attr) = @_;
my $db = $class->SUPER::new(%attr);
$db->setname($attr{name})
or $log->push, return undef;
if ($dbcache{$db->getname}) {
$log->put("duplicate db")->push($db);
return undef;
}
$db->setcomment($attr{comment});
$db->setversion($attr{version})
or $log->push, return undef;
if (defined($attr{base})) {
$db->setbase($attr{base})
or $log->push, return undef;
}
if (defined($attr{home})) {
if ($^O ne 'MSWin32' && $attr{home} !~ m!^/! && $db->hasbase) {
$attr{home} = $db->getbase . "/$attr{home}";
}
$db->sethome($attr{home})
or $log->push, return undef;
}
if (defined($attr{nodeport})) {
$db->setnodeport($attr{nodeport})
or $log->push, return undef;
}
if ($^O eq 'MSWin32' && ! $db->hasnodeport) {
$log->put("nodeport required on windows")->push($db), return undef;
}
$db->{nodehash} = {};
$dbcache{$db->getname} = $db;
return $db;
}
sub delete {
my $db = shift;
my $nodelist = $db->getnodelist('all');
for my $node (@$nodelist) {
$node->delete;
}
delete $dbcache{$db->getname};
}
sub deleteall {
my $class = shift;
for my $name (sort keys %dbcache) {
my $db = $dbcache{$name};
$db->delete;
}
}
# assume numerical dot separated version numbers like 1.1.2
sub cmpversion {
my $db = shift;
my $version = shift;
my @x = split(/\./, $db->getversion);
my @y = split(/\./, $version);
while (@x || @y) {
return -1 if $x[0] < $y[0];
return +1 if $x[0] > $y[0];
shift(@x);
shift(@y);
}
return 0;
}
# nodes
sub addnode {
my $db = shift;
@_ == 1 or confess 0+@_;
my($node) = @_;
unless (ref($node) && $node->isa('NDB::Net::Node')) {
confess 'oops';
}
my $id = $node->getid;
if ($db->{nodehash}{$id}) {
$log->put("$id: duplicate node id")->push($db);
return undef;
}
$db->{nodehash}{$id} = $node;
return 1;
}
sub getnode {
my $db = shift;
@_ == 1 or confess 0+@_;
my($id) = @_;
$id += 0;
my $node = $db->{nodehash}{$id};
if (! $node) {
$log->put("$id: no such node id")->push($db);
return undef;
}
return $node;
}
sub getnodelist {
my $db = shift;
@_ == 1 or confess 0+@_;
my($type) = @_;
$type =~ /^(all|mgmt|db|api)$/ or confess 'oops';
my @nodes = ();
for my $id (sort { $a <=> $b } keys %{$db->{nodehash}}) {
my $node = $db->{nodehash}{$id};
if ($type eq 'all' or $type eq $node->gettype) {
push(@nodes, $node);
}
}
return \@nodes;
}
# start /stop
sub start {
my $db = shift;
@_ == 1 or confess 0+@_;
my($opts) = @_;
if ($opts->{stop} || $opts->{kill}) {
my $method = $opts->{stop} ? "stop" : "kill";
my %opts = ();
$db->$method(\%opts)
or $log->push, return undef;
}
$log->put("start")->push($db)->info;
my $nodesmgmt = $db->getnodelist('mgmt');
my $nodesdb = $db->getnodelist('db');
my $nodesapi = $db->getnodelist('api');
my $ret;
try: {
my %startopts = ();
for my $k (qw(local init_rm nostart config old home clean proxy)) {
$startopts{$k} = $opts->{$k} if defined($opts->{$k});
}
my %writeopts = ();
for my $k (qw(local)) {
$writeopts{$k} = $opts->{$k} if defined($opts->{$k});
}
if ($db->cmpversion("1.0") > 0) {
for my $node (@$nodesmgmt) {
$node->start(\%startopts) or last try;
}
for my $node (@$nodesdb) {
$node->start(\%startopts) or last try;
}
if (! $opts->{config}) {
for my $node (@$nodesmgmt) { # probably redundant
$node->write(\%writeopts, "all start") or last try;
last;
}
}
}
else {
for my $node (@$nodesdb) {
$node->start(\%startopts) or last try;
}
if (! $opts->{config}) {
for my $node (@$nodesdb) { # probably redundant
$node->write(\%writeopts, "start") or last try;
}
}
}
for my $node (@$nodesapi) {
my %apiopts = %startopts;
if ($node->getruntype eq 'manual') {
$apiopts{config} = 1;
}
$node->start(\%apiopts) or last try;
}
$ret = 1;
}
if (! $ret) {
$log->push("start failed")->push($db);
return undef;
}
my $msg = ! $opts->{config} ? "start done" : "config created";
$log->put($msg)->push($db)->user;
return 1;
}
sub stop {
my $db = shift;
@_ == 1 or confess 0+@_;
my($opts) = @_;
$log->put("stop")->push($db)->info;
my $nodesmgmt = $db->getnodelist('mgmt');
my $nodesdb = $db->getnodelist('db');
my $nodesapi = $db->getnodelist('api');
my $ret;
try: {
for my $node (@$nodesapi) {
$node->stop($opts) or last try;
}
if ($db->cmpversion("1.0") > 0) {
for my $node (@$nodesmgmt) {
$node->write($opts, "all stop") or last try;
last;
}
for my $node (@$nodesdb) {
$node->stop($opts) or last try;
}
for my $node (@$nodesmgmt) {
$node->stop($opts) or last try;
}
}
else {
for my $node (@$nodesdb) {
$node->write($opts, "stop") or last try;
}
for my $node (@$nodesdb) {
$node->stop($opts) or last try;
}
}
$ret = 1;
}
if (! $ret) {
$log->push("stop failed")->push($db);
return undef;
}
$log->put("stop done")->push($db)->user;
return 1;
}
sub kill {
my $db = shift;
@_ == 1 or confess 0+@_;
my($opts) = @_;
$log->put("kill")->push($db)->info;
my $nodesmgmt = $db->getnodelist('mgmt');
my $nodesdb = $db->getnodelist('db');
my $nodesapi = $db->getnodelist('api');
my $ret = 1;
try: {
for my $node (@$nodesapi) {
$node->kill($opts) || ($ret = undef);
}
for my $node (@$nodesdb) {
$node->kill($opts) || ($ret = undef);
}
for my $node (@$nodesmgmt) {
$node->kill($opts) || ($ret = undef);
}
}
if (! $ret) {
$log->push("kill failed")->push($db);
return undef;
}
$log->put("kill done")->push($db)->user;
return 1;
}
sub list {
my $db = shift;
@_ == 1 or confess 0+@_;
my($opts) = @_;
my $dbsts = {};
$dbsts->{comment} = $db->getcomment("");
$dbsts->{home} = $db->gethome;
$log->put("status")->push($db)->info;
my $mgmsts;
for my $node (@{$db->getnodelist('mgmt')}) {
$mgmsts = $node->get_status or
$log->push->error;
last;
}
$mgmsts ||= {};
for my $node (@{$db->getnodelist('all')}) {
my $id = $node->getid;
my $nodests = $dbsts->{node}{$id} ||= {};
my $stat = $node->stat($opts) or
$log->push->error;
$nodests->{id} = $id;
$nodests->{type} = $node->gettype;
$nodests->{comment} = $node->getcomment("");
$nodests->{host} = $node->getserver->gethost;
$nodests->{run} = $stat || "error";
$nodests->{status} = $mgmsts->{node}{$id};
}
return $dbsts;
}
1;
# vim:set sw=4: