def update_db(self): m = netforce.model.get_model(self.model) mr = netforce.model.get_model(self.relation) db = database.get_connection() schema = database.get_active_schema() or "public" res = db.get("SELECT * FROM pg_class JOIN pg_catalog.pg_namespace n ON n.oid=pg_class.relnamespace WHERE relname=%s AND n.nspname=%s", self.reltable, schema) if not res: db.execute("CREATE TABLE %s (%s int4 NOT NULL REFERENCES %s(id) ON DELETE CASCADE, %s int4 NOT NULL REFERENCES %s(id) ON DELETE CASCADE)" % ( self.reltable, self.relfield, m._table, self.relfield_other, mr._table))
def is_empty_db(): db = database.get_connection() schema = database.get_active_schema() or "public" res = db.get("SELECT * FROM pg_class JOIN pg_catalog.pg_namespace n ON n.oid=pg_class.relnamespace WHERE relname='settings' AND nspname=%s",schema) if not res: return True res = db.get("SELECT * FROM settings WHERE id=1") if not res: return True return False
def set_db_version(version): db = database.get_connection() schema = database.get_active_schema() or "public" res = db.get("SELECT * FROM pg_class JOIN pg_catalog.pg_namespace n ON n.oid=pg_class.relnamespace WHERE relname='settings' AND nspname=%s",schema) if not res: raise Exception("Missing settings table") res = db.get("SELECT * FROM settings WHERE id=1") if not res: raise Exception("Missing settings record") db.execute("UPDATE settings SET version=%s WHERE id=1", version)
def is_empty_db(): db = database.get_connection() schema = database.get_active_schema() or "public" res = db.get( "SELECT * FROM pg_class JOIN pg_catalog.pg_namespace n ON n.oid=pg_class.relnamespace WHERE relname='settings' AND nspname=%s", schema) if not res: return True res = db.get("SELECT * FROM settings WHERE id=1") if not res: return True return False
def set_db_version(version): db = database.get_connection() schema = database.get_active_schema() or "public" res = db.get( "SELECT * FROM pg_class JOIN pg_catalog.pg_namespace n ON n.oid=pg_class.relnamespace WHERE relname='settings' AND nspname=%s", schema) if not res: raise Exception("Missing settings table") res = db.get("SELECT * FROM settings WHERE id=1") if not res: raise Exception("Missing settings record") db.execute("UPDATE settings SET version=%s WHERE id=1", version)
def update_db(self): super(Many2One, self).update_db() m = netforce.model.get_model(self.model) if not m._table or not self.store: return db = database.get_connection() schema = database.get_active_schema() or "public" fkname = m._table + "_" + self.name + "_fk" if self.on_delete == "restrict": delete_rule = "r" on_delete_sql = "RESTRICT" elif self.on_delete == "no_action": delete_rule = "a" on_delete_sql = "NO_ACTION" elif self.on_delete == "cascade": delete_rule = "c" on_delete_sql = "CASCADE" elif self.on_delete == "set_null": delete_rule = "n" on_delete_sql = "SET NULL" elif self.on_delete == "set_default": delete_rule = "d" on_delete_sql = "SET DEFAULT" else: raise Exception("Invalid on_delete on %s.%s (%s)" % (m._name, self.name, self.on_delete)) mr = netforce.model.get_model(self.relation) if not mr: raise Exception("Relation model '%s' does not exist" % self.relation) drop_fk = False add_fk = False res = db.get( "SELECT r.relname,c.confdeltype FROM pg_constraint c,pg_class r JOIN pg_catalog.pg_namespace n ON n.oid=r.relnamespace WHERE c.conname=%s AND r.oid=c.confrelid AND n.nspname=%s", fkname, schema) if not res: print("adding foreign key %s.%s" % (self.model, self.name)) drop_fk = False add_fk = True else: if res.confdeltype != delete_rule or res.relname != mr._table: print("changing foreign key %s.%s" % (self.model, self.name)) print(" delete_rule: %s -> %s" % (res.confdeltype, delete_rule)) print(" relation: %s -> %s" % (res.relname, mr._table)) drop_fk = True add_fk = True if drop_fk: db.execute("ALTER TABLE %s DROP CONSTRAINT %s" % (m._table, fkname)) if add_fk: q = "ALTER TABLE %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (id)" % ( m._table, fkname, self.name, mr._table) if self.on_delete: q += " ON DELETE %s" % on_delete_sql print(q) db.execute(q)
def get_db_version(): db = database.get_connection() schema = database.get_active_schema() or "public" res = db.get( "SELECT * FROM pg_class JOIN pg_catalog.pg_namespace n ON n.oid=pg_class.relnamespace WHERE relname='settings' AND nspname=%s", schema, ) if not res: return None res = db.get("SELECT * FROM settings WHERE id=1") if not res: return None return res.version
def update_db(self): if self.name == "id": return m = netforce.model.get_model(self.model) if not m._table or not self.store: return db = database.get_connection() schema = database.get_active_schema() or "public" col_type = self.get_col_type() res = db.get( "SELECT * FROM pg_attribute a,pg_type t WHERE attrelid=(SELECT pg_class.oid FROM pg_class JOIN pg_catalog.pg_namespace n ON n.oid=pg_class.relnamespace WHERE relname=%s AND n.nspname=%s) AND attname=%s and t.oid=a.atttypid", m._table, schema, self.name) if not res: print("adding column %s.%s" % (m._table, self.name)) q = "ALTER TABLE %s ADD COLUMN \"%s\" %s" % (m._table, self.name, col_type) db.execute(q) else: old_col_type = res.typname if res.typname == "varchar": old_col_type += "(%s)" % (res.atttypmod - 4) elif res.typname == "numeric": prec = ((res.atttypmod - 4) >> 16) & 0xffff scale = (res.atttypmod - 4) & 0xffff old_col_type += "(%s,%s)" % (prec, scale) if old_col_type != col_type: try: print(" changing column %s.%s" % (self.model, self.name)) print(" %s -> %s" % (old_col_type, col_type)) q = "ALTER TABLE %s ALTER COLUMN \"%s\" TYPE %s" % (m._table, self.name, col_type) db.execute(q) except: raise Exception("Failed to update database column type for field '%s' of '%s'" % (self.name, m._name)) if self.required and (not res or not res.attnotnull): print(" adding not-null for %s.%s" % (self.model, self.name)) q = "SELECT COUNT(*) AS count FROM %s WHERE \"%s\" IS NULL" % (m._table, self.name) res = db.get(q) if res.count > 0: print("WARNING: can not add not-null constraint for %s.%s" % (self.model, self.name)) else: q = "ALTER TABLE %s ALTER COLUMN \"%s\" SET NOT NULL" % (m._table, self.name) db.execute(q) elif not self.required and res and res.attnotnull: print(" dropping not-null") q = "ALTER TABLE %s ALTER COLUMN \"%s\" DROP NOT NULL" % (m._table, self.name) db.execute(q) if self.index: idx_name = m._table + "_" + self.name + "_idx" res = db.get("SELECT * FROM pg_index i,pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace WHERE c.oid=i.indexrelid AND c.relname=%s AND n.nspname=%s", idx_name,schema) if not res: print("creating index %s" % idx_name) db.execute("CREATE INDEX " + idx_name + " ON " + m._table + " (" + self.name + ")")
def post(self): req = json.loads(self.request.body.decode()) # open("/tmp/json_rpc.log","a").write(self.request.body.decode()+"\n###############################################################\n") db = database.get_connection() if db: db.begin() try: clear_cache() method = req["method"] params = req["params"] if method == "execute": model = params[0] method = params[1] if method.startswith("_"): raise Exception("Invalid method") args = params[2] if len(params) >= 4: opts = params[3] or {} else: opts = {} if len(params) >= 5: cookies = params[4] or {} else: cookies = {} if "locale" in cookies: set_active_locale(cookies["locale"]) if "user_id" in cookies: user_id=int(cookies["user_id"]) token=cookies.get("token") dbname=database.get_active_db() schema=database.get_active_schema() if check_token(dbname, user_id, token, schema=schema): access.set_active_user(user_id) user_id = access.get_active_user() rpc_log.info("EXECUTE db=%s model=%s method=%s user=%s" % (database.get_active_db(), model, method, user_id)) m = get_model(model) f = getattr(m, method) ctx = { "request_handler": self, "request": self.request, } ctx.update(self.get_cookies()) ctx.update(cookies); ctx.update(opts.get("context",{})) opts["context"]=ctx with timeout(seconds=900): # XXX: can make this faster? (less signal sys handler overhead) t0 = time.time() res = f(*args, **opts) t1 = time.time() dt = (t1 - t0) * 1000 rpc_log.info("<<< %d ms" % dt) resp = { "result": res, "error": None, "id": req["id"], } else: raise Exception("Invalid method: %s" % method) if db: db.commit() except Exception as e: try: msg = translate(str(e)) except: print("WARNING: Failed to translate error message") msg = str(e) rpc_log.error(msg) if db: db.rollback() rpc_log.error(traceback.format_exc()) err = { "message": msg, } error_fields = getattr(e, "error_fields", None) if error_fields: err["error_fields"] = error_fields resp = { "result": None, "error": err, "id": req["id"], } access.clear_active_user() try: data = json_dumps(resp) self.add_header("Access-Control-Allow-Origin","*") self.write(data) except: print("JSONRPC ERROR: invalid response") from pprint import pprint pprint(resp) traceback.print_exc()
def post(self): req = json.loads(self.request.body.decode()) # open("/tmp/json_rpc.log","a").write(self.request.body.decode()+"\n###############################################################\n") db = database.get_connection() if db: db.begin() try: clear_cache() method = req["method"] params = req["params"] if method == "execute": model = params[0] method = params[1] if method.startswith("_"): raise Exception("Invalid method") args = params[2] if len(params) >= 4: opts = params[3] or {} else: opts = {} if len(params) >= 5: cookies = params[4] or {} else: cookies = {} if "locale" in cookies: set_active_locale(cookies["locale"]) if "user_id" in cookies: user_id = int(cookies["user_id"]) token = cookies.get("token") dbname = database.get_active_db() schema = database.get_active_schema() if check_token(dbname, user_id, token, schema=schema): access.set_active_user(user_id) user_id = access.get_active_user() rpc_log.info( "EXECUTE db=%s model=%s method=%s user=%s" % (database.get_active_db(), model, method, user_id)) m = get_model(model) f = getattr(m, method) ctx = { "request_handler": self, "request": self.request, } ctx.update(self.get_cookies()) ctx.update(cookies) ctx.update(opts.get("context", {})) opts["context"] = ctx with timeout( seconds=900 ): # XXX: can make this faster? (less signal sys handler overhead) t0 = time.time() res = f(*args, **opts) t1 = time.time() dt = (t1 - t0) * 1000 rpc_log.info("<<< %d ms" % dt) resp = { "result": res, "error": None, "id": req["id"], } else: raise Exception("Invalid method: %s" % method) if db: db.commit() except Exception as e: try: msg = translate(str(e)) except: print("WARNING: Failed to translate error message") msg = str(e) rpc_log.error(msg) if db: db.rollback() rpc_log.error(traceback.format_exc()) err = { "message": msg, } error_fields = getattr(e, "error_fields", None) if error_fields: err["error_fields"] = error_fields resp = { "result": None, "error": err, "id": req["id"], } access.clear_active_user() try: data = json_dumps(resp) self.add_header("Access-Control-Allow-Origin", "*") self.write(data) except: print("JSONRPC ERROR: invalid response") from pprint import pprint pprint(resp) traceback.print_exc()