From ce4e8b57c53cc8dbcf23544b1ac4a72a9a63efdf Mon Sep 17 00:00:00 2001 From: JoYo <> Date: Tue, 19 Feb 2019 04:40:35 +0000 Subject: [PATCH] initial orm for sqlite state --- sins/__init__.py | 5 +++-- sins/orm.py | 34 +++++++++++++++++++++++++--------- sins/run.py | 46 ++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 68 insertions(+), 17 deletions(-) diff --git a/sins/__init__.py b/sins/__init__.py index f5a6506..2b0ce9d 100644 --- a/sins/__init__.py +++ b/sins/__init__.py @@ -1,3 +1,4 @@ #!/usr/bin/env python3 -from .run import sins, generation -# from .orm import SeedNode +from .run import sins +from .mutation import generation, flip, seed_shell +from .orm import db_config, ScrapNode diff --git a/sins/orm.py b/sins/orm.py index 92682e7..96745fc 100644 --- a/sins/orm.py +++ b/sins/orm.py @@ -1,19 +1,26 @@ #!/usr/bin/env python3 from datetime import datetime -from sqlalchemy import Blob, Column, ForeignKey, Integer, String, DateTime, create_engine, exists, desc +from hashlib import sha1 +from pathlib import Path +from sqlalchemy import LargeBinary, Column, ForeignKey, Integer, String, DateTime, create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import Session, relationship, backref from sqlalchemy.orm.collections import attribute_mapped_collection import logging -from hashlib import sha1 logger = logging.getLogger('sins') now = '{0:%Y%m%dT%H%M%S}'.format(datetime.utcnow()) Base = declarative_base() +def db_config(path: Path) -> Session: + engine = create_engine(f'sqlite:///{path.resolve()}', native_datetime=True) + Base.metadata.create_all(engine) + session = Session(engine) + return session -class SeedNode(Base): +class ScrapNode(Base): + __tablename__ = 'scrap_node' ctime = Column(DateTime, default=datetime.utcnow) id = Column(Integer, primary_key=True) length = Column(Integer, default=0) @@ -21,20 +28,29 @@ class SeedNode(Base): parent_id = Column(Integer, ForeignKey(id)) checksum = Column(String) stdout = Column(String) - image = Column(Blob) + image = Column(LargeBinary) children = relationship( - "SeedNode", + "ScrapNode", cascade="all, delete-orphan", backref=backref("parent", remote_side=id), collection_class=attribute_mapped_collection('name')) - def __init__(self, *, child: bytes, parent: SeedNode = None): - if parent: - self.parent_id = parent.id - + def __init__(self, *, child: bytes, parent_id: int = None): + self.parent_id = parent_id self.image = child self.length = len(child) + self.sha1sum + + def __repr__(self): + values = { + 'id': self.id, + 'checksum': self.checksum, + 'length': self.length, + 'parent_id': self.parent_id, + } + + return str(values) @property def sha1sum(self): diff --git a/sins/run.py b/sins/run.py index 3f7fdc7..d68b906 100755 --- a/sins/run.py +++ b/sins/run.py @@ -4,9 +4,12 @@ from datetime import datetime from multiprocessing import Process, Queue from pathlib import Path from queue import Empty +from sqlalchemy import exists, desc +from tempfile import TemporaryDirectory import logging from .mutation import generation, flip, seed_shell +from .orm import db_config, ScrapNode def sins(): @@ -53,19 +56,47 @@ def sins(): with seed.open('rb') as seed_file: seed_data = seed_file.read() - logger.info(f'seed:\n{seed_data}') + seed = ScrapNode(child=seed_data) + + logger.info(f'seed:\n{seed}') + + if args.output: + db_path = Path(f'{args.output}/sins.sqlite') + else: + temp_dir = TemporaryDirectory() + db_path = Path(f'{temp_dir.name}/sins.sqlite') + + session = db_config(db_path) + logger.info(f'db_path: {db_path}') + + if args.seed: + exists = session.query(ScrapNode).filter(ScrapNode.checksum == seed.checksum) + + if exists: + seed = exists[0] + + else: + session.add(seed) + session.commit() + else: + recent = session.query(ScrapNode).order_by(desc('ctime')).first() + + if recent: + seed = recent + + parent = seed queue = Queue() while True: lineage = 0 - seed_flipped = flip(seed_data) + scrap = flip(parent.image) while lineage < args.lineage: logger.info(f'lineage: {lineage}') result = None - proc = Process(target=generation, args=(queue, seed_flipped)) + proc = Process(target=generation, args=(queue, scrap)) proc.start() try: result = queue.get(timeout=1) @@ -77,7 +108,10 @@ def sins(): lineage += 1 continue - logger.info(f'scrap:\n{seed_flipped}') - logger.info(f'result: {result}') + parent = ScrapNode(child=scrap, parent_id=parent.id) + parent.length = result + session.add(seed) + session.commit() + logger.info(f'scrap:\n{parent}') lineage = 0 - seed_flipped = flip(seed_flipped) + scrap = flip(parent.image)