1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00
This commit is contained in:
gnosygnu
2015-07-12 21:10:02 -04:00
commit 794b5a232f
3099 changed files with 238212 additions and 0 deletions

View File

@@ -0,0 +1,100 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.fsdb.data; import gplx.*; import gplx.fsdb.*;
import gplx.core.primitives.*;
import gplx.dbs.*; import gplx.ios.*;
import gplx.dbs.engines.sqlite.*;
public class Fsd_bin_tbl implements RlsAble {
private final String tbl_name = "fsdb_bin"; private final Db_meta_fld_list flds = Db_meta_fld_list.new_();
private final String fld_owner_id, fld_owner_tid, fld_part_id, fld_data_url, fld_data;
private Db_conn conn; private Db_stmt stmt_insert, stmt_select; private Bry_bfr tmp_bfr;
private final Bool_obj_ref saved_in_parts = Bool_obj_ref.n_();
public Fsd_bin_tbl(Db_conn conn, boolean schema_is_1) {
this.conn = conn;
fld_owner_id = flds.Add_int_pkey ("bin_owner_id");
fld_owner_tid = flds.Add_byte ("bin_owner_tid");
fld_part_id = flds.Add_int ("bin_part_id");
fld_data_url = flds.Add_str ("bin_data_url", 255);
fld_data = flds.Add_bry ("bin_data"); // mediumblob
conn.Rls_reg(this);
}
public void Rls() {
stmt_insert = Db_stmt_.Rls(stmt_insert);
stmt_select = Db_stmt_.Rls(stmt_select);
}
public void Create_tbl() {conn.Ddl_create_tbl(Db_meta_tbl.new_(tbl_name, flds));}
public void Insert_bgn() {conn.Txn_bgn(); stmt_insert = conn.Stmt_insert(tbl_name, flds);}
public void Insert_commit() {conn.Txn_sav();}
public void Insert_end() {conn.Txn_end(); stmt_insert = Db_stmt_.Rls(stmt_insert);}
public void Insert_rdr(int id, byte tid, long bin_len, Io_stream_rdr bin_rdr) {
if (stmt_insert == null) {
stmt_insert = conn.Stmt_insert(tbl_name, flds);
tmp_bfr = Bry_bfr.reset_(Io_mgr.Len_kb);
}
byte[] bin_ary = null;
bin_ary = Io_stream_rdr_.Load_all_as_bry(tmp_bfr, bin_rdr);
stmt_insert.Clear()
.Val_int(fld_owner_id, id)
.Val_byte(fld_owner_tid, tid)
.Val_int(fld_part_id, Part_id_null)
.Val_str(fld_data_url, Data_url_null)
.Val_bry(fld_data, bin_ary)
.Exec_insert();
}
public Io_stream_rdr Select_as_rdr(int owner_id) {
byte[] rv = Select(owner_id, null);
return rv == null
? Io_stream_rdr_.Noop
: Io_stream_rdr_.mem_(rv);
}
public boolean Select_to_url(int owner_id, Io_url url) {
saved_in_parts.Val_n();
byte[] rv = Select(owner_id, url);
if (rv == null) return false;
if (saved_in_parts.Val_y()) return true;
Io_mgr.I.SaveFilBry(url, rv);
return true;
}
private byte[] Select(int owner_id, Io_url url) {
if (stmt_select == null) stmt_select = conn.Stmt_select(tbl_name, String_.Ary(fld_data), fld_owner_id);
Db_rdr rdr = stmt_select.Clear().Crt_int(fld_owner_id, owner_id).Exec_select__rls_manual();
try {
if (rdr.Move_next()) {
byte[] rv = null;
try {rv = rdr.Read_bry(fld_data);}
catch (Exception e) {
if ( Op_sys.Cur().Tid_is_drd()
&& url != null // called by Select_to_url
&& String_.Has(Err_.Message_lang(e), "get field slot from row") // get field slot from row 0 col 0 failed
) {
rdr.Save_bry_in_parts(url, tbl_name, fld_data, fld_owner_id, owner_id);
saved_in_parts.Val_y_();
}
}
return rv == null ? Bry_.Empty : rv; // NOTE: bug in v0.10.1 where .ogg would save as null; return Bry_.Empty instead, else java.io.ByteArrayInputStream would fail on null
}
else
return null;
}
finally {rdr.Rls();}
}
public static final byte Owner_tid_fil = 1, Owner_tid_thm = 2;
public static final int Bin_db_id_null = -1, Size_null = -1;
private static final int Part_id_null = -1;
private static final String Data_url_null = "";
}

View File

@@ -0,0 +1,27 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.fsdb.data; import gplx.*; import gplx.fsdb.*;
public class Fsd_dir_itm {
public Fsd_dir_itm(int dir_id, int owner, byte[] name) {this.dir_id = dir_id; this.owner = owner; this.name = name;}
public int Dir_id() {return dir_id;} private final int dir_id;
public int Owner() {return owner;} private final int owner;
public byte[] Name() {return name;} private final byte[] name;
public static final int Owner_root = 0;
public static final Fsd_dir_itm Null = null;
}

View File

@@ -0,0 +1,68 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.fsdb.data; import gplx.*; import gplx.fsdb.*;
import gplx.dbs.*;
public class Fsd_dir_tbl implements RlsAble {
private final String tbl_name = "fsdb_dir"; private final Db_meta_fld_list flds = Db_meta_fld_list.new_();
private final String fld_id, fld_owner_id, fld_name;
private final Db_conn conn; private Db_stmt stmt_insert, stmt_update, stmt_select_by_name;
public Fsd_dir_tbl(Db_conn conn, boolean schema_is_1) {
this.conn = conn;
this.fld_id = flds.Add_int_pkey ("dir_id");
this.fld_owner_id = flds.Add_int ("dir_owner_id");
this.fld_name = flds.Add_str ("dir_name", 255);
conn.Rls_reg(this);
}
public void Rls() {
stmt_insert = Db_stmt_.Rls(stmt_insert);
stmt_update = Db_stmt_.Rls(stmt_update);
stmt_select_by_name = Db_stmt_.Rls(stmt_select_by_name);
}
public void Create_tbl() {
conn.Ddl_create_tbl
( Db_meta_tbl.new_(tbl_name, flds
, Db_meta_idx.new_normal_by_tbl(tbl_name, "name", fld_name, fld_owner_id, fld_id)));
}
public void Insert(int id, byte[] name, int owner_id) {
if (stmt_insert == null) stmt_insert = conn.Stmt_insert(tbl_name, flds);
stmt_insert.Clear()
.Val_int(fld_id, id)
.Val_int(fld_owner_id, owner_id)
.Val_bry_as_str(fld_name, name)
.Exec_insert();
}
public void Update(int id, byte[] name, int owner_id) {
if (stmt_update == null) stmt_update = conn.Stmt_update_exclude(tbl_name, flds, fld_id);
stmt_update.Clear()
.Val_int(fld_owner_id, owner_id)
.Val_bry_as_str(fld_name, name)
.Crt_int(fld_id, id)
.Exec_update();
}
public Fsd_dir_itm Select_or_null(byte[] name) {
if (stmt_select_by_name == null) stmt_select_by_name = conn.Stmt_select(tbl_name, flds, fld_name);
Db_rdr rdr = stmt_select_by_name.Clear().Crt_bry_as_str(fld_name, name).Exec_select__rls_manual();
try {
return rdr.Move_next()
? new Fsd_dir_itm(rdr.Read_int(fld_id), rdr.Read_int(fld_owner_id), name)
: Fsd_dir_itm.Null
;
}
finally {rdr.Rls();}
}
}

View File

@@ -0,0 +1,34 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.fsdb.data; import gplx.*; import gplx.fsdb.*;
public class Fsd_fil_itm {
public Fsd_fil_itm Ctor(int mnt_id, int dir_id, int fil_id, int bin_db_id, byte[] name, int ext_id) {
this.mnt_id = mnt_id; this.dir_id = dir_id; this.fil_id = fil_id; this.bin_db_id = bin_db_id; this.name = name; this.ext_id = ext_id;
return this;
}
public int Mnt_id() {return mnt_id;} private int mnt_id;
public int Fil_id() {return fil_id;} private int fil_id;
public int Dir_id() {return dir_id;} private int dir_id;
public int Bin_db_id() {return bin_db_id;} private int bin_db_id;
public byte[] Name() {return name;} private byte[] name;
public int Ext_id() {return ext_id;} private int ext_id;
public static final Fsd_fil_itm Null = null;
public static byte[] Gen_cache_key(Bry_bfr bfr, int dir_id, byte[] name) {
return bfr.Add_int_variable(dir_id).Add_byte_pipe().Add(name).Xto_bry_and_clear();
}
}

View File

@@ -0,0 +1,105 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.fsdb.data; import gplx.*; import gplx.fsdb.*;
import gplx.dbs.*; import gplx.dbs.qrys.*; import gplx.dbs.engines.sqlite.*;
public class Fsd_fil_tbl implements RlsAble {
private final String tbl_name = "fsdb_fil"; private final Db_meta_fld_list flds = Db_meta_fld_list.new_();
private final String fld_id, fld_owner_id, fld_name, fld_xtn_id, fld_ext_id, fld_size, fld_modified, fld_hash, fld_bin_db_id;
private final String idx_owner;
private Db_conn conn; private Db_stmt stmt_insert, stmt_update, stmt_select_by_name; private int mnt_id;
public Fsd_fil_tbl(Db_conn conn, boolean schema_is_1, int mnt_id) {
this.conn = conn; this.mnt_id = mnt_id;
this.fld_id = flds.Add_int_pkey ("fil_id");
this.fld_owner_id = flds.Add_int ("fil_owner_id");
this.fld_xtn_id = flds.Add_int ("fil_xtn_id");
this.fld_ext_id = flds.Add_int ("fil_ext_id");
this.fld_bin_db_id = flds.Add_int ("fil_bin_db_id"); // group ints at beginning of table
this.fld_name = flds.Add_str ("fil_name", 255);
this.fld_size = flds.Add_long ("fil_size");
this.fld_modified = flds.Add_str ("fil_modified", 14); // stored as yyyyMMddHHmmss
this.fld_hash = flds.Add_str ("fil_hash", 40);
this.idx_owner = Db_meta_idx.Bld_idx_name(tbl_name, "owner");
conn.Rls_reg(this);
}
public void Rls() {
stmt_insert = Db_stmt_.Rls(stmt_insert);
stmt_update = Db_stmt_.Rls(stmt_update);
stmt_select_by_name = Db_stmt_.Rls(stmt_select_by_name);
}
public void Create_tbl() {
conn.Ddl_create_tbl(Db_meta_tbl.new_(tbl_name, flds
, Db_meta_idx.new_unique_by_name(tbl_name, idx_owner, fld_owner_id, fld_name, fld_id)
));
}
public void Insert(int id, int owner_id, byte[] name, int xtn_id, int ext_id, long size, int bin_db_id) {
if (stmt_insert == null) stmt_insert = conn.Stmt_insert(tbl_name, flds);
stmt_insert.Clear()
.Val_int(fld_id, id)
.Val_int(fld_owner_id, owner_id)
.Val_int(fld_xtn_id, xtn_id)
.Val_int(fld_ext_id, ext_id)
.Val_int(fld_bin_db_id, bin_db_id)
.Val_bry_as_str(fld_name, name)
.Val_long(fld_size, size)
.Val_str(fld_modified, String_.Empty)
.Val_str(fld_hash, String_.Empty)
.Exec_insert();
}
public void Update(int id, int owner_id, byte[] name, int xtn_id, int ext_id, long size, int bin_db_id) {
if (stmt_update == null) stmt_update = conn.Stmt_update_exclude(tbl_name, flds, fld_id);
stmt_update.Clear()
.Val_int(fld_owner_id, owner_id)
.Val_int(fld_xtn_id, xtn_id)
.Val_int(fld_ext_id, ext_id)
.Val_int(fld_bin_db_id, bin_db_id)
.Val_bry_as_str(fld_name, name)
.Val_long(fld_size, size)
.Val_str(fld_modified, String_.Empty)
.Val_str(fld_hash, String_.Empty)
.Crt_int(fld_id, id)
.Exec_update();
}
public Fsd_fil_itm Select_or_null(int dir_id, byte[] fil_name) {
if (stmt_select_by_name == null) {
Db_qry__select_cmd qry = Db_qry__select_cmd.new_().From_(tbl_name).Cols_(flds.To_str_ary()).Where_(Db_crt_.eq_many_(fld_owner_id, fld_name)).Indexed_by_(idx_owner);
stmt_select_by_name = conn.Stmt_new(qry);
}
Db_rdr rdr = stmt_select_by_name.Clear()
.Crt_int(fld_owner_id, dir_id)
.Crt_bry_as_str(fld_name, fil_name)
.Exec_select__rls_manual();
try {
return rdr.Move_next() ? new_(mnt_id, rdr) : Fsd_fil_itm.Null;
}
finally {rdr.Rls();}
}
public void Select_all(Bry_bfr key_bfr, gplx.cache.Gfo_cache_mgr_bry cache) {
Db_rdr rdr = conn.Stmt_select(tbl_name, flds, Db_meta_fld.Ary_empty).Exec_select__rls_auto();
try {
while (rdr.Move_next()) {
Fsd_fil_itm fil = new_(mnt_id, rdr);
byte[] cache_key = Fsd_fil_itm.Gen_cache_key(key_bfr, fil.Dir_id(), fil.Name());
cache.Add(cache_key, fil);
}
}
finally {rdr.Rls();}
}
private Fsd_fil_itm new_(int mnt_id, Db_rdr rdr) {
return new Fsd_fil_itm().Ctor(mnt_id, rdr.Read_int(fld_owner_id), rdr.Read_int(fld_id), rdr.Read_int(fld_bin_db_id), rdr.Read_bry_by_str(fld_name), rdr.Read_int(fld_ext_id));
}
}

View File

@@ -0,0 +1,27 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.fsdb.data; import gplx.*; import gplx.fsdb.*;
public class Fsd_img_itm {
public void Ctor(int mnt_id, int dir_id, int fil_id, int bin_db_id) {
this.mnt_id = mnt_id; this.dir_id = dir_id; this.fil_id = fil_id; this.bin_db_id = bin_db_id;
}
public int Mnt_id() {return mnt_id;} private int mnt_id;
public int Fil_id() {return fil_id;} private int fil_id;
public int Dir_id() {return dir_id;} private int dir_id;
public int Bin_db_id() {return bin_db_id;} private int bin_db_id;
}

View File

@@ -0,0 +1,61 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.fsdb.data; import gplx.*; import gplx.fsdb.*;
public class Fsd_thm_itm {
public void Ctor(int mnt_id, int dir_id, int fil_id, int thm_id, int bin_db_id, int w, int h, double time, int page, long size, String modified, String hash) {
this.mnt_id = mnt_id; this.dir_id = dir_id; this.fil_id = fil_id; this.thm_id = thm_id; this.bin_db_id = bin_db_id;
this.w = w; this.h = h; this.time = time; this.page = page;
this.size = size; this.modified = modified; this.hash = hash;
}
public int Mnt_id() {return mnt_id;} private int mnt_id;
public int Dir_id() {return dir_id;} private int dir_id;
public int Fil_id() {return fil_id;} private int fil_id;
public int Thm_id() {return thm_id;} private int thm_id;
public int Bin_db_id() {return bin_db_id;} private int bin_db_id;
public int W() {return w;} private int w;
public int H() {return h;} private int h;
public double Time() {return time;} private double time;
public int Page() {return page;} private int page;
public long Size() {return size;} private long size;
public String Modified() {return modified;} private String modified;
public String Hash() {return hash;} private String hash;
public int Req_w() {return req_w;} private int req_w;
public double Req_time() {return req_time;} private double req_time;
public int Req_page() {return req_page;} private int req_page;
public void Init_by_req(int w, double time, int page) {this.w = w; this.time = time; this.page = page;}
public void Init_by_match(Fsd_thm_itm comp) {
this.req_w = w; this.req_time = time; this.req_page = page;
this.mnt_id = comp.mnt_id; this.dir_id = comp.dir_id; this.fil_id = comp.fil_id; this.thm_id = comp.thm_id; this.bin_db_id = comp.bin_db_id;
this.w = comp.w; this.h = comp.h; this.time = comp.time; this.page = comp.page;
this.size = comp.size; this.modified = comp.modified; this.hash = comp.hash;
}
public static final Fsd_thm_itm Null = null;
public static final Fsd_thm_itm[] Ary_empty = new Fsd_thm_itm[0];
public static Fsd_thm_itm new_() {return new Fsd_thm_itm();} Fsd_thm_itm() {}
}
class Fsdb_thm_itm_sorter implements gplx.lists.ComparerAble {
public int compare(Object lhsObj, Object rhsObj) {
Fsd_thm_itm lhs = (Fsd_thm_itm)lhsObj;
Fsd_thm_itm rhs = (Fsd_thm_itm)rhsObj;
int comp = Int_.Compare (lhs.W() , rhs.W()); if (comp != CompareAble_.Same) return -comp; // sort by decreasing width
comp = Double_.Compare (lhs.Time() , rhs.Time()); if (comp != CompareAble_.Same) return comp; // sort by increasing time
return Int_.Compare (lhs.Page() , rhs.Page()); // sort by increasing page
}
public static final Fsdb_thm_itm_sorter I = new Fsdb_thm_itm_sorter(); Fsdb_thm_itm_sorter() {}
}

View File

@@ -0,0 +1,155 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.fsdb.data; import gplx.*; import gplx.fsdb.*;
import gplx.dbs.*; import gplx.fsdb.meta.*; import gplx.xowa.files.*;
public class Fsd_thm_tbl implements RlsAble {
private final String tbl_name; private final Db_meta_fld_list flds = Db_meta_fld_list.new_();
private final String fld_id, fld_owner_id, fld_w, fld_h, fld_time, fld_page, fld_bin_db_id, fld_size, fld_modified, fld_hash;
private final Db_conn conn; private Db_stmt stmt_insert, stmt_select_by_fil_exact, stmt_select_by_fil_near; private int mnt_id; private boolean schema_thm_page;
public Fsd_thm_tbl(Db_conn conn, boolean schema_is_1, int mnt_id, boolean schema_thm_page) {
this.conn = conn; this.mnt_id = mnt_id; this.schema_thm_page = schema_thm_page;
this.tbl_name = schema_is_1 ? "fsdb_xtn_thm" : "fsdb_thm";
this.fld_id = flds.Add_int_pkey ("thm_id");
this.fld_owner_id = flds.Add_int ("thm_owner_id");
this.fld_w = flds.Add_int ("thm_w");
this.fld_h = flds.Add_int ("thm_h");
if (schema_thm_page) {
this.fld_time = flds.Add_double ("thm_time");
this.fld_page = flds.Add_int ("thm_page");
}
else {
this.fld_time = flds.Add_int ("thm_thumbtime");
this.fld_page = Db_meta_fld.Key_null;
}
this.fld_bin_db_id = flds.Add_int ("thm_bin_db_id");
this.fld_size = flds.Add_long ("thm_size");
this.fld_modified = flds.Add_str ("thm_modified", 14); // stored as yyyyMMddHHmmss
this.fld_hash = flds.Add_str ("thm_hash", 40);
conn.Rls_reg(this);
}
public void Rls() {
stmt_insert = Db_stmt_.Rls(stmt_insert);
stmt_select_by_fil_exact = Db_stmt_.Rls(stmt_select_by_fil_exact);
stmt_select_by_fil_near = Db_stmt_.Rls(stmt_select_by_fil_near);
}
public void Create_tbl() {
conn.Ddl_create_tbl(Db_meta_tbl.new_(tbl_name, flds
, Db_meta_idx.new_unique_by_tbl(tbl_name, "owner", fld_owner_id, fld_id, fld_w, fld_time, fld_page)
));
}
public void Insert(int id, int thm_owner_id, int width, int height, double thumbtime, int page, int bin_db_id, long size) {
if (stmt_insert == null) stmt_insert = conn.Stmt_insert(tbl_name, flds);
stmt_insert.Clear()
.Val_int(fld_id, id)
.Val_int(fld_owner_id, thm_owner_id)
.Val_int(fld_w, width)
.Val_int(fld_h, height);
if (schema_thm_page) {
stmt_insert.Val_double (fld_time, Xof_lnki_time.Db_save_double(thumbtime));
stmt_insert.Val_int (fld_page, Xof_lnki_page.Db_save_int(page));
}
else
stmt_insert.Val_int (fld_time, Xof_lnki_time.Db_save_int(thumbtime));
stmt_insert
.Val_int(fld_bin_db_id, bin_db_id)
.Val_long(fld_size, size)
.Val_str(fld_modified, Modified_null_str)
.Val_str(fld_hash, Hash_null)
.Exec_insert();
}
public boolean Select_itm_by_w_exact(int dir_id, int fil_id, Fsd_thm_itm thm) {
if (stmt_select_by_fil_exact == null) stmt_select_by_fil_exact = conn.Stmt_select(tbl_name, flds, String_.Ary_wo_null(fld_owner_id, fld_w, fld_time, fld_page));
stmt_select_by_fil_exact.Clear().Crt_int(fld_owner_id, fil_id).Crt_int(fld_w, thm.W());
if (schema_thm_page) {
stmt_select_by_fil_exact.Crt_double (fld_time, Xof_lnki_time.Db_save_double(thm.Time()));
stmt_select_by_fil_exact.Crt_int (fld_page, Xof_lnki_page.Db_save_int(thm.Page()));
}
else {
stmt_select_by_fil_exact.Crt_int (fld_time, Xof_lnki_time.Db_save_int(thm.Time()));
}
Db_rdr rdr = stmt_select_by_fil_exact.Exec_select__rls_manual();
try {
return rdr.Move_next()
? Ctor_by_load(thm, rdr, dir_id)
: false;
}
finally {rdr.Rls();}
}
public boolean Select_itm_by_w_near(int dir_id, int fil_id, Fsd_thm_itm thm) {
if (stmt_select_by_fil_near == null) stmt_select_by_fil_near = conn.Stmt_select(tbl_name, flds, fld_owner_id);
List_adp list = List_adp_.new_();
Db_rdr rdr = stmt_select_by_fil_near.Clear().Crt_int(fld_owner_id, fil_id).Exec_select__rls_manual();
try {
while (rdr.Move_next()) {
Fsd_thm_itm itm = Fsd_thm_itm.new_();
Ctor_by_load(itm, rdr, dir_id);
list.Add(itm);
}
return Match_nearest(list, thm, schema_thm_page);
}
finally {rdr.Rls();}
}
private boolean Ctor_by_load(Fsd_thm_itm itm, Db_rdr rdr, int dir_id) {
int thm_id = rdr.Read_int(fld_id);
int fil_id = rdr.Read_int(fld_owner_id);
int w = rdr.Read_int(fld_w);
int h = rdr.Read_int(fld_h);
long size = rdr.Read_long(fld_size);
String modified = rdr.Read_str(fld_modified);
String hash = rdr.Read_str(fld_hash);
int bin_db_id = rdr.Read_int(fld_bin_db_id);
double time = 0;
int page = 0;
if (schema_thm_page) {
time = Xof_lnki_time.Db_load_double(rdr, fld_time);
page = Xof_lnki_page.Db_load_int(rdr, fld_page);
}
else {
time = Xof_lnki_time.Db_load_int(rdr, fld_time);
page = Xof_lnki_page.Null;
}
itm.Ctor(mnt_id, dir_id, fil_id, thm_id, bin_db_id, w, h, time, page, size, modified, hash);
return true;
}
public static final DateAdp Modified_null = null;
public static final String Hash_null = "", Modified_null_str = "";
public static boolean Match_nearest(List_adp list, Fsd_thm_itm thm, boolean schema_thm_page) {
int len = list.Count(); if (len == 0) return Bool_.N;
list.Sort_by(Fsdb_thm_itm_sorter.I);
int thm_w = thm.W(), thm_page = thm.Page(); double thm_time = thm.Time();
Fsd_thm_itm max = null;
for (int i = 0; i < len; ++i) {
Fsd_thm_itm comp = (Fsd_thm_itm)list.Get_at(i);
int comp_w = comp.W();
int comp_page = schema_thm_page ? comp.Page() : thm_page;
if ( thm_w == comp_w
&& thm_time == comp.Time()
&& thm_page == comp_page
) { // exact match
thm.Init_by_match(comp);
return Bool_.Y;
}
if (comp_w > thm_w) max = comp;
else if (max == null) max = comp;
else break;
}
if (max == null) return Bool_.N;
thm.Init_by_match(max);
return Bool_.Y;
}
}

View File

@@ -0,0 +1,58 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.fsdb.data; import gplx.*; import gplx.fsdb.*;
import org.junit.*;
public class Fsd_thm_tbl_tst {
@Before public void init() {fxt.Clear();} private Fsd_thm_tbl_fxt fxt = new Fsd_thm_tbl_fxt();
@Test public void Basic() {
fxt.Init_list(fxt.Make(100), fxt.Make(200), fxt.Make(400));
fxt.Test_match_nearest_itm(fxt.Make(400), fxt.Make(400));
fxt.Test_match_nearest_itm(fxt.Make(200), fxt.Make(200));
fxt.Test_match_nearest_itm(fxt.Make(100), fxt.Make(100));
fxt.Test_match_nearest_itm(fxt.Make(350), fxt.Make(400));
fxt.Test_match_nearest_itm(fxt.Make(150), fxt.Make(200));
fxt.Test_match_nearest_itm(fxt.Make(999), fxt.Make(400));
}
@Test public void Empty() {
fxt.Init_list(); // no items
fxt.Test_match_nearest_itm(fxt.Make(100), Fsd_thm_itm.Null);
}
}
class Fsd_thm_tbl_fxt {
private final List_adp list = List_adp_.new_();
public void Clear() {list.Clear();}
public Fsd_thm_itm Make(int w) {
double time = gplx.xowa.files.Xof_lnki_time.Null;
int page = gplx.xowa.files.Xof_lnki_page.Null;
Fsd_thm_itm rv = Fsd_thm_itm.new_();
rv.Init_by_req(w, time, page);
return rv;
}
public void Init_list(Fsd_thm_itm... ary) {list.Add_many((Object[])ary);}
public void Test_match_nearest_itm(Fsd_thm_itm req, Fsd_thm_itm expd) {
Fsd_thm_tbl.Match_nearest(list, req, Bool_.Y);
if (expd == Fsd_thm_itm.Null) {
Tfds.Eq(req.Req_w(), 0);
}
else {
Tfds.Eq(expd.W(), req.W());
Tfds.Eq(expd.Time(), req.Time());
Tfds.Eq(expd.Page(), req.Page());
}
}
}