From 01e45caa5ad68de647ef28dfc068519117f1ed4a Mon Sep 17 00:00:00 2001 From: gnosygnu Date: Mon, 17 Oct 2016 20:37:50 -0400 Subject: [PATCH] Fix build error for English Wikibooks --- 100_core/src/gplx/Bry_find_.java | 4 ++ 100_core/src/gplx/Int_.java | 17 +++++++ .../bldrs/sql_dumps/Xosql_tbl_parser.java | 44 +++++++++++-------- .../sql_dumps/Xosql_tbl_parser__tst.java | 44 ++++++++++++++----- .../xowa/xtns/gallery/Gallery_parser.java | 2 +- 5 files changed, 81 insertions(+), 30 deletions(-) diff --git a/100_core/src/gplx/Bry_find_.java b/100_core/src/gplx/Bry_find_.java index 80af17d93..377b1a617 100644 --- a/100_core/src/gplx/Bry_find_.java +++ b/100_core/src/gplx/Bry_find_.java @@ -29,6 +29,10 @@ public class Bry_find_ { int rv = Find_fwd(src, lkp, cur, end); return rv == Bry_find_.Not_found ? or : rv; } + public static int Find_fwd_or(byte[] src, byte[] lkp, int cur, int end, int or) { + int rv = Find_fwd(src, lkp, cur, end); + return rv == Bry_find_.Not_found ? or : rv; + } public static int Find_bwd(byte[] src, byte lkp) {return Find_bwd(src, lkp, src.length, 0);} public static int Find_bwd(byte[] src, byte lkp, int cur) {return Find_bwd(src, lkp, cur , 0);} public static int Find_bwd(byte[] src, byte lkp, int cur, int end) { diff --git a/100_core/src/gplx/Int_.java b/100_core/src/gplx/Int_.java index dd7887337..5a97dc6c2 100644 --- a/100_core/src/gplx/Int_.java +++ b/100_core/src/gplx/Int_.java @@ -86,6 +86,23 @@ public class Int_ implements Gfo_invk { } public static int BoundEnd(int v, int end) {return v >= end ? end - 1 : v;} public static int Min(int lhs, int rhs) {return lhs < rhs ? lhs : rhs;} + public static int Min_many(int... ary) { + int len = ary.length; if (len == 0) throw Err_.new_wo_type("Min_many requires at least 1 value"); + boolean init = true; + int min = Int_.Min_value; + for (int i = 0; i < len; ++i) { + int val = ary[i]; + if (init) { + min = val; + init = false; + } + else { + if (val < min) + min = val; + } + } + return min; + } public static int Max(int lhs, int rhs) {return lhs > rhs ? lhs : rhs;} public static int ModIfNeg1(int v, int or) {return v == -1 ? or : v;} public static boolean RangeCheck(int v, int max) {return v >= 0 && v < max;} diff --git a/400_xowa/src/gplx/xowa/bldrs/sql_dumps/Xosql_tbl_parser.java b/400_xowa/src/gplx/xowa/bldrs/sql_dumps/Xosql_tbl_parser.java index 45ef5b2af..27e395d53 100644 --- a/400_xowa/src/gplx/xowa/bldrs/sql_dumps/Xosql_tbl_parser.java +++ b/400_xowa/src/gplx/xowa/bldrs/sql_dumps/Xosql_tbl_parser.java @@ -20,21 +20,7 @@ import gplx.core.ios.*; class Xosql_tbl_parser { public Ordered_hash Parse(byte[] raw) { Ordered_hash rv = Ordered_hash_.New_bry(); - // get bgn of fields def; assume after "CREATE TABLE" - int bgn = Bry_find_.Find_fwd(raw, Tkn__create_table); if (bgn == Bry_find_.Not_found) throw Err_.new_wo_type("could not find 'CREATE TABLE'"); - bgn = Bry_find_.Find_fwd(raw, Byte_ascii.Nl, bgn); if (bgn == Bry_find_.Not_found) throw Err_.new_wo_type("could not find new line after 'CREATE TABLE'"); - bgn += 1; // position after character - - // get end of fields def; assume before "UNIQUE KEY" or "PRIMARY KEY" - int end = Bry_find_.Find_fwd(raw, Tkn__primary_key); - if (end == Bry_find_.Not_found) { // as of 2016-07, en.w:categorylinks no longer has UNIQUE KEY; try PRIMARY KEY; DATE:2016-07-08 - end = Bry_find_.Find_fwd(raw, Tkn__unique_index); - if (end == Bry_find_.Not_found) throw Err_.new_wo_type("could not find 'UNIQUE KEY' or 'PRIMARY KEY'"); - } - end = Bry_find_.Find_bwd(raw, Byte_ascii.Nl, end); if (bgn == Bry_find_.Not_found) throw Err_.new_wo_type("could not find new line before 'UNIQUE KEY'"); - - // do parse - Parse_flds(rv, Bry_.Mid(raw, bgn, end)); + Parse_flds(rv, Extract_flds(raw)); return rv; } private void Parse_flds(Ordered_hash rv, byte[] raw) { @@ -53,9 +39,31 @@ class Xosql_tbl_parser { rv.Add(key, new Xosql_fld_itm(Int_.Max_value, key, fld_idx++)); } } - private static final byte[] + public byte[] Extract_flds(byte[] raw) { // NOTE: very dependent on MySQL dump formatter + // get bgn of flds; assume after "CREATE TABLE" + int bgn = Bry_find_.Find_fwd(raw, Tkn__create_table); if (bgn == Bry_find_.Not_found) throw Err_.new_wo_type("could not find 'CREATE TABLE'"); + bgn = Bry_find_.Find_fwd(raw, Byte_ascii.Nl, bgn); if (bgn == Bry_find_.Not_found) throw Err_.new_wo_type("could not find new line after 'CREATE TABLE'"); + bgn += 1; // position after \n + + // get end of flds; more involved, as need to find last field before indexes + // first, get absolute end; don't want to pick up "PRIMARY KEY" in data; EX:en.b:categorylinks.sql DATE:2016-10-17 + int end = Bry_find_.Find_fwd(raw, Tkn__engine); if (end == Bry_find_.Not_found) throw Err_.new_wo_type("could not find ') ENGINE'"); + + // now look for "UNIQUE KEY", "KEY", "PRIMARY KEY" + int key_idx = Bry_find_.Find_fwd_or(raw, Tkn__key , bgn, end, Int_.Max_value__31); + int pkey_idx = Bry_find_.Find_fwd_or(raw, Tkn__pkey, bgn, end, Int_.Max_value__31); + int ukey_idx = Bry_find_.Find_fwd_or(raw, Tkn__ukey, bgn, end, Int_.Max_value__31); + + // get min; fail if none found + int rv = Int_.Min_many(key_idx, pkey_idx, ukey_idx); + if (rv == Int_.Max_value__31) throw Err_.new_wo_type("could not find 'PRIMARY KEY', 'UNIQUE KEY', or 'KEY' in SQL", "raw", Bry_.Mid(raw, bgn, end)); + return Bry_.Mid(raw, bgn, rv); + } + private final byte[] Tkn__create_table = Bry_.new_a7("CREATE TABLE") - , Tkn__unique_index = Bry_.new_a7("UNIQUE KEY") - , Tkn__primary_key = Bry_.new_a7("PRIMARY KEY") + , Tkn__ukey = Bry_.new_a7("\n UNIQUE KEY") + , Tkn__pkey = Bry_.new_a7("\n PRIMARY KEY") + , Tkn__key = Bry_.new_a7("\n KEY ") + , Tkn__engine = Bry_.new_a7("\n) ENGINE") ; } diff --git a/400_xowa/src/gplx/xowa/bldrs/sql_dumps/Xosql_tbl_parser__tst.java b/400_xowa/src/gplx/xowa/bldrs/sql_dumps/Xosql_tbl_parser__tst.java index d86db26aa..dafae829e 100644 --- a/400_xowa/src/gplx/xowa/bldrs/sql_dumps/Xosql_tbl_parser__tst.java +++ b/400_xowa/src/gplx/xowa/bldrs/sql_dumps/Xosql_tbl_parser__tst.java @@ -19,7 +19,7 @@ package gplx.xowa.bldrs.sql_dumps; import gplx.*; import gplx.xowa.*; import gpl import org.junit.*; import gplx.core.tests.*; public class Xosql_tbl_parser__tst { private final Xosql_tbl_parser__fxt fxt = new Xosql_tbl_parser__fxt(); - @Test public void Basic() { + @Test public void Unique_key() { fxt.Exec__parse(String_.Concat_lines_nl ( "ignore" , "CREATE TABLE tbl_0 (" @@ -27,7 +27,7 @@ public class Xosql_tbl_parser__tst { , " `fld_1` int," , " `fld_0` int," , " UNIQUE KEY idx_0 (fld_2)" - , ");" + , ") ENGINE;" )); fxt.Test__count(3); fxt.Test__get("fld_0", 2); @@ -36,20 +36,39 @@ public class Xosql_tbl_parser__tst { fxt.Test__get("fld_3", -1); } @Test public void Primary_key() { - fxt.Exec__parse(String_.Concat_lines_nl + fxt.Test__extract(String_.Concat_lines_nl ( "ignore" , "CREATE TABLE tbl_0 (" - , " `fld_2` int," - , " `fld_1` int," , " `fld_0` int," , " PRIMARY KEY idx_0 (fld_2)" - , ");" + , ") ENGINE;" + ), String_.Concat_lines_nl + ( " `fld_0` int," + )); + } + @Test public void Key() { + fxt.Test__extract(String_.Concat_lines_nl + ( "ignore" + , "CREATE TABLE tbl_0 (" + , " `fld_0` int," + , " KEY idx_0 (fld_2)" + , ") ENGINE;" + ), String_.Concat_lines_nl + ( " `fld_0` int," + )); + } + @Test public void Unique_key__key__primary_key() { + fxt.Test__extract(String_.Concat_lines_nl + ( "ignore" + , "CREATE TABLE tbl_0 (" + , " `fld_0` int," + , " UNIQUE KEY idx_0 (fld_2)," + , " KEY idx_0 (fld_2)," + , " PRIMARY KEY idx_0 (fld_2)," + , ") ENGINE;" + ), String_.Concat_lines_nl + ( " `fld_0` int," )); - fxt.Test__count(3); - fxt.Test__get("fld_0", 2); - fxt.Test__get("fld_1", 1); - fxt.Test__get("fld_2", 0); - fxt.Test__get("fld_3", -1); } } class Xosql_tbl_parser__fxt { @@ -61,4 +80,7 @@ class Xosql_tbl_parser__fxt { Xosql_fld_itm actl_itm = (Xosql_fld_itm)tbl_flds.Get_by(Bry_.new_u8(key)); Gftest.Eq__int(expd, actl_itm == null ? Bry_find_.Not_found : actl_itm.Idx()); } + public void Test__extract(String raw, String expd) { + Gftest.Eq__ary__lines(expd, parser.Extract_flds(Bry_.new_u8(raw)), "extract"); + } } diff --git a/400_xowa/src/gplx/xowa/xtns/gallery/Gallery_parser.java b/400_xowa/src/gplx/xowa/xtns/gallery/Gallery_parser.java index db1faee83..a3e45cc2e 100644 --- a/400_xowa/src/gplx/xowa/xtns/gallery/Gallery_parser.java +++ b/400_xowa/src/gplx/xowa/xtns/gallery/Gallery_parser.java @@ -242,7 +242,7 @@ public class Gallery_parser { // MW changed behavior from chaining multiple args to keeping last one; EX: "File:A.png|a|b" -> "b" x> "a|b" PAGE:fr.w:Belgique DATE:2016-10-17 REF: https://github.com/wikimedia/mediawiki/commit/63aeabeff1e098e872cc46f3698c61457e44ba15 private static byte[] Make_caption_bry(Bry_bfr tmp_bfr, Xowe_wiki wiki, Xop_ctx ctx, byte[] src) { // parse caption to tkns - Xop_root_tkn root = wiki.Parser_mgr().Main().Parse_text_to_wdom(Xop_ctx.New__top(wiki), src, false); + Xop_root_tkn root = wiki.Parser_mgr().Main().Parse_text_to_wdom(Xop_ctx.New__top(wiki), src, false); // NOTE: ctx must be top, else will get double-counted // loop tkns int subs_len = root.Subs_len();