Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # -*- coding: utf-8 -*-
- from google.appengine.ext import db, webapp
- from google.appengine.api import users
- from google.appengine.ext.webapp.util import run_wsgi_app
- import logging
- STATE_START = 0
- STATE_HALF = 1
- STATE_FINISHED = 2
- class User(db.Model):
- name = db.StringProperty(required=True)
- sum = db.IntegerProperty(required=True,default=1000)
- def start_trans(self, trans):
- def txn():
- self.sum = self.sum - trans.amount
- self.put()
- log = TransactionLog(parent=self, transaction=trans, amount=trans.amount)
- log.put()
- log = TransactionLog.all().filter('transaction =', trans
- ).ancestor(self).get()
- if log is None:
- db.run_in_transaction(txn)
- trans.state = STATE_HALF
- trans.put()
- def accept_trans(self, trans):
- def txn():
- self.sum = self.sum + trans.amount
- self.put()
- log = TransactionLog(parent=self, transaction=trans, amount=trans.amount*-1)
- log.put()
- log = TransactionLog.all().filter('transaction =', trans
- ).ancestor(self).get()
- if log is None:
- db.run_in_transaction(txn)
- trans.state = STATE_FINISHED
- trans.put()
- def delete_log(self, trans):
- log = TransactionLog.all().filter('transaction =', trans
- ).ancestor(self).get()
- log.delete()
- class Transaction(db.Model):
- t_from = db.ReferenceProperty(User,collection_name="from_set")
- t_to = db.ReferenceProperty(User,collection_name="to_set")
- amount = db.IntegerProperty(required=True)
- state = db.IntegerProperty(required=True,default=STATE_START)
- def do_job(self):
- if self.state == STATE_START:
- logging.debug('start_trans called.')
- self.t_from.start_trans(self)
- return self.do_job()
- elif self.state == STATE_HALF:
- logging.debug('accept_trans called.')
- self.t_to.accept_trans(self)
- return self.do_job()
- elif self.state == STATE_FINISHED:
- log = TransactionLog.all().filter(
- 'transaction =', self).ancestor(self.t_from).get()
- if log is not None:
- self.t_from.delete_log(self)
- return self.do_job()
- log = TransactionLog.all().filter(
- 'transaction =', self).ancestor(self.t_to).get()
- if log is not None:
- self.t_to.delete_log(self)
- return self.do_job()
- self.delete()
- return True
- else:
- raise RuntimeError('It should never occur.')
- class TransactionLog(db.Model):
- transaction = db.ReferenceProperty(Transaction)
- amount = db.IntegerProperty(required=True)
- def init_data():
- users = User.all().fetch(100)
- db.delete(users)
- trans = Transaction.all().fetch(100)
- db.delete(trans)
- logs = TransactionLog.all().fetch(100)
- db.delete(logs)
- usera = User(name="A", sum=2000)
- userb = User(name="B", sum=3000)
- usera.put()
- userb.put()
- class MainHandler(webapp.RequestHandler):
- def get(self):
- if self.request.get("init"):
- init_data()
- self.response.headers['Content-Type'] = 'text/html; charset=utf-8'
- self.response.out.write("<html><body>")
- self.response.out.write("<a href='/?init=1'>Initialize data</a><br/>")
- self.response.out.write("<table border='1'><tr>\n")
- self.response.out.write("<th>Name</th><th>Sum</th>")
- self.response.out.write("</tr>\n")
- query = User.all()
- users = query.fetch(4)
- for user in users:
- self.response.out.write("<tr><td>%s</td>" % user.name)
- self.response.out.write("<td>%s</td>" % user.sum)
- self.response.out.write("</tr>")
- self.response.out.write("</table>")
- self.response.out.write("<form method='POST'>")
- self.response.out.write("<input type='submit' value='send 100 from A to B.'></form>")
- self.response.out.write("</body></html>")
- def post(self):
- user_a = User.all().filter('name =', 'A').get()
- user_b = User.all().filter('name =', 'B').get()
- txn = Transaction(t_from=user_a, t_to=user_b, amount=100)
- txn.put()
- txn.do_job()
- self.redirect("/")
- application = webapp.WSGIApplication([('/', MainHandler)],
- debug=True)
- def main():
- logging.getLogger().setLevel(logging.DEBUG)
- run_wsgi_app(application)
- if __name__ == "__main__":
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement