/* TRelationType.java - SQL operations with the table 'relation_type' * in Wiktionary parsed database. * * Copyright (c) 2009-2011 Andrew Krizhanovsky <andrew.krizhanovsky at gmail.com> * Distributed under EPL/LGPL/GPL/AL/BSD multi-license. */ package wikokit.base.wikt.sql; import wikokit.base.wikt.constant.Relation; import wikokit.base.wikipedia.sql.Connect; import wikokit.base.wikipedia.sql.UtilSQL; import wikokit.base.wikipedia.sql.Statistics; import java.sql.*; import java.util.Map; import java.util.LinkedHashMap; import java.util.Collection; import java.util.List; import java.util.ArrayList; import java.util.Collections; /** An operations with the table 'relation_type' in Wiktionary parsed database. * The table 'relation_type' contains a list of semantic relations: name and ID. */ public class TRelationType { /** Unique POS identifier. */ private int id; /** Name of semantic relations, e.g. synonymy. */ private Relation name; /** Map from an ID to a relation. It is created from data of the table `relation_type`, * which is created from data in Relation.java.*/ private static Map<Integer, TRelationType> id2relation; /** Map from a relation to an ID.*/ private static Map<Relation, Integer> relation2id; private final static TRelationType[] NULL_TRELATIONTYPE_ARRAY = new TRelationType[0]; public TRelationType(int _id,Relation _name) { id = _id; name = _name; } /** Gets an unique ID of this relation. */ public int getID() { return id; } /** Gets a semantic relation. */ public Relation getRelation() { return name; } /** Gets semantic relations' ID from the table 'relation_type'.<br><br> * REM: createFastMaps() should be run at least once, before this function execution. */ public static int getIDFast(Relation r) { if(null == relation2id) { System.out.println("Error (wikt_parsed TRelationType.getIDFast()):: What about calling 'createFastMaps()' before?"); return -1; } if(null == r) { System.out.println("Error (wikt_parsed TRelationType.getIDFast()):: argument POS is null"); return -1; } return relation2id.get(r); } /** Gets semantic relations by ID from the table 'relation_type'.<br><br> * REM: createFastMaps() should be run at least once, before this function execution. */ public static TRelationType getRelationFast(int id) { if(null == id2relation) { System.out.println("Error (wikt_parsed TRelationType.getRelationFast()):: What about calling 'createFastMaps()' before?"); return null; } if(id <= 0) { System.out.println("Error (wikt_parsed TRelationType.getRelationFast()):: argument id <=0, id = "+id); return null; } return id2relation.get(id); } /** Gets semantic relations (name with ID) from the table 'relation_type'.<br><br> * REM: createFastMaps() should be run at least once, before this function execution. */ public static TRelationType getRelationFast(Relation r) { return getRelationFast(getIDFast(r)); } /** Read all records from the table 'relation_type', * fills the internal map from a table ID to a semantic relation .<br><br> * * REM: during a creation of Wiktionary parsed database * the functions recreateTable() should be called (before this function). */ public static void createFastMaps(Connect connect) { System.out.println("Loading table `relation_type`..."); TRelationType[] rel_type = getAllRelations(connect); int size = rel_type.length; if(rel_type.length != Relation.size()) System.out.println("Warning (wikt_parsed TRelationType.java createFastMaps()):: Relation.size (" + Relation.size() + ") is not equal to size of table 'relation_type'("+ size +"). Is the database outdated?"); if(null != id2relation && id2relation.size() > 0) id2relation.clear(); if(null != relation2id && relation2id.size() > 0) relation2id.clear(); id2relation = new LinkedHashMap<Integer, TRelationType>(size); relation2id = new LinkedHashMap<Relation, Integer>(size); for(TRelationType t : rel_type) { id2relation.put(t.getID(), t); relation2id.put(t.getRelation(), t.getID()); } } /** Gets all records from the table 'relation_type'. */ private static TRelationType[] getAllRelations(Connect connect) { int size = Statistics.Count(connect, "relation_type"); if(0==size) { System.out.println("Error (wikt_parsed TRelationType.java getAllRelations()):: The table `relation_type` is empty!"); return NULL_TRELATIONTYPE_ARRAY; } List<TRelationType>list_rel = new ArrayList<>(size); Collection<Relation> rr = Relation.getAllRelations(); for(Relation r : rr) { TRelationType t = get(connect, r); if(null != t) list_rel.add(t); } return( (TRelationType[])list_rel.toArray(NULL_TRELATIONTYPE_ARRAY) ); } /** Deletes all records from the table 'relation_type', * loads parts of speech names from POS.java, * sorts by name, * fills the table. */ public static void recreateTable(Connect connect) { System.out.println("Recreating the table `relation_type`..."); Map<Integer, Relation> _id2relation = fillLocalMaps(); UtilSQL.deleteAllRecordsResetAutoIncrement(connect, "relation_type"); fillDB(connect, _id2relation); { int db_current_size = wikokit.base.wikipedia.sql.Statistics.Count(connect, "relation_type"); assert(db_current_size == Relation.size()); // ~ 9 types of relations } } /** Load data from a Relation class, sorts, * and fills the local map 'id2relation'. */ public static Map<Integer, Relation> fillLocalMaps() { int size = Relation.size(); List<String>list_rel = new ArrayList<>(size); list_rel.addAll(Relation.getAllRelationNames()); Collections.sort(list_rel); // Collections.sort(list_rel, StringUtil.LEXICOGRAPHICAL_ORDER); // OK, we have list of relation names. Sorted list 'list_rel' // Local map from id to Relation. It is created from data in Relation.java. // It is used to fill the table 'relation_type' in right sequence. Map<Integer, Relation> _id2relation = new LinkedHashMap<>(size); for(int id=0; id<size; id++) { String s = list_rel.get(id); // s - semantic relation name assert(Relation.has(s)); //System.out.println("fillLocalMaps---id="+id+"; s="+s); _id2relation.put(id+1, Relation.get(s)); } return _id2relation; } /** Fills database table 'relation_type' by data from Relation class. */ public static void fillDB(Connect connect,Map<Integer, Relation> id2relation) { for(int id : id2relation.keySet()) insert (connect, id2relation.get(id)); } /** Inserts record into the table 'relation_type'.<br><br> * INSERT INTO relation_type (name) VALUES ("synonymy"); * @param name semantic relation, e.g. 'synonymy' */ public static void insert (Connect connect,Relation r) { if(null == r) return; StringBuilder str_sql = new StringBuilder(); try { Statement s = connect.conn.createStatement (); try { str_sql.append("INSERT INTO relation_type (name) VALUES (\""); //String safe_title = StringUtil.spaceToUnderscore( // StringUtil.escapeChars(name)); //str_sql.append(safe_title); str_sql.append(r.toString()); str_sql.append("\")"); s.executeUpdate (str_sql.toString()); } finally { s.close(); } }catch(SQLException ex) { System.out.println("SQLException (wikt_parsed TRelationType.java insert()):: sql='" + str_sql.toString() + "' " + ex.getMessage()); } } /** Selects row from the table 'relation_type' by a semantic relation name.<br><br> * SELECT id FROM relation_type WHERE name="synonymy"; * @param r semantic relation * @return null if a semantic relation is absent in the table 'relation_type' */ public static TRelationType get (Connect connect,Relation r) { if(null == r) return null; StringBuilder str_sql = new StringBuilder(); TRelationType rel_type = null; try { Statement s = connect.conn.createStatement (); try { str_sql.append("SELECT id FROM relation_type WHERE name=\""); str_sql.append(r.toString()); str_sql.append("\""); ResultSet rs = s.executeQuery (str_sql.toString()); try { if (rs.next ()) rel_type = new TRelationType(rs.getInt("id"), r); else System.out.println("Warning: (wikt_parsed TRelationType.java get()):: POS (" + r.toString() + ") is absent in the table 'relation_type'."); } finally { rs.close(); } } finally { s.close(); } } catch(SQLException ex) { System.out.println("SQLException (TRelationType.get()):: sql='" + str_sql.toString() + "' " + ex.getMessage()); } return rel_type; } /** Deletes row from the table 'relation_type' by the semantic relation name.<br><br> * DELETE FROM relation_type WHERE name="synonymy"; * @param r semantic relation to be deleted */ public static void delete (Connect connect,Relation r) { if(null == r) return; StringBuilder str_sql = new StringBuilder(); try { Statement s = connect.conn.createStatement (); try { str_sql.append("DELETE FROM relation_type WHERE name=\""); str_sql.append(r.toString()); str_sql.append("\""); s.execute (str_sql.toString()); } finally { s.close(); } } catch(SQLException ex) { System.out.println("SQLException (TRelationType.delete()):: sql='" + str_sql.toString() + "' " + ex.getMessage()); } } }