1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2006, 2009-2011 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 #include "data/dataset-writer.h"
23 #include "data/case.h"
24 #include "data/case-map.h"
25 #include "data/casereader.h"
26 #include "data/casewriter-provider.h"
27 #include "data/casewriter.h"
28 #include "data/dataset.h"
29 #include "data/dictionary.h"
30 #include "data/file-handle-def.h"
31 #include "data/variable.h"
32 #include "libpspp/compiler.h"
33 #include "libpspp/taint.h"
35 #include "gl/xalloc.h"
37 #define N_(msgid) (msgid)
39 /* A dataset file writer. */
42 struct dataset
*ds
; /* Underlying dataset. */
43 struct fh_lock
*lock
; /* Exclusive access to file handle. */
44 struct dictionary
*dict
; /* Dictionary for subwriter. */
45 struct case_map
*compactor
; /* Compacts into dictionary. */
46 struct casewriter
*subwriter
; /* Data output. */
49 static const struct casewriter_class dataset_writer_casewriter_class
;
51 /* Opens FH, which must have referent type FH_REF_DATASET, and
52 returns a dataset_writer for it, or a null pointer on
53 failure. Cases stored in the dataset_writer will be expected
54 to be drawn from DICTIONARY. */
56 dataset_writer_open (struct file_handle
*fh
,
57 const struct dictionary
*dictionary
)
59 struct dataset_writer
*writer
;
60 struct casewriter
*casewriter
;
63 /* Get exclusive write access to handle. */
64 /* TRANSLATORS: this fragment will be interpolated into
65 messages in fh_lock() that identify types of files. */
66 lock
= fh_lock (fh
, FH_REF_DATASET
, N_("dataset"), FH_ACC_WRITE
, true);
71 writer
= xmalloc (sizeof *writer
);
73 writer
->ds
= fh_get_dataset (fh
);
75 writer
->dict
= dict_clone (dictionary
);
76 dict_delete_scratch_vars (writer
->dict
);
77 if (dict_count_values (writer
->dict
, 0)
78 < dict_get_next_value_idx (writer
->dict
))
80 writer
->compactor
= case_map_to_compact_dict (writer
->dict
, 0);
81 dict_compact_values (writer
->dict
);
84 writer
->compactor
= NULL
;
85 writer
->subwriter
= autopaging_writer_create (dict_get_proto (writer
->dict
));
87 casewriter
= casewriter_create (dict_get_proto (writer
->dict
),
88 &dataset_writer_casewriter_class
, writer
);
89 taint_propagate (casewriter_get_taint (writer
->subwriter
),
90 casewriter_get_taint (casewriter
));
94 /* Writes case C to WRITER. */
96 dataset_writer_casewriter_write (struct casewriter
*w UNUSED
, void *writer_
,
99 struct dataset_writer
*writer
= writer_
;
100 casewriter_write (writer
->subwriter
,
101 case_map_execute (writer
->compactor
, c
));
106 dataset_writer_casewriter_destroy (struct casewriter
*w UNUSED
, void *writer_
)
108 struct dataset_writer
*writer
= writer_
;
109 struct casereader
*reader
= casewriter_make_reader (writer
->subwriter
);
110 if (!casereader_error (reader
))
112 dataset_set_dict (writer
->ds
, writer
->dict
);
113 dataset_set_source (writer
->ds
, reader
);
117 casereader_destroy (reader
);
118 dict_destroy (writer
->dict
);
121 fh_unlock (writer
->lock
);
125 static const struct casewriter_class dataset_writer_casewriter_class
=
127 dataset_writer_casewriter_write
,
128 dataset_writer_casewriter_destroy
,