<commit_before>package gq.baijie.onetab.internal.storage;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

import javax.annotation.Nonnull;

import gq.baijie.onetab.ProgressOrResult;
import gq.baijie.onetab.Results;
import gq.baijie.onetab.WebArchive;
import rx.Observable;

import static gq.baijie.onetab.StorageService.TYPE_SQLITE;

public class SqliteStorageSpi implements StorageServiceSpi {

  private static final String DATABASE_URL = "jdbc:sqlite:sample.db";

  @Nonnull
  @Override
  public String getType() {
    return TYPE_SQLITE;
  }

  @Nonnull
  @Override
  public Observable<ProgressOrResult<Void, Throwable>> save(@Nonnull WebArchive webArchive) {
    return Observable.create(subscriber -> {
      if(subscriber.isUnsubscribed()) {
        return;
      }
      doSave(webArchive);
      if (subscriber.isUnsubscribed()) {
        return;
      }
      subscriber.onNext(ProgressOrResult.result(Results.<Void, Throwable>succeed(null)));
    });
  }

  @Nonnull
  @Override
  public Observable<ProgressOrResult<WebArchive, Throwable>> retrieve() {
    return null;
  }

  private void doSave(@Nonnull WebArchive webArchive) {
//    final Connection connection = DriverManager.getConnection(DATABASE_URL);
    try(final Connection connection = DriverManager.getConnection(DATABASE_URL);
        final Statement statement = connection.createStatement()) {
//      connection.setAutoCommit(false);
      statement.executeUpdate("drop table if exists section");
      statement.executeUpdate("create table section (id integer PRIMARY KEY)");
      statement.executeUpdate("drop table if exists item");
      statement.executeUpdate("create table item (id integer PRIMARY KEY, section_id integer, link string, title string)");;
      for(WebArchive.Section section:webArchive.getSections()) {
        saveSection(section, connection);
      }
//      connection.commit();
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }

  private void saveSection(@Nonnull WebArchive.Section section, @Nonnull Connection connection)
      throws SQLException {
    try(final PreparedStatement statement = connection.prepareStatement(
//        "insert into section () values ()", Statement.RETURN_GENERATED_KEYS)) {
        "insert into section DEFAULT VALUES", Statement.RETURN_GENERATED_KEYS)) {
      statement.executeUpdate();
      final ResultSet generatedKeys = statement.getGeneratedKeys();
      if (generatedKeys.next()) {
        final long sectionId = generatedKeys.getLong(1);
        saveItems(sectionId, section.getItems(), connection);
      } else {
        throw new IllegalStateException("no generated primary key");
      }
    }
  }

  private void saveItems(
      long sectionId, @Nonnull List<WebArchive.Item> items, @Nonnull Connection connection)
      throws SQLException {<commit_msg>use transaction<commit_after>package gq.baijie.onetab.internal.storage;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

import javax.annotation.Nonnull;

import gq.baijie.onetab.ProgressOrResult;
import gq.baijie.onetab.Results;
import gq.baijie.onetab.WebArchive;
import rx.Observable;

import static gq.baijie.onetab.StorageService.TYPE_SQLITE;

public class SqliteStorageSpi implements StorageServiceSpi {

  private static final String DATABASE_URL = "jdbc:sqlite:sample.db";

  @Nonnull
  @Override
  public String getType() {
    return TYPE_SQLITE;
  }

  @Nonnull
  @Override
  public Observable<ProgressOrResult<Void, Throwable>> save(@Nonnull WebArchive webArchive) {
    return Observable.create(subscriber -> {
      if(subscriber.isUnsubscribed()) {
        return;
      }
      doSave(webArchive);
      if (subscriber.isUnsubscribed()) {
        return;
      }
      subscriber.onNext(ProgressOrResult.result(Results.<Void, Throwable>succeed(null)));
    });
  }

  @Nonnull
  @Override
  public Observable<ProgressOrResult<WebArchive, Throwable>> retrieve() {
    return null;
  }

  private void doSave(@Nonnull WebArchive webArchive) {
//    final Connection connection = DriverManager.getConnection(DATABASE_URL);
    try(final Connection connection = DriverManager.getConnection(DATABASE_URL);
        final Statement statement = connection.createStatement()) {
      connection.setAutoCommit(false);

      statement.executeUpdate("drop table if exists section");
      statement.executeUpdate("create table section (id integer PRIMARY KEY)");
      statement.executeUpdate("drop table if exists item");
      statement.executeUpdate("create table item (id integer PRIMARY KEY, section_id integer, link string, title string)");;
      for(WebArchive.Section section:webArchive.getSections()) {
        saveSection(section, connection);
      }

      connection.commit();
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }

  private void saveSection(@Nonnull WebArchive.Section section, @Nonnull Connection connection)
      throws SQLException {
    try(final PreparedStatement statement = connection.prepareStatement(
//        "insert into section () values ()", Statement.RETURN_GENERATED_KEYS)) {
        "insert into section DEFAULT VALUES", Statement.RETURN_GENERATED_KEYS)) {
      statement.executeUpdate();
      final ResultSet generatedKeys = statement.getGeneratedKeys();
      if (generatedKeys.next()) {
        final long sectionId = generatedKeys.getLong(1);
        saveItems(sectionId, section.getItems(), connection);
      } else {
        throw new IllegalStateException("no generated primary key");
      }
    }
  }

  private void saveItems(
      long sectionId, @Nonnull List<WebArchive.Item> items, @Nonnull Connection connection)
      throws SQLException {
{'fraction_non_alphanumeric': 0.09959758551307847, 'fraction_numerical': 0.00033534540576794097, 'mean_word_length': 3.9791318864774623, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '20955', 'n_tokens_mistral': 1682, 'n_tokens_neox': 1631, 'n_words': 379}