View Javadoc

1   package org.kuali.common.impex.data.impl.mysql;
2   
3   import java.io.BufferedReader;
4   import java.io.IOException;
5   import java.text.SimpleDateFormat;
6   import java.util.ArrayList;
7   import java.util.Collections;
8   import java.util.List;
9   
10  import org.apache.commons.lang3.StringUtils;
11  import org.kuali.common.impex.data.MpxHeaderData;
12  import org.kuali.common.impex.data.impl.AbstractSqlProducer;
13  import org.kuali.common.impex.data.impl.DataBean;
14  import org.kuali.common.impex.data.impl.MpxParser;
15  import org.kuali.common.impex.model.Column;
16  import org.kuali.common.impex.model.Table;
17  import org.kuali.common.util.CollectionUtils;
18  
19  public class MySqlProducer extends AbstractSqlProducer {
20  
21      public static final String SUPPORTED_VENDOR = "mysql";
22  
23      private static final String BATCH_SEPARATOR = ",";
24      private static final String ARG_LIST_START = "(";
25      private static final String ARG_LIST_END = ")";
26      private static final String SPACE = " ";
27  
28      private static final String DATE_VALUE_PREFIX = "STR_TO_DATE('";
29      public static final String DATE_VALUE_SUFFIX = "','%Y%m%d%H%i%s')";
30  
31      private static final String PREFIX_START = "INSERT INTO ";
32      private static final String PREFIX_END = " VALUES ";
33  
34      /**
35       * Read data lines from the .mpx file and combine them into batched up, INSERT INTO sql statements. Individual data lines are merged together into SQL statements 50 lines at a
36       * time or 50K in length whichever comes first.
37       */
38      @Override
39      public List<String> getSql(Table table, MpxHeaderData headerData, BufferedReader reader) throws IOException {
40  
41          // Extract the columns into a list
42          List<Column> columns = table.getColumns();
43  
44          // Setup some storage
45          StringBuilder sb = new StringBuilder();
46  
47          // INSERT INTO FOO (BAR1,BAR2) VALUES
48          sb.append(getPrefix(table, headerData));
49  
50          // Track rows processed
51          int rows = 0;
52  
53          // read the first line
54          String line = reader.readLine();
55  
56          // Iterate through the .mpx file
57          for (; ; ) {
58  
59              // We hit the end of the .mpx file
60              if (line == null) {
61                  break;
62              }
63  
64              List<DataBean> rowBeans = buildRowData(columns, MpxParser.parseMpxLine(line), headerData);
65  
66              if (rows != 0) {
67                  // Need to add a comma, unless this is the first set of values
68                  sb.append(BATCH_SEPARATOR);
69              }
70  
71              sb.append(buildBatchSql(rowBeans));
72  
73              // increment our counters
74              rows++;
75  
76              // Have we exceeded any of our limits?
77              if (batchLimitReached(rows, sb.length())) {
78                  break;
79              }
80  
81              // read the next line and start the loop over
82              line = reader.readLine();
83          }
84  
85          // return null to indicate no rows were processed
86          if (rows == 0) {
87              return null;
88          } else {
89              return Collections.singletonList(sb.toString());
90          }
91      }
92  
93      protected String buildBatchSql(List<DataBean> rowBeans) {
94          StringBuilder batchBuilder = new StringBuilder();
95          SimpleDateFormat sqlDateFormatter = new SimpleDateFormat(OUTPUT_DATE_FORMAT);
96          List<String> sqlValues = new ArrayList<String>(rowBeans.size());
97          for (DataBean d : rowBeans) {
98              sqlValues.add(getSqlValue(d, sqlDateFormatter));
99          }
100         batchBuilder.append(ARG_LIST_START);
101         batchBuilder.append(CollectionUtils.getCSV(sqlValues));
102         batchBuilder.append(ARG_LIST_END);
103         return batchBuilder.toString();
104     }
105 
106     protected String getSqlValue(DataBean data, SimpleDateFormat dateFormat) {
107         StringBuilder result = new StringBuilder();
108 
109         if (data.getDateValue() != null) {
110             result.append(DATE_VALUE_PREFIX);
111             result.append(dateFormat.format(data.getDateValue()));
112             result.append(DATE_VALUE_SUFFIX);
113         } else {
114             result.append(data.getValue());
115         }
116 
117         return result.toString();
118     }
119 
120     // INSERT INTO FOO (BAR1,BAR2) VALUES
121     protected String getPrefix(Table table, MpxHeaderData headerData) {
122         String columnNamesCSV = CollectionUtils.getCSV(headerData.getColumnNames());
123         StringBuilder sb = new StringBuilder();
124         sb.append(PREFIX_START).append(table.getName()).append(SPACE);
125         sb.append(ARG_LIST_START).append(columnNamesCSV).append(ARG_LIST_END);
126         sb.append(PREFIX_END);
127         return sb.toString();
128     }
129 
130     @Override
131     protected String getEscapedValue(Column column, String token) {
132         String escaped1 = StringUtils.replace(token, "\\", "\\\\");
133         String escaped2 = StringUtils.replace(escaped1, "'", "\\'");
134         String escaped3 = StringUtils.replace(escaped2, "\n", "\\n");
135         return "'" + escaped3 + "'";
136     }
137 }