1 /*
2  * Copyright (c) 2016,2017,2019 Daichi GOTO
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #define VERSION "20190812"
29 #define CMDNAME "gyo_delete"
30 #define ALIAS "gyodel row_delete"
31 
32 #include <limits.h>
33 #ifdef __linux__
34 #include <db_185.h>
35 #else
36 #include <db.h>
37 #endif
38 
39 #include "ttt.h"
40 
41 void simple_comparison(int, char**);
42 
43 #define TGT_RETU_PROCESS(BUF,BUFLEN,INDEX) \
44 	fp_no_output = 1; \
45 	b_key.data = BUF; \
46 	b_key.size = strlen(b_key.data) + 1; \
47 	b_val.data = "1"; \
48 	b_val.size = 2; \
49 	btrees[i]->put(btrees[i], &b_key, &b_val, 0);
50 
51 #define NOTGT_RETU_PROCESS(BUF,BUFLEN,INDEX) \
52 	fp_no_output = 1; \
53 
54 #define END_OF_LINE_RETU_PROCESS
55 
56 #define TGT_GYO_PROCESS(GYO_BUFFER,NF) \
57 	nf = NF; \
58 	if (FLAG_1 && first_line) { \
59 		first_line = 0; \
60 		goto gyo_match; \
61 	} \
62 	if (!FLAG_o) { \
63 		/* AND CONDITION */ \
64 		for (int i = 1; i <= match_count; i++) { \
65 			if (0 == NF) \
66 				goto gyo_match; \
67 			if (NF < R_ARGV[i]) \
68 				goto gyo_not_match; \
69 			if ('!' != R_ARGV_DELIM[i] && \
70 			    '@' == GYO_BUFFER[R_ARGV[i]][0] && \
71 			   '\0' == GYO_BUFFER[R_ARGV[i]][1] && \
72 			   !('@' == R_ARGV_ARG1[i][0] && \
73 			    '\0' == R_ARGV_ARG1[i][1])) \
74 				goto gyo_not_match; \
75 			if (NULL != btrees[i]) { \
76 				b_key.data = GYO_BUFFER[R_ARGV[i]]; \
77 				b_key.size = strlen(b_key.data) + 1; \
78 				if (1 == btrees[i]->get(btrees[i], \
79 					&b_key, &b_val, 0)) \
80 					goto gyo_not_match; \
81 			} \
82 			else { \
83 				if (FLAG_N) { \
84 					errno = 0; \
85 					n1 = strtoll(GYO_BUFFER[R_ARGV[i]],\
86 						(char **)NULL, 10); \
87 					if (EINVAL == errno) \
88 						goto gyo_not_match; \
89 					cmpret = 0; \
90 					if (n1 > n2[i]) \
91 						cmpret = 1; \
92 					else if (n1 < n2[i]) \
93 						cmpret = -1; \
94 				} \
95 				else \
96 					cmpret = \
97 					strcmp(GYO_BUFFER[R_ARGV[i]], \
98 						R_ARGV_ARG1[i]); \
99 				switch (R_ARGV_DELIM[i]) { \
100 				case '>': \
101 					if (0 >= cmpret) \
102 						goto gyo_not_match; \
103 					break; \
104 				case '<': \
105 					if (0 <= cmpret) \
106 						goto gyo_not_match; \
107 					break; \
108 				case '!': \
109 					if (0 == cmpret) \
110 						goto gyo_not_match; \
111 					break; \
112 				default: \
113 					if (0 != cmpret) \
114 						goto gyo_not_match; \
115 					break; \
116 				} \
117 			} \
118 		} \
119 		goto gyo_match; \
120 	} \
121 	else { \
122 		/* OR CONDITION */ \
123 		for (int i = 1; i <= match_count; i++) { \
124 			if (0 == NF) \
125 				goto gyo_match; \
126 			if (NF < R_ARGV[i]) \
127 				goto gyo_not_match; \
128 			if ('!' != R_ARGV_DELIM[i] && \
129 			    '@' == GYO_BUFFER[R_ARGV[i]][0] && \
130 			   '\0' == GYO_BUFFER[R_ARGV[i]][1] && \
131 			   !('@' == R_ARGV_ARG1[i][0] && \
132 			    '\0' == R_ARGV_ARG1[i][1])) \
133 				continue; \
134 			if (NULL != btrees[i]) { \
135 				b_key.data = GYO_BUFFER[R_ARGV[i]]; \
136 				b_key.size = strlen(b_key.data) + 1; \
137 				if (0 == btrees[i]->get(btrees[i], \
138 					&b_key, &b_val, 0)) \
139 					goto gyo_match; \
140 			} \
141 			else { \
142 				if (FLAG_N) { \
143 					errno = 0; \
144 					n1 = strtoll(GYO_BUFFER[R_ARGV[i]],\
145 						(char **)NULL, 10); \
146 					if (EINVAL == errno) \
147 						continue; \
148 					cmpret = 0; \
149 					if (n1 > n2[i]) \
150 						cmpret = 1; \
151 					else if (n1 < n2[i]) \
152 						cmpret = -1; \
153 				} \
154 				else \
155 					cmpret = \
156 					strcmp(GYO_BUFFER[R_ARGV[i]], \
157 						R_ARGV_ARG1[i]); \
158 				switch (R_ARGV_DELIM[i]) { \
159 				case '>': \
160 					if (0 < cmpret) \
161 						goto gyo_match; \
162 					break; \
163 				case '<': \
164 					if (0 > cmpret) \
165 						goto gyo_match; \
166 					break; \
167 				case '!': \
168 					if (0 != cmpret) \
169 						goto gyo_match; \
170 					break; \
171 				default: \
172 					if (0 == cmpret) \
173 						goto gyo_match; \
174 					break; \
175 				} \
176 			} \
177 		} \
178 		goto gyo_not_match; \
179 	} \
180 gyo_not_match: \
181 	match_or_not = 0; \
182 	if (!FLAG_n) { \
183 		if (R_ARGC == match_count) { \
184 			for (int i = 1; i < NF; i++) \
185 				PRINT(GYO_BUFFER[i], " "); \
186 			PRINT(GYO_BUFFER[NF], "\n"); \
187 		} \
188 		else { \
189 			for (int i = match_count+1; i < R_ARGC; i++) \
190 				if (R_ARGV[i] > NF || \
191 					NULL == GYO_BUFFER[R_ARGV[i]]) { \
192 					PRINT("@", " "); \
193 				} \
194 				else { \
195 					PRINT(GYO_BUFFER[R_ARGV[i]], " "); \
196 				} \
197 			if (R_ARGV[R_ARGC] > NF || \
198 				NULL == GYO_BUFFER[R_ARGV[R_ARGC]]) { \
199 				PRINT("@", "\n"); \
200 			} \
201 			else { \
202 				PRINT(GYO_BUFFER[R_ARGV[R_ARGC]], "\n"); \
203 			} \
204 		} \
205 	} \
206 gyo_match:
207 
208 #define PRINT(TARGET,DELIMITER) \
209 	if ('@' == TARGET[0] && '\0' == TARGET[1]) { \
210 		printf("%s%s", val, DELIMITER); \
211 	} \
212 	else \
213 		printf("%s%s", TARGET, DELIMITER);
214