Bug fixes. Field prefix used in queries.
[idzebra-moved-to-github.git] / index / extract.c
1 /*
2  * Copyright (C) 1994-1995, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: extract.c,v $
7  * Revision 1.11  1995-09-28 12:10:31  adam
8  * Bug fixes. Field prefix used in queries.
9  *
10  * Revision 1.10  1995/09/28  09:19:41  adam
11  * xfree/xmalloc used everywhere.
12  * Extract/retrieve method seems to work for text records.
13  *
14  * Revision 1.9  1995/09/27  12:22:28  adam
15  * More work on extract in record control.
16  * Field name is not in isam keys but in prefix in dictionary words.
17  *
18  * Revision 1.8  1995/09/14  07:48:22  adam
19  * Record control management.
20  *
21  * Revision 1.7  1995/09/11  13:09:32  adam
22  * More work on relevance feedback.
23  *
24  * Revision 1.6  1995/09/08  14:52:27  adam
25  * Minor changes. Dictionary is lower case now.
26  *
27  * Revision 1.5  1995/09/06  16:11:16  adam
28  * Option: only one word key per file.
29  *
30  * Revision 1.4  1995/09/05  15:28:39  adam
31  * More work on search engine.
32  *
33  * Revision 1.3  1995/09/04  12:33:41  adam
34  * Various cleanup. YAZ util used instead.
35  *
36  * Revision 1.2  1995/09/04  09:10:34  adam
37  * More work on index add/del/update.
38  * Merge sort implemented.
39  * Initial work on z39 server.
40  *
41  * Revision 1.1  1995/09/01  14:06:35  adam
42  * Split of work into more files.
43  *
44  */
45 #include <stdio.h>
46 #include <assert.h>
47 #include <unistd.h>
48 #include <fcntl.h>
49 #include <ctype.h>
50
51 #include <alexutil.h>
52 #include <recctrl.h>
53 #include "index.h"
54
55 static Dict file_idx;
56 static SYSNO sysno_next;
57 static int key_fd = -1;
58 static int sys_idx_fd = -1;
59 static char *key_buf;
60 static int key_offset, key_buf_size;
61 static int key_cmd;
62 static int key_sysno;
63
64 void key_open (const char *fname)
65 {
66     void *file_key;
67     if (key_fd != -1)
68         return;
69     if ((key_fd = open (fname, O_RDWR|O_CREAT, 0666)) == -1)
70     {
71         logf (LOG_FATAL|LOG_ERRNO, "open %s", fname);
72         exit (1);
73     }
74     logf (LOG_DEBUG, "key_open of %s", fname);
75     key_buf_size = 49100;
76     key_buf = xmalloc (key_buf_size);
77     key_offset = 0;
78     if (!(file_idx = dict_open (FNAME_FILE_DICT, 40, 1)))
79     {
80         logf (LOG_FATAL, "dict_open fail of %s", "fileidx");
81         exit (1);
82     }
83     file_key = dict_lookup (file_idx, ".");
84     if (file_key)
85         memcpy (&sysno_next, (char*)file_key+1, sizeof(sysno_next));
86     else
87         sysno_next = 1;
88     if ((sys_idx_fd = open (FNAME_SYS_IDX, O_RDWR|O_CREAT, 0666)) == -1)
89     {
90         logf (LOG_FATAL|LOG_ERRNO, "open %s", FNAME_SYS_IDX);
91         exit (1);
92     }
93 }
94
95 int key_close (void)
96 {
97     if (key_fd == -1)
98     {
99         logf (LOG_DEBUG, "key_close - but no file");
100         return 0;
101     }
102     close (key_fd);
103     close (sys_idx_fd);
104     dict_insert (file_idx, ".", sizeof(sysno_next), &sysno_next);
105     dict_close (file_idx);
106     key_fd = -1;
107     xfree (key_buf);
108     return 1;
109 }
110
111 void wordFlush (int sysno)
112 {
113     size_t i = 0;
114     int w;
115
116     if (key_fd == -1)
117         return; 
118     while (i < key_offset)
119     {
120         w = write (key_fd, key_buf + i, key_offset - i);
121         if (w == -1)
122         {
123             logf (LOG_FATAL|LOG_ERRNO, "Write key fail");
124             exit (1);
125         }
126         i += w;
127     }
128     key_offset = 0;
129 }
130
131 static void wordInit (RecWord *p)
132 {
133     p->attrSet = 1;
134     p->attrUse = 1016;
135     p->which = Word_String;
136 }
137
138 static void wordAdd (const RecWord *p)
139 {
140     struct it_key key;
141     char x;
142     size_t i;
143
144     if (key_offset + 1000 > key_buf_size)
145     {
146         char *new_key_buf;
147
148         key_buf_size *= 2;
149         new_key_buf = xmalloc (2*key_buf_size);
150         memcpy (new_key_buf, key_buf, key_offset);
151         xfree (key_buf);
152         key_buf = new_key_buf;
153     }
154     key_offset += index_word_prefix (key_buf + key_offset,
155                                      p->attrSet, p->attrUse);
156     switch (p->which)
157     {
158     case Word_String:
159         for (i = 0; p->u.string[i]; i++)
160             key_buf[key_offset++] = index_char_cvt (p->u.string[i]);
161         key_buf[key_offset++] = '\0';
162         break;
163     default:
164         return ;
165     }
166     x = (key_cmd == 'a') ? 1 : 0;
167     memcpy (key_buf + key_offset, &x, 1);
168     key_offset++;
169
170     key.sysno = key_sysno;
171     key.seqno = p->seqno;
172     memcpy (key_buf + key_offset, &key, sizeof(key));
173     key_offset += sizeof(key);
174 }
175
176 void file_extract (int cmd, const char *fname, const char *kname)
177 {
178     int i;
179     char ext[128];
180     SYSNO sysno;
181     char ext_res[128];
182     const char *file_type;
183     void *file_info;
184     FILE *inf;
185     struct recExtractCtrl extractCtrl;
186     RecType rt;
187
188     logf (LOG_DEBUG, "%c %s k=%s", cmd, fname, kname);
189     for (i = strlen(fname); --i >= 0; )
190         if (fname[i] == '/')
191         {
192             strcpy (ext, "");
193             break;
194         }
195         else if (fname[i] == '.')
196         {
197             strcpy (ext, fname+i+1);
198             break;
199         }
200     sprintf (ext_res, "fileExtension.%s", ext);
201     if (!(file_type = res_get (common_resource, ext_res)))
202         return;
203     if (!(rt = recType_byName (file_type)))
204         return;
205     file_info = dict_lookup (file_idx, kname);
206     if (!file_info)
207     {
208         sysno = sysno_next++;
209         dict_insert (file_idx, kname, sizeof(sysno), &sysno);
210         lseek (sys_idx_fd, sysno * SYS_IDX_ENTRY_LEN, SEEK_SET);
211         write (sys_idx_fd, file_type, strlen (file_type)+1);
212         write (sys_idx_fd, kname, strlen(kname)+1);
213     }
214     else
215         memcpy (&sysno, (char*) file_info+1, sizeof(sysno));
216
217     if (!(inf = fopen (fname, "r")))
218     {
219         logf (LOG_WARN|LOG_ERRNO, "open %s", fname);
220         return;
221     }
222     extractCtrl.inf = inf;
223     extractCtrl.subType = "";
224     extractCtrl.init = wordInit;
225     extractCtrl.add = wordAdd;
226     key_sysno = sysno;
227     key_cmd = cmd;
228     (*rt->extract)(&extractCtrl);
229     fclose (inf);
230     wordFlush (sysno);
231 }
232
233