ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/XML-DB/DB.pm
(Generate patch)

Comparing XML-DB/DB.pm (file contents):
Revision 1.1 by root, Sun Apr 21 15:41:31 2002 UTC vs.
Revision 1.5 by root, Thu Apr 25 00:28:40 2002 UTC

20 20
21=cut 21=cut
22 22
23package XML::DB; 23package XML::DB;
24 24
25use XML::Parser;
26use PApp::SQL;
27
25#require Exporter; 28#require Exporter;
26require DynaLoader; 29BEGIN {
30 $VERSION = 0.01;
27 31
28$VERSION = 0.01; 32 use base DynaLoader;
29@ISA = qw/DynaLoader/;
30 33
31bootstrap DB $VERSION; 34 bootstrap XML::DB $VERSION;
35}
36
37sub new {
38 my $class = shift;
39 bless { @_ }, $class;
40}
41
42sub seq {
43 sql_insertid sql_exec "update $_[0]_seq set n = last_insert_id(n + 1)";
44}
45
46sub name_id {
47 # not threadsafe
48 sql_ufetch $_[0]{dbh}, "select i from name where n = ? and v = ?", "$_[1]", $_[2]
49 or sql_insertid sql_exec $_[0]{dbh}, "insert into name values (NULL, ?, ?)", "$_[1]", $_[2];
50
51}
52
53sub new_xml_insert_parser {
54 my $self = shift;
55 my $dbh = $self->{dbh};
56
57 my $did = 55;
58 my $max = 1 + sql_fetch $dbh, "select max(l) from node";
59
60 my $n = $max;
61
62 my @l;
63 my @attr;
64
65 new XML::Parser
66 Namespaces => 1,
67 NoExpand => 1,
68 Handlers => {
69 Comment => sub {
70 ++$n;
71 sql_exec $dbh, "insert into node values (?, ?, 'comment', NULL)",
72 $n, $n+1;
73 sql_exec $dbh, "insert into value values (?, ?)",
74 $n, $_[1];
75 ++$n;
76 },
77 Char => sub {
78 ++$n;
79 sql_exec $dbh, "insert into node values (?, ?, 'pcdata', NULL)",
80 $n, $n+1;
81 sql_exec $dbh, "insert into value values (?, ?)",
82 $n, $_[1];
83 ++$n;
84 },
85 Start => sub {
86 my ($parser, $element, @attrs) = @_;
87 push @l, ++$n;
88 push @attr, \@attrs;
89 },
90 End => sub {
91 my ($parser, $element) = @_;
92 my $attr = pop @attr;
93 my $l = pop @l;
94 sql_exec $dbh, "insert into node values (?, ?, 'element', ?)",
95 $l, ++$n, $self->name_id($parser->namespace($element), $element);
96
97 for (my $i = 0; $i < @$attr; $i += 2) {
98 sql_exec $dbh, "insert into attr values (?, ?, ?)",
99 $l, $self->name_id($parser->namespace($attr->[$i]), $attr->[$i]),
100 $attr->[$i+1];
101 }
102 },
103 Final => sub {
104 sql_exec $dbh, "insert into node values (?, ?, 'root', NULL)",
105 $max*1, ++$n;
106 },
107 },
108 @_,
109 ;
110}
111
112sub get_fragment {
113 my ($self, $ol) = @_;
114
115 my $or = sql_fetch $self->{dbh}, "select r from node where l = ?", $ol;
116 my $st = sql_exec $self->{dbh}, \my($l, $r, $t, $ns, $name, $value),
117 "select node.l, node.r, node.t, name.n, name.v, value.v
118 from node left join name on (node.n = name.i)
119 left join value on (node.l = value.l)
120 where node.l > ? and node.r < ? order by node.l",
121 $ol, $or;
122
123 my $ot;
124 my @stack;
125 my $doc = "";
126 my (%nsp, $nsps, $nso);
127 my $nsp = "a";
128
129 my $expand_name = sub {
130 $_[0] ? ($nsp{$_[0]} ||= do {
131 $nsps .= " xmlns:$nsp='$_[0]'";
132 $nsp++;
133 }) . ":$_[1]"
134 : $_[1];
135 };
136
137 while ($st->fetch) {
138 if ($l > $or) {
139 ($ol, $or, $oc) = @{pop @stack};
140
141 $doc .= "</$oc>";
142 }
143
144 if ($t eq "element") {
145 push @stack, [$ol, $or, $name];
146 ($ol, $or) = ($l, $r);
147
148 $doc .= "<" . $expand_name->($ns, $name);
149 $nso ||= length $doc;
150
151 my $st = sql_exec $self->{dbh}, \my($ns, $name, $value),
152 "select name.n, name.v, attr.v
153 from attr inner join name on (attr.k = name.i)
154 where attr.l = ?",
155 $l;
156 while ($st->fetch) {
157 $doc .= " " . $expand_name->($ns, $name) . "='" . $value ."'";
158 }
159
160 $doc .= ">";
161 } elsif ($t eq "pcdata" or $t eq "comment") {
162 $doc .= $value;
163 } elsif ($t eq "entity") {
164 } elsif ($t eq "pi") {
165 } elsif ($t eq "doctype") {
166 } else {
167 die "FATAL: database corrupt, unexpected nodetype '$t'";
168 }
169 }
170
171 substr $doc, $nso, 0, $nsps;
172 $doc;
173}
32 174
331; 1751;
34 176
35 177
36 178

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines