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