/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.fsdb.meta; import gplx.*; import gplx.fsdb.*;
import gplx.core.primitives.*; import gplx.core.caches.*; import gplx.core.ios.*; import gplx.core.ios.streams.*;
import gplx.dbs.*; import gplx.dbs.engines.sqlite.*; import gplx.fsdb.data.*;
public class Fsm_atr_fil {
private final Fsm_mnt_itm mnt_itm; private final int mnt_id;
private Fsd_dir_tbl tbl_dir; private Fsd_fil_tbl tbl_fil; private Fsd_thm_tbl tbl_thm;
private final Gfo_cache_mgr_bry dir_cache = new Gfo_cache_mgr_bry(); private Gfo_cache_mgr_bry fil_cache; private Bry_bfr fil_cache_key_bfr;
public Fsm_atr_fil(Fsm_mnt_itm mnt_itm, int id, String url_rel, Db_conn conn, boolean schema_is_1, boolean schema_thm_page) {
this.mnt_itm = mnt_itm; this.mnt_id = mnt_itm.Id();
this.id = id; this.url_rel = url_rel; this.conn = conn;
this.tbl_dir = new Fsd_dir_tbl(conn, schema_is_1);
this.tbl_fil = new Fsd_fil_tbl(conn, schema_is_1, mnt_id);
this.tbl_thm = new Fsd_thm_tbl(conn, schema_is_1, mnt_id, schema_thm_page);
}
public int Id() {return id;} private final int id;
public String Url_rel() {return url_rel;} private final String url_rel;
public Db_conn Conn() {return conn;} private final Db_conn conn;
public Fsd_fil_itm Select_fil_or_null(byte[] dir, byte[] fil) {
int dir_id = Get_dir_id_or_neg1(dir);
return dir_id == Int_.Neg1 ? Fsd_fil_itm.Null : tbl_fil.Select_or_null(dir_id, fil);
}
public boolean Select_thm(boolean exact, Fsd_thm_itm rv, int dir_id, int fil_id) {
return exact ? tbl_thm.Select_itm_by_w_exact(dir_id, fil_id, rv) : tbl_thm.Select_itm_by_w_near(dir_id, fil_id, rv);
}
public Fsd_fil_itm Insert_fil(byte[] dir, byte[] fil, int ext_id, int bin_db_id, long bin_len, Io_stream_rdr bin_rdr) {
int dir_id = Get_dir_id_or_make(dir);
int fil_id = Get_fil_id_or_make(Tid_none, dir_id, fil, ext_id, bin_db_id, bin_len);
return new Fsd_fil_itm(mnt_id, dir_id, fil_id, 0, ext_id, fil, bin_len, null, null, bin_db_id);
}
public Fsd_img_itm Insert_img(byte[] dir, byte[] fil, int ext_id, int img_w, int img_h, int bin_db_id, long bin_len, Io_stream_rdr bin_rdr) {
int dir_id = Get_dir_id_or_make(dir);
int fil_id = Get_fil_id_or_make(Tid_img, dir_id, fil, ext_id, bin_db_id, bin_len);
return new Fsd_img_itm(mnt_id, dir_id, fil_id, bin_db_id);
}
public int Insert_thm(Fsd_thm_itm rv, byte[] dir, byte[] fil, int ext_id, int w, int h, double time, int page, int bin_db_id, long bin_len, Io_stream_rdr bin_rdr) {
int dir_id = Get_dir_id_or_make(dir);
int fil_id = Get_fil_id_or_make(Tid_thm, dir_id, fil, ext_id, Fsd_bin_tbl.Bin_db_id_null, Fsd_bin_tbl.Size_null); // NOTE: bin_db_id must be set to NULL
int thm_id = mnt_itm.Next_id();
tbl_thm.Insert(thm_id, fil_id, w, h, time, page, bin_db_id, bin_len);
rv.Ctor(mnt_id, dir_id, fil_id, thm_id, bin_db_id, w, h, time, page, bin_len, Fsd_thm_tbl.Modified_null_str, Fsd_thm_tbl.Hash_null);
return thm_id;
}
public void Fil_cache_enabled_y_() {
fil_cache = new Gfo_cache_mgr_bry();
fil_cache_key_bfr = Bry_bfr_.Reset(255);
tbl_fil.Select_all(fil_cache_key_bfr, fil_cache);
}
private int Get_dir_id_or_neg1(byte[] dir_bry) {
Object rv_obj = dir_cache.Get_or_null(dir_bry);
if (rv_obj == null) { // not in mem
Fsd_dir_itm itm = tbl_dir.Select_or_null(dir_bry); // try db
if (itm == Fsd_dir_itm.Null) return -1; // not in db
int dir_id = itm.Dir_id();
dir_cache.Add(dir_bry, Int_obj_ref.New(dir_id)); // add to mem
return dir_id;
}
else
return ((Int_obj_ref)rv_obj).Val();
}
private int Get_dir_id_or_make(byte[] dir_bry) {
int rv = Get_dir_id_or_neg1(dir_bry);
if (rv == -1) {
rv = mnt_itm.Next_id();
tbl_dir.Insert(rv, dir_bry, Fsd_dir_itm.Owner_root);
dir_cache.Add(dir_bry, Int_obj_ref.New(rv));
}
return rv;
}
private int Get_fil_id_or_make(int xtn_tid, int dir_id, byte[] fil, int ext_id, int bin_db_id, long bin_len) {
if (fil_cache != null) {
byte[] cache_key = Fsd_fil_itm.Gen_cache_key(fil_cache_key_bfr, dir_id, fil);
Object cache_obj = fil_cache.Get_or_null(cache_key);
if (cache_obj != null) return ((Fsd_fil_itm)cache_obj).Fil_id();
}
Fsd_fil_itm fil_itm = tbl_fil.Select_or_null(dir_id, fil);
int fil_id = -1;
if (fil_itm == Fsd_fil_itm.Null) { // new item
fil_id = mnt_itm.Next_id();
tbl_fil.Insert(fil_id, dir_id, fil, xtn_tid, ext_id, bin_len, bin_db_id);
}
else { // existing item
fil_id = fil_itm.Fil_id();
if ( fil_itm.Bin_db_id() == Fsd_bin_tbl.Bin_db_id_null // prv row was previously inserted by thumb
&& xtn_tid != Tid_thm // cur row is not thumb
) {
tbl_fil.Update(fil_id, dir_id, fil, xtn_tid, ext_id, bin_len, bin_db_id); // update props; note that thumb inserts null props, whereas file will insert real props (EX: bin_db_id)
}
}
return fil_id;
}
private static final int Tid_none = 0, Tid_thm = 1, Tid_img = 2;
}