Write a Java program that reads data from a CSV file and stores it in an SQLite database. The program should support command line arguments for the input CSV file path, output SQLite database file path, and table name. It should also handle duplicate entries by updating existing records with new data.
PLAINFORMAT
import com.opencsv.CSVReader;
import com.opencsv.exceptions.CsvException;

import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;

public class CsvToSqlite {

    public static void main(String[] args) {
        if (args.length != 3) {
            System.out.println("Usage: java CsvToSqlite input.csv output.db table_name");
            return;
        }

        String csvFile = args[0];
        String dbFile = args[1];
        String tableName = args[2];

        try {
            List<String[]> records = readCsv(csvFile);
            storeInDatabase(records, dbFile, tableName);
        } catch (IOException | CsvException | SQLException e) {
            System.err.println("Error: " + e.getMessage());
        }
    }

    private static List<String[]> readCsv(String csvFile) throws IOException, CsvException {
        try (CSVReader reader = new CSVReader(new FileReader(csvFile))) {
            return reader.readAll();
        }
    }

    private static void storeInDatabase(List<String[]> records, String dbFile, String tableName) throws SQLException {
        if (records.isEmpty()) {
            System.out.println("No data found in the CSV file.");
            return;
        }

        String[] headers = records.get(0);
        records.remove(0);

        String url = "jdbc:sqlite:" + dbFile;

        try (Connection conn = DriverManager.getConnection(url)) {
            createTable(conn, tableName, headers);
            insertOrUpdateRecords(conn, tableName, headers, records);
        }
    }

    private static void createTable(Connection conn, String tableName, String[] headers) throws SQLException {
        StringBuilder sb = new StringBuilder();
        sb.append("CREATE TABLE IF NOT EXISTS ").append(tableName).append(" (");

        for (int i = 0; i < headers.length; i++) {
            sb.append(headers[i]).append(" TEXT");
            if (i < headers.length - 1) {
                sb.append(", ");
            }
        }

        sb.append(");");

        try (PreparedStatement stmt = conn.prepareStatement(sb.toString())) {
            stmt.execute();
        }
    }

    private static void insertOrUpdateRecords(Connection conn, String tableName, String[] headers, List<String[]> records) throws SQLException {
        StringBuilder sb = new StringBuilder();
        sb.append("INSERT OR REPLACE INTO ").append(tableName).append(" (");

        for (int i = 0; i < headers.length; i++) {
            sb.append(headers[i]);
            if (i < headers.length - 1) {
                sb.append(", ");
            }
        }

        sb.append(") VALUES (");

        for (int i = 0; i < headers.length; i++) {
            sb.append("?");
            if (i < headers.length - 1) {
                sb.append(", ");
            }
        }

        sb.append(");");

        try (PreparedStatement stmt = conn.prepareStatement(sb.toString())) {
            for (String[] record : records) {
                for (int i = 0; i < record.length; i++) {
                    stmt.setString(i + 1, record[i]);
                }
                stmt.addBatch();
            }
            stmt.executeBatch();
        }
    }
}