def findOrCreate(roles, extra_roles, lvalues, extra_lvalues, rvalues, extra_rvalues): statements = [] data = [] conditions = [] query = f"select role.l from {roles[0]}cn role " for (i, role) in enumerate(roles[1:]): query += f"join {role}cn role{i} on (role{i}.l = role.l) " for (i, (rel, value)) in enumerate(lvalues): query += f"join {rel}cn1 lvalue{i} on (lvalue{i}.l = role.l) " conditions += [f"lvalue{i}.r = ? "] data += [value] for (i, (rel, value)) in enumerate(rvalues): query += f"join {rel}c1n rvalue{i} on (rvalue{i}.r = role.l) " conditions += [f"rvalue{i}.l = ? "] data += [value] for (i, condition) in enumerate(conditions): query += "where " if i == 0 else "and " query += condition query += "limit 1" c = core.conn.cursor() c.execute(query, data) found = None for row in c: found = row[0] c.close() if not found: found = str(uuid.uuid4()) for role in roles: statements += core.relate([found, role]) for (rel, value) in lvalues: statements += core.relate([found, rel, value]) for (rel, value) in rvalues: statements += core.relate([value, rel, found]) statements += addRoles(found, extra_roles) for (rel, value) in extra_lvalues: statements += link(found, rel, value) for (rel, value) in extra_rvalues: statements += link(value, rel, found) return (statements, found)
def trackFile(path, label, id, contenttype, mutable=None): basename = os.path.basename(path) if not mutable: (statements, mutable) = findOrCreate(["EntityE", "MutableE", "FileE"], [], [("LabelES", label), ("IdentityES", f"{id} [in file] {basename}"), ("PathES", path)], [], [], []) else: statements = addRoles(mutable, "FileE") statements += weakLLink(mutable, "PathES", path) statements += weakLLink(mutable, "LabelES", label) statements += weakLLink(mutable, "IdentityES", f"{id} [in file] {basename}") sha = sha256sum(path) c = core.conn.cursor() c.execute( """select constant.l from ConstantEcn constant left join ShaEScn1 sha on (constant.l = sha.l) left join ContentTypeEScn1 contenttype on (constant.l = contenttype.l) where sha.r = ? and contenttype.r = ? limit 1""", (sha, contenttype)) constant = None for row in c: constant = row[0] c.close() if not constant: mtime = datetime.datetime.fromtimestamp( os.path.getmtime(path)).isoformat() constant = str(uuid.uuid4()) statements += core.relate([constant, "EntityE"]) statements += core.relate([constant, "LabelES", mtime]) basename = os.path.basename(path) statements += core.relate([ constant, "IdentityES", f"{id} [in file] {basename} [at] {mtime}" ]) statements += core.relate([constant, "ConstantE"]) statements += core.relate([constant, "ShaES", sha]) statements += core.relate([constant, "ContentTypeES", contenttype]) statements += core.relate([constant, "CreationTimeES", mtime]) statements += core.relate( [constant, "ContentEB", sqlite3.Binary(open(path, "rb").read())]) statements += link(mutable, "ContentEE", constant) return (statements, mutable, constant)
def trackEmbedded(value, label, id, contenttype, mtime, mutable=None): statements = [] if not mutable: (statements, mutable) = findOrCreate(["EntityE", "MutableE"], [], [("LabelES", label), ("IdentityES", id)], [], [], []) else: statements = weakLLink(mutable, "LabelES", label) statements += weakLLink(mutable, "IdentityES", id) sha = sha256sum(value, value=True) c = core.conn.cursor() c.execute( """select constant.l from ConstantEcn constant left join ShaEScn1 sha on (constant.l = sha.l) left join ContentTypeEScn1 contenttype on (constant.l = contenttype.l) where sha.r = ? and contenttype.r = ? limit 1""", (sha, contenttype)) constant = None for row in c: constant = row[0] c.close() if not constant: constant = str(uuid.uuid4()) statements += core.relate([constant, "EntityE"]) statements += core.relate([constant, "LabelES", mtime]) statements += core.relate( [constant, "IdentityES", f"{id} [at] {mtime}"]) statements += core.relate([constant, "ConstantE"]) statements += core.relate([constant, "ShaES", sha]) statements += core.relate([constant, "ContentTypeES", contenttype]) statements += core.relate([constant, "CreationTimeES", mtime]) statements += core.relate( [constant, "ContentEB", sqlite3.Binary(value.encode())]) statements += core.relate([constant, "EmbeddedE"]) statements += link(mutable, "ContentEE", constant) return (statements, mutable, constant)
def addRoles(entity, roles): if not entity: raise PiiException("addRoles(): entity is null") statements = [] if isinstance(roles, str): roles = [roles] c = core.conn.cursor() c.execute("""select role.r from RoleEScnn role where role.l = ?""", (entity, )) existing = [] for row in c: existing += [row[0]] c.close() for role in roles: if not role in existing: statements += core.relate([entity, role]) return statements
def weakLLink(l, rel, r, card="cnn"): if not l: raise PiiException("weakLLink(): l is null") if not r: raise PiiException("weakLLink(): r is null") statements = [] c = core.conn.cursor() c.execute( f"""select rel.l, rel.r from {rel}{card} rel where rel.l = ? limit 1""", (l, )) lnk = None for row in c: lnk = row[0] c.close() if not lnk: statements += core.relate([l, rel, r]) return statements
# Performing a Test on an Implementation yields a TestResult statements += core.model( "TestResultE -- ImplementationEEcn1 -- ImplementationE") statements += core.model("TestResultE -- TestEEcn1 -- TestE") # A Guide tells you how to use an Appliance statements += core.model("ApplianceE -- GuideEEcnn -- GuideE") # A version in Git have additional properties. statements += core.model("GitVersionE -- CommitEScn1") statements += core.model("GitVersionE -- DateETcn1") statements += core.model("GitVersionE -- CommentEBcn1") # Graphical Presentation statements += core.relate(["EntityE", "ShapeSS", "box"]) statements += core.relate(["EntityE", "RedSI", 255]) statements += core.relate(["EntityE", "GreenSI", 255]) statements += core.relate(["EntityE", "BlueSI", 255]) statements += core.relate(["ArtifactE", "RedSI", 128]) statements += core.relate(["VersionE", "RedSI", 192]) statements += core.relate(["MutableE", "BlueSI", 0]) statements += core.relate(["ContainerE", "BlueSI", 64]) statements += core.relate(["ConstantE", "BlueSI", 128]) statements += core.relate(["EmbeddedE", "BlueSI", 192]) statements += core.relate(["SpecificationE", "GreenSI", 128]) statements += core.relate(["ImplementationE", "GreenSI", 192])