Skip to content

Commit

Permalink
dbimport now populates System, Station, Ship and ShipVendor
Browse files Browse the repository at this point in the history
  • Loading branch information
kfsone committed Aug 25, 2014
1 parent 926c8cc commit d9b7f1a
Showing 1 changed file with 118 additions and 48 deletions.
166 changes: 118 additions & 48 deletions dbimport.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,34 @@
#! /usr/bin/env python
# Convert accdb to sqlite3 db
#
# Bootstrap a new .SQ3 database from dataseeds and an existing ACCDB database.
#
# Note: This is NOT intended to be user friendly. If you don't know what this
# script is for, then you can safely ignore it.

import sys
import os
import re
# Main imports.
import sys, os, re

# We'll need a list of star systems.
import stars
import dataseed.stars
import dataseed.ships
from tradedb import *

# Filenames/URIs
dbDef = "dataseed/dbdef.sql"
inDB = "Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=.\\TradeDangerous.accdb"
outDB = "tradedb.sq3"

# Delete the old file. This is an import tool not a maintenance tool.
try: os.remove(outDB)
except: pass

systems = {}
stations, stationByOldID, stationByNewID = {}, {}, {}

class check_item(object):
"""
'with' wrapper for putting
Wrapper class that allows us to beautify the output as a sort
of checklist.
Usage:
with check_item("Step description"):
things_in_step()
"""
def __init__(self, title):
self.title = title
Expand All @@ -35,46 +42,109 @@ def __exit__(self, type, value, traceback):
else:
print('[+]')

# This is not intended to be user friendly.
with check_item("Connect to MS Access DB"):
import pypyodbc
inConn = pypyodbc.connect(inDB)
inCur = inConn.cursor()
def main():
# Destroy the SQLite database if it already exists.
try: os.remove(outDB)
except: pass

with check_item("Connect to SQLite3 DB"):
import sqlite3
outConn = sqlite3.connect(outDB)
outCur = outConn.cursor()
with check_item("Connect to MS Access DB"):
import pypyodbc
inConn = pypyodbc.connect(inDB)
inCur = inConn.cursor()

with check_item("Initialize SQlite3 DB Structure"):
outCur.executescript(open("dbdef.sql").read())
outConn.commit()
with check_item("Connect to SQLite3 DB"):
import sqlite3
outConn = sqlite3.connect(outDB)
outCur = outConn.cursor()

with check_item("Populate `Systems` table"):
stmt = "INSERT INTO Systems (name, pos_x, pos_y, pos_z) VALUES (?, ?, ?, ?)"
values = []
for star in stars.stars:
outCur.execute(stmt, [ star.name, star.x, star.y, star.z ])
systemID = int(outCur.lastrowid)
system = System(systemID, star.name, star.x, star.y, star.z)
systems[TradeDB.normalized_str(star.name)] = system
outConn.commit()
with check_item("Apply DDL commands from '%s'" % dbDef):
# Sure, I could have written: outCur.executescript(open(dbDef).read()).commit()
# but my perl days are behind me...
ddlScript = open(dbDef).read()
outCur.executescript(ddlScript)

with check_item("Populate `System` table"):
# Star data is stored in 'stars.py'
stmt = "INSERT INTO System (name, pos_x, pos_y, pos_z) VALUES (?, ?, ?, ?)"
for star in dataseed.stars.stars:
outCur.execute(stmt, [ star.name, star.x, star.y, star.z ])
systemID = int(outCur.lastrowid)
system = System(systemID, star.name, star.x, star.y, star.z)
systems[TradeDB.normalized_str(star.name)] = system

with check_item("Populate `Station` table"):
# We're going to remap the station IDs to new IDs, and we're the accessdb
# hails back to ED:Beta 1 so it doesn't distinguish between systems and
# stations, so we'll need to make the associations between stations
# and the systems they are in.

# Systems without a station were represented by a station called 'STARNAME*',
# and we're going to want to filter those out.
fakeNameRe = re.compile(r'\*$')

inCur.execute("SELECT ID, station, system FROM Stations ORDER BY ID")
stmt = "INSERT INTO Station (name, system_id, ls_from_star) VALUES (?, ?, 0)"
for (ID, stationName, systemName) in inCur:
if fakeNameRe.search(stationName):
pass
system = systems[TradeDB.normalized_str(systemName)]

outCur.execute(stmt, [ stationName, system.ID ])
newStationID = int(outCur.lastrowid)
oldStationID = int(ID)

station = Station(newStationID, system, stationName)
stations[stationName] = station
stationByOldID[oldStationID] = station
stationByNewID[newStationID] = station

with check_item("Populate `Ship` table"):
# I'm not entirely sure whether I really want this data in the database,
# it seems perfectly fine to maintain it as a python script.
stmt = """
INSERT INTO Ship
(
name
, capacity, mass, drive_rating
, max_ly_empty, max_ly_full
, max_speed, boost_speed
)
VALUES
(
?
, ?, ?, ?
, ?, ?
, ?, ?
)
"""
rows = []
for ship in dataseed.ships.ships:
rows += [ [
ship.name
, ship.capacity, ship.mass, ship.driveRating
, ship.maxJump, ship.maxJumpFull
, ship.maxSpeed, ship.boostSpeed
] ]
outCur.executemany(stmt, rows)

with check_item("Populate `ShipVendor` table"):
stmt = """
INSERT INTO ShipVendor
( ship_id, station_id, cost )
VALUES
( (SELECT ship_id FROM Ship WHERE Ship.name = ?), ?, ? )
"""
rows = []
for ship in dataseed.ships.ships:
for stationName in ship.stations:
station = stations[TradeDB.list_search("Station", stationName, stations)]
rows += [ [
ship.name, station.ID, 0 # We don't have prices yet.
] ]
outCur.executemany(stmt, rows)

with check_item("Populate `Stations` table"):
inCur.execute("SELECT ID, station, system FROM Stations ORDER BY ID")
stmt = "INSERT INTO Stations (name, system_id, ls_from_star) VALUES (?, ?, 0)"
fakeNameRe = re.compile(r'\*$')
values = []
for (ID, stationName, systemName) in inCur:
if fakeNameRe.search(stationName):
pass
system = systems[TradeDB.normalized_str(systemName)]

outCur.execute(stmt, [ stationName, system.ID ])
newStationID = int(outCur.lastrowid)
oldStationID = int(ID)

station = Station(newStationID, system, stationName)
stationByOldID[oldStationID] = station
stationByNewID[newStationID] = station
outConn.commit()


if __name__ == "__main__":
main()

0 comments on commit d9b7f1a

Please sign in to comment.