Example #1
0
 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))
Example #2
0
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
Example #3
0
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)
Example #4
0
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
Example #5
0
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)
Example #6
0
 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)
Example #7
0
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
Example #8
0
 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 + ")")
Example #9
0
 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()
Example #10
0
 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()