@@ -41,44 +41,66 @@ private long getAccountId(Connection con, String subjectType, String subjectKey,
4141 private static Date toSqlDate (LocalDate d ) { return Date .valueOf (d ); }
4242 private Date todayLocal () { return toSqlDate (LocalDate .now (zoneId )); }
4343
44+ // 1) subjects を upsert して subjectId を返す(nameは上書き)
45+ public long ensureSubject (Connection con , String subjectType , String subjectKey , String name ) throws SQLException {
46+ try (PreparedStatement ps = con .prepareStatement (
47+ "INSERT INTO " + Names .t ("subjects" ) + " (type, subject_key, name) VALUES (?, ?, ?) " +
48+ "ON DUPLICATE KEY UPDATE name=VALUES(name)" )) {
49+ ps .setString (1 , subjectType );
50+ ps .setString (2 , subjectKey );
51+ ps .setString (3 , name );
52+ ps .executeUpdate ();
53+ }
54+ try (PreparedStatement ps = con .prepareStatement (
55+ "SELECT id FROM " + Names .t ("subjects" ) + " WHERE type=? AND subject_key=?" )) {
56+ ps .setString (1 , subjectType );
57+ ps .setString (2 , subjectKey );
58+ try (ResultSet rs = ps .executeQuery ()) {
59+ if (!rs .next ()) throw new IllegalStateException ("Subject not found after upsert" );
60+ return rs .getLong (1 );
61+ }
62+ }
63+ }
64+
65+ // 2) accounts を upsert して accountId を返す(scopeユニーク)
66+ public long ensureAccountForScope (Connection con , long subjectId , String scope ) throws SQLException {
67+ try (PreparedStatement ps = con .prepareStatement (
68+ "INSERT INTO " + Names .t ("accounts" ) + " (subject_id, scope) VALUES (?, ?) " +
69+ "ON DUPLICATE KEY UPDATE scope=scope" )) {
70+ ps .setLong (1 , subjectId );
71+ ps .setString (2 , scope );
72+ ps .executeUpdate ();
73+ }
74+ try (PreparedStatement ps = con .prepareStatement (
75+ "SELECT id FROM " + Names .t ("accounts" ) + " WHERE subject_id=? AND scope=?" )) {
76+ ps .setLong (1 , subjectId );
77+ ps .setString (2 , scope );
78+ try (ResultSet rs = ps .executeQuery ()) {
79+ if (!rs .next ()) throw new IllegalStateException ("Account not found after upsert" );
80+ return rs .getLong (1 );
81+ }
82+ }
83+ }
84+
85+ // 3) account_balances を確保(INSERT IGNORE)
86+ public void ensureBalances (Connection con , long accountId ) throws SQLException {
87+ try (PreparedStatement ps = con .prepareStatement (
88+ "INSERT IGNORE INTO " + Names .t ("account_balances" ) + " (account_id, now_point, total_point) " +
89+ "VALUES (?, 0, 0)" )) {
90+ ps .setLong (1 , accountId );
91+ ps .executeUpdate ();
92+ }
93+ }
94+
95+ // 4) 互換レイヤ(既存の ensureAccount を “まとめ役” に)
4496 @ Override
4597 public void ensureAccount (String subjectType , String subjectKey , String scope , String name ) {
4698 try (Connection con = ds .getConnection ()) {
4799 con .setAutoCommit (false );
48100 try {
49- // subjects
50- PreparedStatement ps1 = con .prepareStatement (
51- "INSERT INTO " + Names .t ("subjects" ) + " (type, subject_key, name) VALUES(?, ?, ?) " +
52- "ON DUPLICATE KEY UPDATE name=VALUES(name)" );
53- ps1 .setString (1 , subjectType );
54- ps1 .setString (2 , subjectKey );
55- ps1 .setString (3 , name );
56- ps1 .executeUpdate ();
57- ps1 .close ();
58-
59- // accounts
60- PreparedStatement ps2 = con .prepareStatement (
61- "INSERT INTO " + Names .t ("accounts" ) + " (subject_id, scope) " +
62- "SELECT id, ? FROM " + Names .t ("subjects" ) + " WHERE type=? AND subject_key=? " +
63- "ON DUPLICATE KEY UPDATE scope=scope" );
64- ps2 .setString (1 , scope );
65- ps2 .setString (2 , subjectType );
66- ps2 .setString (3 , subjectKey );
67- ps2 .executeUpdate ();
68- ps2 .close ();
69-
70- // account_balances
71- PreparedStatement ps3 = con .prepareStatement (
72- "INSERT IGNORE INTO " + Names .t ("account_balances" ) + " (account_id, now_point, total_point) " +
73- "SELECT a.id, 0, 0 FROM " + Names .t ("accounts" ) + " a " +
74- "JOIN " + Names .t ("subjects" ) + " s ON s.id=a.subject_id " +
75- "WHERE s.type=? AND s.subject_key=? AND a.scope=?" );
76- ps3 .setString (1 , subjectType );
77- ps3 .setString (2 , subjectKey );
78- ps3 .setString (3 , scope );
79- ps3 .executeUpdate ();
80- ps3 .close ();
81-
101+ long subjectId = ensureSubject (con , subjectType , subjectKey , name );
102+ long accountId = ensureAccountForScope (con , subjectId , scope );
103+ ensureBalances (con , accountId );
82104 con .commit ();
83105 } catch (SQLException e ) {
84106 con .rollback ();
@@ -90,7 +112,6 @@ public void ensureAccount(String subjectType, String subjectKey, String scope, S
90112 throw new RuntimeException (e );
91113 }
92114 }
93-
94115 @ Override
95116 public long getNowPoint (String subjectType , String subjectKey , String scope ) {
96117 try (Connection con = ds .getConnection ();
0 commit comments