#
#   queryIsectd.py
#
from struct import *
from socket import *
import os

#
#   priority is required for clients, but not for workers
#   workerid is required for workers, but not for clients.  Isectd supplies the workerid when it
#   instructs the worker to start
#
def attach(host, port, service, priority, workerid):
	# attach to Isectd (isdBadge and isdHeader must BOTH be exactly 48 bytes long)
	isdBadge = pack('7s3s5s3s30s',str(os.getpid()),priority,workerid,'',service)
	isdHeader = pack('7s3s3s9s3s3s3s8s9s',str(len(isdBadge)),'','','','','','','','')# must always contain the message length
	s = socket(AF_INET, SOCK_STREAM)
	s.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1)
	s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
	s.connect((host, port))
	s.sendall(isdHeader + isdBadge)
	return s

def send(sock, reply, more, dataOut):
	# Send data to socket
	dataOut = dataOut + "\0"
	isdHeader = pack("7s3s3s9s3s3s3s8s9s",str(len(dataOut)),str(reply),str(more),'','','','','','')
	sock.sendall(isdHeader + dataOut)

def receive(sock):
	# Pull data from socket
	response = ""
	while 1:
		headerIn = sock.recv(48)# get the header first which tells us what is coming next
		if len(headerIn):
			dataIn = unpack('7s3s3s9s3s3s3s8s9s',headerIn)
			length = dataIn[0]
			reply = dataIn[1]
			more = dataIn[2]
			length = int(length[:length.index('\x00')])
			reply = int(reply[:reply.index('\x00')])
			more = int(more[:more.index('\x00')])
		else:
			break

		if length > 0:
			response = response + sock.recv(length)# get the data package following the header

		if more == 0:
			break
	return response, headerIn

def query(sock, sql):
	# send sql query to Database expecting a reply
	send(sock, 1, 0, sql)
	response, headerIn = receive(sock)
	return response

def commit(sock):
	send(sock, 0, 0, "commit")

def rollback(sock):
	send(sock, 0, 0, "rollback")

def close(sock):
	sock.close()
