def load_from(cls, file_): """Create an instance from a YAML file.""" file_ = path(file_) if not file_.exists: log.error("file does not exist: {0}".format(file_.absolute)) return return cls(list(yaml.load_all(file_.open("r"))), file_)
def main(): setup_logging() parser = argparse.ArgumentParser() parser.add_argument("-w", "--working-directory", dest="path", default=path("."), nargs="?", help="specify path to YAML documents") parser.add_argument("spec", help="name of spec or 'all'") parser.add_argument("operation", help="[execute|dml]", nargs="?", default="dml") args = parser.parse_args() op = args.operation.lower() if op not in ("execute", "dml"): log.error("invalid operation") sys.exit(1) wd = path(args.path) default_wd = path("~/.trine") search_path = [wd] if not wd.exists: log.error("directory '{0}' does not exist".format(wd)) if not default_wd.exists: log.critical("default working directory (%s) does not exist" % default_wd) sys.exit(1) search_path += default_wd config_file = None search_path = [wd] if default_wd.exists: search_path.append(default_wd) for documents in [p.glob("*.yml") for p in search_path]: if not documents: log.error("no YAML documents found in {0}".format(wd.absolute)) else: for document in documents: if document.name == "config.yml": config_file = document break if config_file: break config = AttrDict(yaml.load(config_file.open("r"))) setup_db_sessions(config) specs = [] for documents in [p.glob("*.yml") for p in search_path]: for spec in documents: if spec.name == "config.yml": continue if args.spec == "all" or spec.name.startswith(args.spec): specs.append(spec) if args.spec == spec.name: break if not specs: log.error("invalid spec name") sys.exit(1) install_yaml_tags() for spec in specs: spec = SpecFile.load_from(spec) total_queries = 0 for model, bind, queries in spec.query_generator(): if op == "dml": [printquery(query, bind) for query in queries] elif op == "execute": affected_rows = 0 queries = list(queries) log.info({ "update": "updated", "insert": "created", "delete": "deleted", }[model.stmt_used] + " " + str(model)) for query in queries: result = bind.execute(query) affected_rows += result.rowcount if "items" in model.data: log.info("populating vendor with %d items" % len(model.data["items"])) total_queries += len(queries) if op == "execute": log.debug("executed %d queries (%d records affected)" % (total_queries, affected_rows))
def process(self): """ Preprocess DBC flags, WHERE clauses, and item lists for vendors. """ def _process_where(data, table): if not "where" in data: return for where_col_name, values in data["where"].items(): if not isinstance(values, list): values = [values] data["where"][where_col_name] = [] for value in values: if isinstance(value, SelectQueryBuilder): rows = flatten(self._execute(value.build()).fetchall()) for field in rows: data["where"][where_col_name].append( get_cmp(table, where_col_name, field)) else: data["where"][where_col_name].append( get_cmp(table, where_col_name, value)) for col_name, values in self.data.items(): flags = get_flags(col_name, values) # DBC flags if flags is not None: self.data[col_name] = flags # vendor items elif col_name == "items" and values is not None: items = [] item_table = get_table("ItemTemplate") if not isinstance(values, list): values = [values] for item in values: query_append = None if isinstance(item, basestring): if item.endswith("^"): item = item[:-1] query_append = lambda q: \ q.order_by(desc(item_table.c.ItemLevel)) query = select([item_table.c.entry])\ .where(get_cmp(item_table, "name", item)[0]) if query_append: query = query_append(query) items.append(self._execute(query).fetchone()) if items[-1] is None: log.error("could not find entry for '%s'" % item) elif isinstance(item, int): items.append(item) elif isinstance(item, SelectQueryBuilder): items += item_table.bind.execute( item.build()).fetchall() self.data["items"] = flatten(items) elif col_name == "extended_costs": costs = self.data["extended_costs"] costs = [costs] if not isinstance(costs, list) else costs for cost_spec in costs: _process_where(cost_spec, get_table("ItemTemplate")) _process_where(self.data, self.table)
def process(self): """ Preprocess DBC flags, WHERE clauses, and item lists for vendors. """ def _process_where(data, table): if not "where" in data: return for where_col_name, values in data["where"].items(): if not isinstance(values, list): values = [values] data["where"][where_col_name] = [] for value in values: if isinstance(value, SelectQueryBuilder): rows = flatten(self._execute(value.build()).fetchall()) for field in rows: data["where"][where_col_name].append( get_cmp(table, where_col_name, field) ) else: data["where"][where_col_name].append( get_cmp(table, where_col_name, value) ) for col_name, values in self.data.items(): flags = get_flags(col_name, values) # DBC flags if flags is not None: self.data[col_name] = flags # vendor items elif col_name == "items" and values is not None: items = [] item_table = get_table("ItemTemplate") if not isinstance(values, list): values = [values] for item in values: query_append = None if isinstance(item, basestring): if item.endswith("^"): item = item[:-1] query_append = lambda q: \ q.order_by(desc(item_table.c.ItemLevel)) query = select([item_table.c.entry])\ .where(get_cmp(item_table, "name", item)[0]) if query_append: query = query_append(query) items.append(self._execute(query).fetchone()) if items[-1] is None: log.error("could not find entry for '%s'" % item) elif isinstance(item, int): items.append(item) elif isinstance(item, SelectQueryBuilder): items += item_table.bind.execute(item.build()).fetchall() self.data["items"] = flatten(items) elif col_name == "extended_costs": costs = self.data["extended_costs"] costs = [costs] if not isinstance(costs, list) else costs for cost_spec in costs: _process_where(cost_spec, get_table("ItemTemplate")) _process_where(self.data, self.table)