00001
package com.quadcap.sql;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
import java.io.BufferedOutputStream;
00042
import java.io.Externalizable;
00043
import java.io.IOException;
00044
import java.io.ObjectInput;
00045
import java.io.ObjectOutput;
00046
import java.io.OutputStream;
00047
00048
import java.sql.SQLException;
00049
00050
import com.quadcap.sql.io.ObjectInputStream;
00051
import com.quadcap.sql.io.ObjectOutputStream;
00052
import com.quadcap.sql.io.Extern;
00053
00054
import com.quadcap.sql.file.BlockAccess;
00055
import com.quadcap.sql.file.BlockFile;
00056
import com.quadcap.sql.file.ByteArrayRandomAccess;
00057
import com.quadcap.sql.file.Datafile;
00058
import com.quadcap.sql.file.Log;
00059
import com.quadcap.sql.file.PageManager;
00060
import com.quadcap.sql.file.SubPageManager;
00061
00062
import com.quadcap.sql.types.Value;
00063
import com.quadcap.sql.types.ValueBlob;
00064
00065
import com.quadcap.util.Debug;
00066
import com.quadcap.util.Util;
00067
00068
00069
00070
00071
00072
00073 public class InsertRow extends LogStep implements Externalizable {
00074
00075 transient Table table;
00076 transient Row row = null;
00077
00078 byte[]
rowBytes;
00079 String
tableName = null;
00080 long rowId = 0;
00081
00082 public InsertRow() {}
00083
00084 public InsertRow(
Session session,
Table table,
Row row) {
00085 super(session);
00086
this.table = table;
00087
this.row = row;
00088
this.tableName = table.
getName();
00089 }
00090
00091 public long getRowId() {
return rowId; }
00092
00093 Table getTable(
Database db)
throws IOException {
00094
if (
table == null) {
00095
table = (
Table)db.getRelation(
tableName);
00096
if (
table == null) {
00097
throw new IOException(
"Table not found: " +
tableName);
00098 }
00099 }
00100
return table;
00101 }
00102
00103
00104
00105
00106 final void getRow(
Datafile db)
throws IOException, SQLException {
00107
if (
row == null) {
00108
LazyRow lrow =
new LazyRow(
table.
getColumnCount());
00109 lrow.
reset(
rowBytes, db);
00110
row = lrow;
00111 }
00112 }
00113
00114 public void redo(
Session session)
throws IOException, SQLException {
00115
Database db = session.getDatabase();
00116
BlockFile file = db.getFile();
00117
if (session.getConnection().inRecovery()) {
00118
Log log = session.getLog();
00119 getTable(db);
00120
00121
00122
if (
table.
hasBlobs()) {
00123
boolean anyChanged =
false;
00124 getRow(db);
00125
for (
int i = 1; i <=
row.
size(); i++) {
00126
Value v =
row.
item(i);
00127
if (v instanceof
ValueBlob) {
00128
ValueBlob vb = (
ValueBlob)v;
00129
long blk = vb.
getPermBlock();
00130
long blk2 = log.
getRowMap(blk);
00131
if (blk != blk2) {
00132 vb.
setPermBlock(blk2);
00133 anyChanged =
true;
00134 }
00135 }
00136 }
00137
if (anyChanged) {
00138
row.
set(1,
row.
item(1));
00139
this.rowBytes =
LazyRow.writeRow(session,
table,
row);
00140 }
00141 }
00142
long oldRowId =
rowId;
00143 rowId = file.
putBytes(
rowBytes);
00144
if (oldRowId != 0) log.
putRowMap(oldRowId, rowId);
00145 }
00146 session.incrUpdateCount();
00147 }
00148
00149 public void undo(
Session session)
throws IOException, SQLException {
00150
Database db = session.getDatabase();
00151
Log log = session.getLog();
00152
BlockFile file = db.getFile();
00153 getTable(db);
00154
00155
long actualRowId = log.
getRowMap(
rowId);
00156 log.
removeRowMap(
rowId);
00157
if (actualRowId != 0) db.
removeRow(actualRowId);
00158
00159 session.decrUpdateCount();
00160 }
00161
00162
00163
00164
00165 public void prepare(
Session session)
throws IOException, SQLException {
00166
Database db = session.getDatabase();
00167
if (db.
inMemory()) {
00168
this.rowId = db.
putRow(session, db.getFile(), getTable(db),
row);
00169 }
else {
00170
BlockFile file = db.getFile();
00171
this.rowBytes =
LazyRow.writeRow(session,
table,
row);
00172
this.rowId = file.
putBytes(
rowBytes);
00173 }
00174 }
00175
00176 public void readExternal(ObjectInput in)
00177
throws IOException, ClassNotFoundException
00178 {
00179 super.readExternal(in);
00180
rowId = in.readLong();
00181
tableName = (String)in.readObject();
00182
int size = in.readInt();
00183
this.rowBytes =
new byte[size];
00184 in.read(
rowBytes);
00185 }
00186
00187 public void writeExternal(ObjectOutput out)
throws IOException {
00188 super.writeExternal(out);
00189 out.writeLong(
rowId);
00190 out.writeObject(
tableName);
00191 out.writeInt(
rowBytes.length);
00192 out.write(
rowBytes);
00193 }
00194
00195
00196 public String
toString() {
00197 StringBuffer sb =
new StringBuffer(super.toString());
00198 sb.append(
" InsertRow(");
00199 sb.append(
tableName);
00200 sb.append(
',');
00201 sb.append(
SubPageManager.toString(
rowId));
00202
if (!
Trace.bit(3)) {
00203 sb.append(
',');
00204 sb.append(
Util.hexBytes(
rowBytes));
00205 }
00206 sb.append(
')');
00207
return sb.toString();
00208 }
00209
00210
00211 static Extern
extern;
00212 public void setExtern(Extern
extern) {
InsertRow.extern =
extern; }
00213 public Extern
getExtern() {
return extern; }
00214 }