1XBase::Index(3) User Contributed Perl Documentation XBase::Index(3)
2
3
4
6 XBase::Index - base class for the index files for dbf
7
9 use XBase;
10 my $table = new XBase "data.dbf";
11 my $cur = $table->prepare_select_with_index("id.ndx",
12 "ID", "NAME);
13 $cur->find_eq(1097);
14
15 while (my @data = $cur->fetch()) {
16 last if $data[0] != 1097;
17 print "@data\n";
18 }
19
20 This is a snippet of code to print ID and NAME fields from dbf data.dbf
21 where ID equals 1097. Provided you have index on ID in file id.ndx. You
22 can use the same code for ntx and idx index files. For the cdx and
23 mdx, the prepare_select call would be
24
25 prepare_select_with_index(['rooms.cdx', 'ROOMNAME'])
26
27 so instead of plain filename you specify an arrayref with filename and
28 an index tag in that file. The reason is that cdx and mdx can contain
29 multiple indexes in one file and you have to distinguish, which you
30 want to use.
31
33 The module XBase::Index is a collection of packages to provide index
34 support for XBase-like dbf database files.
35
36 An index file is generaly a file that holds values of certain database
37 field or expression in sorted order, together with the record number
38 that the record occupies in the dbf file. So when you search for a
39 record with some value, you first search in this sorted list and once
40 you have the record number in the dbf, you directly fetch the record
41 from dbf.
42
43 What indexes do
44 To make the searching in this ordered list fast, it's generally
45 organized as a tree -- it starts with a root page with records that
46 point to pages at lower level, etc., until leaf pages where the pointer
47 is no longer a pointer to the index but to the dbf. When you search for
48 a record in the index file, you fetch the root page and scan it
49 (lineary) until you find key value that is equal or grater than that
50 you are looking for. That way you've avoided reading all pages
51 describing the values that are lower. Here you descend one level, fetch
52 the page and again search the list of keys in that page. And you repeat
53 this process until you get to the leaf (lowest) level and here you
54 finaly find a pointer to the dbf. XBase::Index does this for you.
55
56 Some of the formats also support multiple indexes in one file --
57 usually there is one top level index that for different field values
58 points to different root pages in the index file (so called tags).
59
60 XBase::Index supports (or aims to support) the following index formats:
61 ndx, ntx, mdx, cdx and idx. They differ in a way they store the keys
62 and pointers but the idea is always the same: make a tree of pages,
63 where the page contains keys and pointer either to pages at lower
64 levels, or to dbf (or both). XBase::Index only supports read only
65 access to the index fields at the moment (and if you need writing them
66 as well, follow reading because we need to have the reading support
67 stable before I get to work on updating the indexes).
68
69 Testing your index file (and XBase::Index)
70 You can test your index using the indexdump script in the main
71 directory of the DBD::XBase distribution (I mean test XBase::Index on
72 correct index data, not testing corrupted index file, of course ;-)
73 Just run
74
75 ./indexdump ~/path/index.ndx
76 ./indexdump ~/path/index.cdx tag_name
77
78 or
79
80 perl -Ilib ./indexdump ~/path/index.cdx tag_name
81
82 if you haven't installed this version of XBase.pm/DBD::XBase yet. You
83 should get the content of the index file. On each row, there is the key
84 value and a record number of the record in the dbf file. Let me know if
85 you get results different from those you expect. I'd probably ask you
86 to send me the index file (and possibly the dbf file as well), so that
87 I can debug the problem.
88
89 The index file is (as already noted) a complement to a dbf file. Index
90 file without a dbf doesn't make much sense because the only thing that
91 you can get from it is the record number in the dbf file, not the
92 actual data. But it makes sense to test -- dump the content of the
93 index to see if the sequence is OK.
94
95 The index formats usually distinguish between numeric and character
96 data. Some of the file formats include the information about the type
97 in the index file, other depend on the dbf file. Since with indexdump
98 we only look at the index file, you may need to specify the -type
99 option to indexdump if it complains that it doesn't know the data type
100 of the values (this is the case with cdx at least). The possible values
101 are num, char and date and the call would be like
102
103 ./indexdump -type=num ~/path/index.cdx tag_name
104
105 (this -type option may not work with all index formats at the moment --
106 will be fixed and patches always welcome).
107
108 You can use "-ddebug" option to indexdump to see how pages are fetched
109 and decoded, or run debugger to see the calls and parsing.
110
111 Using the index files to speed up searches in dbf
112 The syntax for using the index files to access data in the dbf file is
113 generally
114
115 my $table = new XBase "tablename";
116 # or any other arguments to get the XBase object
117 # see XBase(3)
118 my $cur = $table->prepare_select_with_index("indexfile",
119 "list", "of", "fields", "to", "return");
120
121 or
122
123 my $cur = $table->prepare_select_with_index(
124 [ "indexfile_with_tags", "tag_name" ],
125 "list", "of", "fields", "to", "return");
126
127 where we specify the tag in the index file (this is necessary with cdx
128 and mdx). After we have the cursor, we can search to given record and
129 start fetching the data:
130
131 $cur->find_eq('jezek');
132 while (my @data = $cur->fetch) { # do something
133
134 Supported index formats
135 The following table summarizes which formats are supproted by
136 XBase::Index. If the field says something else that Yes, I welcome
137 testers and offers of example index files.
138
139 Reading of index files -- types supported by XBase::Index
140
141 type string numeric date
142 ----------------------------------------------------------
143 ndx Yes Yes Yes (you need to
144 convert to Julian)
145
146 ntx Yes Yes Untested
147
148 idx Untested Untested Untested
149 (but should be pretty usable)
150
151 mdx Untested Untested Untested
152
153 cdx Yes Yes Untested
154
155
156 Writing of index files -- not supported untill the reading
157 is stable enough.
158
159 So if you have access to an index file that is untested or unsupported
160 and you care about support of these formats, contact me. If you are
161 able to actually generate those files on request, the better because I
162 may need specific file size or type to check something. If the file
163 format you work with is supported, I still appreciate a report that it
164 really works for you.
165
166 Please note that there is very little documentation about the file
167 formats and the work on XBase::Index is heavilly based on making
168 assumption based on real life data. Also, the documentation is often
169 wrong or only describing some format variations but not the others. I
170 personally do not need the index support but am more than happy to make
171 it a reality for you. So I need your help -- contact me if it doesn't
172 work for you and offer me your files for testing. Mentioning word XBase
173 somewhere in the Subject line will get you (hopefully ;-) fast
174 response. Mentioning work Help or similar stupidity will probably make
175 my filters to consider your email as spam. Help yourself by making my
176 life easier in helping you.
177
178 Programmer's notes
179 Programmers might find the following information usefull when trying to
180 debug XBase::Index from their files:
181
182 The XBase::Index module contains the basic XBase::Index package and
183 also packages XBase::ndx, XBase::ntx, XBase::idx, XBase::mdx and
184 XBase::cdx, and for each of these also a package
185 XBase::index_type::Page. Reading the file goes like this: you create as
186 object calling either new XBase::Index or new XBase::ndx (or whatever
187 the index type is). This can also be done behind the scenes, for
188 example XBase::prepare_select_with_index calls new XBase::Index. The
189 index file is opened using the XBase::Base::new/open and then the
190 XBase::index_type::read_header is called. This function fills the basic
191 data fields of the object from the header of the file. The new method
192 returns the object corresponding to the index type.
193
194 Then you probably want to do $index->prepare_select or
195 $index->prepare_select_eq, that would possition you just before record
196 equal or greater than the parameter (record in the index file, that
197 is). Then you do a series of fetch'es that return next pair of (key,
198 pointer_to_dbf). Behind the scenes, prepare_select_eq or fetch call
199 XBase::Index::get_record which in turn calls
200 XBase::index_type::Page::new. From the index file perspective, the
201 atomic item in the file is one index page (or block, or whatever you
202 call it). The XBase::index_type::Page::new reads the block of data from
203 the file and parses the information in the page -- pages have more or
204 less complex structures. Page::new fills the structure, so that the
205 fetch calls can easily check what values are in the page.
206
207 For some examples, please see eg/use_index in the distribution
208 directory.
209
211 1.05
212
214 http://www.adelton.com/perl/DBD-XBase/
215
217 (c) 1998--2013 Jan Pazdziora.
218
220 XBase(3), XBase::FAQ(3)
221
222
223
224perl v5.36.0 2022-07-22 XBase::Index(3)