… | |
… | |
48 | sql_ufetch $_[0]{dbh}, "select i from name where n = ? and v = ?", "$_[1]", $_[2] |
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]; |
49 | or sql_insertid sql_exec $_[0]{dbh}, "insert into name values (NULL, ?, ?)", "$_[1]", $_[2]; |
50 | |
50 | |
51 | } |
51 | } |
52 | |
52 | |
53 | sub new_value { |
|
|
54 | sql_insertid sql_exec $_[0]{dbh}, "insert into value values (NULL, ?)", $_[1]; |
|
|
55 | } |
|
|
56 | |
|
|
57 | sub new_xml_insert_parser { |
53 | sub new_xml_insert_parser { |
58 | my $self = shift; |
54 | my $self = shift; |
59 | my $dbh = $self->{dbh}; |
55 | my $dbh = $self->{dbh}; |
60 | |
56 | |
61 | my $did = 55; |
57 | my $did = 55; |
|
|
58 | my $max = 1 + sql_fetch $dbh, "select max(l) from node"; |
|
|
59 | |
62 | my $n = 1; |
60 | my $n = $max + 1; |
63 | |
61 | |
64 | my @l; |
62 | my @l; |
65 | my @attr; |
63 | my @attr; |
66 | |
64 | |
67 | new XML::Parser |
65 | new XML::Parser |
68 | Namespaces => 1, |
66 | Namespaces => 1, |
69 | NoExpand => 1, |
67 | NoExpand => 1, |
70 | Handlers => { |
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 | }, |
71 | Char => sub { |
77 | Char => sub { |
|
|
78 | ++$n; |
72 | sql_exec $dbh, "insert into node values (?, ?, ?, 'pcdata', ?)", |
79 | sql_exec $dbh, "insert into node values (?, ?, 'pcdata', NULL)", |
73 | $did, $n+1, $n+2, $self->new_value($_[1]); |
80 | $n, $n+1; |
|
|
81 | sql_exec $dbh, "insert into value values (?, ?)", |
|
|
82 | $n, $_[1]; |
74 | $n += 2; |
83 | ++$n; |
75 | }, |
84 | }, |
76 | Start => sub { |
85 | Start => sub { |
77 | my ($parser, $element, @attrs) = @_; |
86 | my ($parser, $element, @attrs) = @_; |
78 | push @l, ++$n; |
87 | push @l, ++$n; |
79 | push @attr, \@attrs; |
88 | push @attr, \@attrs; |
80 | }, |
89 | }, |
81 | End => sub { |
90 | End => sub { |
82 | my ($parser, $element) = @_; |
91 | my ($parser, $element) = @_; |
83 | my $attr = pop @attr; |
92 | my $attr = pop @attr; |
84 | my $l = pop @l; |
93 | my $l = pop @l; |
85 | sql_exec $dbh, "insert into node values (?, ?, ?, 'element', ?)", |
94 | sql_exec $dbh, "insert into node values (?, ?, 'element', ?)", |
86 | $did, $l, ++$n, $self->name_id($parser->namespace($element), $element); |
95 | $l, ++$n, $self->name_id($parser->namespace($element), $element); |
87 | |
96 | |
88 | for (my $i = 0; $i < @$attr; $i += 2) { |
97 | for (my $i = 0; $i < @$attr; $i += 2) { |
89 | sql_exec $dbh, "insert into attr values (?, ?, ?, ?)", |
98 | sql_exec $dbh, "insert into attr values (?, ?, ?)", |
90 | $did, $l, $self->name_id($parser->namespace($attr->[$i]), $attr->[$i]), |
99 | $l, $self->name_id($parser->namespace($attr->[$i]), $attr->[$i]), |
91 | $self->new_value($attr->[$i+1]); |
100 | $attr->[$i+1]; |
92 | } |
101 | } |
93 | }, |
102 | }, |
94 | Final => sub { |
103 | Final => sub { |
95 | sql_exec $dbh, "insert into node values (?, ?, ?, 'root', 0)", |
104 | sql_exec $dbh, "insert into node values (?, ?, 'root', NULL)", |
96 | $did, 1, ++$n; |
105 | $max*1, ++$n; |
97 | }, |
106 | }, |
98 | }, |
107 | }, |
99 | @_, |
108 | @_, |
100 | ; |
109 | ; |
101 | } |
110 | } |
102 | |
111 | |
103 | sub get_fragment { |
112 | sub get_fragment { |
104 | my ($self, $did, $ol) = @_; |
113 | my ($self, $ol) = @_; |
105 | |
114 | |
106 | $ol ||= 1; |
|
|
107 | |
|
|
108 | my $or = sql_fetch $self->{dbh}, "select r from node where did = ? and l = ?", $did, $ol; |
115 | my $or = sql_fetch $self->{dbh}, "select r from node where l = ?", $ol; |
109 | my $st = sql_exec $self->{dbh}, \my($l, $r, $t, $c), |
116 | my $st = sql_exec $self->{dbh}, \my($l, $r, $t, $ns, $name, $value), |
110 | "select l, r, t, c from node where did = ? and l > ? and r < ? order by l", |
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", |
111 | $did, $ol, $or; |
121 | $ol, $or; |
112 | |
122 | |
113 | my $ot; |
123 | my $ot; |
114 | my @stack; |
124 | my @stack; |
115 | my $doc = ""; |
125 | my $doc = ""; |
116 | my %ns; |
126 | my (%nsp, $nsps, $nso); |
117 | my $nso; |
|
|
118 | my $nsp = "a"; |
127 | my $nsp = "a"; |
119 | |
128 | |
120 | my $expand_name = sub { |
129 | my $expand_name = sub { |
121 | $ns{$_[0]} ||= $nsp++; |
130 | $_[0] ? ($nsp{$_[0]} ||= do { |
|
|
131 | $nsps .= " xmlns:$nsp='$_[0]'"; |
|
|
132 | $nsp++; |
|
|
133 | }) . ":$_[1]" |
|
|
134 | : $_[1]; |
122 | }; |
135 | }; |
123 | |
136 | |
124 | while ($st->fetch) { |
137 | while ($st->fetch) { |
125 | if ($l > $or) { |
138 | if ($l > $or) { |
126 | ($ol, $or, $oc) = @{pop @stack}; |
139 | ($ol, $or, $oc) = @{pop @stack}; |
127 | |
140 | |
128 | $doc .= "</$oc>"; |
141 | $doc .= "</$oc>"; |
129 | } |
142 | } |
130 | |
143 | |
131 | if ($t eq "element") { |
144 | if ($t eq "element") { |
132 | my ($ns, $name) = $expand_name->(sql_ufetch $self->{dbh}, "select ns, v from name where i = ?", $c); |
|
|
133 | push @stack, [$ol, $or, $ns]; |
145 | push @stack, [$ol, $or, $name]; |
134 | ($ol, $or) = ($l, $r); |
146 | ($ol, $or) = ($l, $r); |
135 | |
147 | |
136 | $doc .= "<$ns"; |
148 | $doc .= "<" . $expand_name->($ns, $name); |
|
|
149 | $nso ||= length $doc; |
137 | |
150 | |
138 | my $st = sql_exec $self->{dbh}, "select name.n, , v from |
151 | my $st = sql_exec $self->{dbh}, \my($ns, $name, $value), |
139 | } elsif ($t eq "pcdata") { |
152 | "select name.n, name.v, attr.v |
140 | $c = sql_ufetch $self->{dbh}, "select v from value where i = ?", $c; |
153 | from attr inner join name on (attr.k = name.i) |
141 | |
154 | where attr.l = ?", |
|
|
155 | $l; |
|
|
156 | while ($st->fetch) { |
|
|
157 | $doc .= " " . $expand_name->($ns, $name) . "='" . $value ."'"; |
|
|
158 | } |
|
|
159 | |
142 | $doc .= "$c"; |
160 | $doc .= ">"; |
143 | |
161 | } elsif ($t eq "pcdata" or $t eq "comment") { |
|
|
162 | $doc .= $value; |
144 | } elsif ($t eq "entity") { |
163 | } elsif ($t eq "entity") { |
145 | } elsif ($t eq "pi") { |
164 | } elsif ($t eq "pi") { |
146 | } elsif ($t eq "doctype") { |
165 | } elsif ($t eq "doctype") { |
147 | } else { |
166 | } else { |
148 | die "FATAL: database corrupt, unexpected nodetype '$t'"; |
167 | die "FATAL: database corrupt, unexpected nodetype '$t'"; |
149 | } |
168 | } |
150 | } |
169 | } |
151 | |
170 | |
|
|
171 | substr $doc, $nso, 0, $nsps; |
152 | $doc; |
172 | $doc; |
153 | } |
173 | } |
154 | |
174 | |
155 | 1; |
175 | 1; |
156 | |
176 | |