<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def setBuildProperty(self, bid, name, value, source):
 """ A kind of create_or_update, that's between one or two queries per call """

        def thd(conn):
            bp_tbl = self.db.model.build_properties
            self.checkLength(bp_tbl.c.name, name)
            self.checkLength(bp_tbl.c.source, source)
            whereclause = sa.and_(bp_tbl.c.buildid == bid,
                                  bp_tbl.c.name == name)
            q = sa.select(
                [bp_tbl.c.value, bp_tbl.c.source],
                whereclause=whereclause)
            prop = conn.execute(q).fetchone()
            value_js = json.dumps(value)
            if prop is None:
                conn.execute(bp_tbl.insert(),
                             dict(buildid=bid, name=name, value=value_js,
                                  source=source))
            elif (prop.value != value_js) or (prop.source != source):
                conn.execute(bp_tbl.update(whereclause=whereclause),
                             dict(value=value_js, source=source))
        yield self.db.pool.do(thd)