Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ include LICENSE
include nixnet/VERSION
recursive-include nixnet *.py
recursive-include nixnet_examples *.py
include nixnet_examples/databases/custom_database.dbc
recursive-include tests *.py
1 change: 1 addition & 0 deletions docs/api_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ API Reference
:caption: Table of Contents:

api_reference/session
api_reference/system
api_reference/convert
api_reference/constants
api_reference/types
Expand Down
7 changes: 7 additions & 0 deletions docs/api_reference/databases.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
nixnet.session.databases
========================

.. automodule:: nixnet.system.databases
:members:
:inherited-members:
:show-inheritance:
13 changes: 13 additions & 0 deletions docs/api_reference/system.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
nixnet.system
=============

.. automodule:: nixnet.system
:members:
:show-inheritance:
:inherited-members:

.. toctree::
:maxdepth: 3
:caption: API Reference:

databases
3 changes: 2 additions & 1 deletion docs/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ Examples
examples/stream_io
examples/single_point_io
examples/conversion
examples/can_lin_diff
examples/can_lin_diff
examples/programmatic_databases
8 changes: 8 additions & 0 deletions docs/examples/programmatic_databases.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Programmatic Database Usage
===========================

This example uses :any:`nixnet.system.databases.Databases` to demonstrate how
databases can be programmatically added and used in a system.

.. literalinclude:: ../../nixnet_examples/programmatic_database_usage.py
:pyobject: main
42 changes: 42 additions & 0 deletions nixnet/_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -712,3 +712,45 @@ def nxdb_undeploy(
database_alias_ctypes,
)
_errors.check_for_error(result.value)


def nxdb_get_database_list(
ip_address, # type: typing.Text
size_of_alias_buffer, # type: int
size_of_filepath_buffer, # type: int
):
# type: (...) -> typing.Tuple[typing.List[typing.Text], typing.List[typing.Text], int]
ip_address_ctypes = _ctypedefs.char_p(ip_address.encode('ascii'))
size_of_alias_buffer_ctypes = _ctypedefs.u32(size_of_alias_buffer)
size_of_filepath_buffer_ctypes = _ctypedefs.u32(size_of_filepath_buffer)
alias_buffer_ctypes = ctypes.create_string_buffer(size_of_alias_buffer)
filepath_buffer_ctypes = ctypes.create_string_buffer(size_of_filepath_buffer)
number_of_databases_ctypes = _ctypedefs.u32()
result = _cfuncs.lib.nxdb_get_database_list(
ip_address_ctypes,
size_of_alias_buffer_ctypes,
alias_buffer_ctypes,
size_of_filepath_buffer_ctypes,
filepath_buffer_ctypes,
number_of_databases_ctypes,
)
_errors.check_for_error(result.value)
alias_buffer = alias_buffer_ctypes.value.decode("ascii")
filepath_buffer = filepath_buffer_ctypes.value.decode("ascii")
return alias_buffer, filepath_buffer, number_of_databases_ctypes.value


def nxdb_get_database_list_sizes(
ip_address, # type: typing.Text
):
# type: (...) -> typing.Tuple[int, int]
ip_address_ctypes = _ctypedefs.char_p(ip_address.encode('ascii'))
size_of_alias_buffer_ctypes = _ctypedefs.u32()
size_of_filepath_buffer_ctypes = _ctypedefs.u32()
result = _cfuncs.lib.nxdb_get_database_list_sizes(
ip_address_ctypes,
size_of_alias_buffer_ctypes,
size_of_filepath_buffer_ctypes,
)
_errors.check_for_error(result.value)
return size_of_alias_buffer_ctypes.value, size_of_filepath_buffer_ctypes.value
22 changes: 0 additions & 22 deletions nixnet/nxdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,6 @@ def delete_object(db_object_ref):
_funcs.nxdb_delete_object(db_object_ref)


def add_alias64(
database_alias,
database_filepath,
default_baud_rate):
_funcs.nxdb_add_alias64(database_alias, database_filepath, default_baud_rate)


def remove_alias(
database_alias):
_funcs.nxdb_remove_alias(database_alias)


def deploy(
ip_address,
database_alias,
Expand All @@ -46,13 +34,3 @@ def undeploy(
ip_address,
database_alias):
_funcs.nxdb_undeploy(ip_address, database_alias)


def get_database_list(
ip_address,
size_of_alias_buffer,
alias_buffer,
size_of_filepath_buffer,
filepath_buffer,
number_of_databases):
raise NotImplementedError("Placeholder")
145 changes: 145 additions & 0 deletions nixnet/system/databases.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import collections
import typing # NOQA: F401

import six

from nixnet import _funcs


class Databases(collections.Mapping):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove relevant functions from nxdb.py

https://github.com/ni/nixnet-python/blob/master/nixnet/nxdb.py

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved

"""Database aliases."""

def __init__(self, handle):
self._handle = handle

def __repr__(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is not tested

return 'System.Databases(handle={0})'.format(self._handle)

def __get_database_list(self, ip_address):
alias_buffer_size, filepath_buffer_size = _funcs.nxdb_get_database_list_sizes(ip_address)
aliases, filepaths, _ = _funcs.nxdb_get_database_list(ip_address, alias_buffer_size, filepath_buffer_size)
return list(zip(aliases.split(","), filepaths.split(",")))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we be returning number_of_databases to __len__ instead of doing a string split, zip, and list?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it makes a difference.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I generally expected "len" operations to be "fast" but in this case we're doing more post-processing than is needed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think doing a split, zip and list is going to be that expensive. Especially when we don't expect users to use a ton of aliases at once. Jeff expects around 100 as a maximum.

Leaving it as is.


def __len__(self):
return len(self.__get_database_list(''))

def __iter__(self):
return self.keys()

def __getitem__(self, index):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is not tested

# type: (str) -> Database
"""Return the Database object associated with the specified alias.

Args:
index(str): The value of the index (alias name).
"""
if isinstance(index, six.string_types):
for alias, filepath in self.__get_database_list(''):
if alias == index:
return self._create_item(alias, filepath)
else:
raise KeyError('Database alias %s not found in the system' % index)
else:
raise TypeError(index)

def __delitem__(self, index):
# type: (str) -> None
"""Delete/Remove a database alias from the system.

This function removes the alias from NI-XNET, but does not affect the
database text file. It just removes the alias association to the
database file path.

This function is supported on Windows only, and the alias is removed
from Windows only (not RT targets). Use 'undeploy' to remove an alias
from a Real-Time (RT) target.

Args:
index(str): The name of the alias to delete.
"""
_funcs.nxdb_remove_alias(index)

def _create_item(self, database_alias, database_filepath):
return Database(database_alias, database_filepath)

def keys(self):
"""Return all keys (alias names) used in the Databases object.

Yields:
An iterator to all the keys in the Database object.
"""
for alias, _ in self.__get_database_list(''):
yield alias

def values(self):
"""Return all Database objects in the system.

Yields:
An iterator to all the values in the Databases object.
"""
for alias, filepath in self.__get_database_list(''):
yield self._create_item(alias, filepath)

def items(self):
"""Return all aliases and database objects associated with those aliases in the system.

Yields:
An iterator to tuple pairs of alias and database objects in the system.
"""
for alias, filepath in self.__get_database_list(''):
yield alias, self._create_item(alias, filepath)

def add_alias(self, database_alias, database_filepath, default_baud_rate):
# type: (str, str, int) -> None
"""Add a new alias with baud rate size of up to 64 bits to a database file.

NI-XNET uses alias names for database files. The alias names provide a
shorter name for display, allow for changes to the file system without
changing the application.

This function is supported on Windows only.

Args:
database_alias(str): Provides the desired alias name. Unlike the names of
other XNET database objects, the alias name can use special
characters such as space and dash. Commas are not allowed in the
alias name. If the alias name already exists, this function
changes the previous filepath to the specified filepath.
database_filepath(str): Provides the path to the CANdb, FIBEX, or LDF
file. Commas are not allowed in the filepath name.
default_baud_rate(int): Provides the default baud rate, used when
filepath refers to a CANdb database (.dbc) or an NI-CAN database
(.ncd). These database formats are specific to CAN and do not
specify a cluster baud rate. Use this default baud rate to
specify a default CAN baud rate to use with this alias. If
database_filepath refers to a FIBEX database (.xml) or LIN LDF
file, the default_baud_rate parameter is ignored. The FIBEX and
LDF database formats require a valid baud rate for every
cluster, and NI-XNET uses that baud rate as the default.
"""
_funcs.nxdb_add_alias64(database_alias, database_filepath, default_baud_rate)


class Database(object):
"""Database alias."""

def __init__(
self,
database_alias,
database_filepath,
):
self._database_alias = database_alias
self._database_filepath = database_filepath

def __repr__(self):
return 'System.Database(alias={}, filepath={})'.format(self._database_alias, self._database_filepath)

@property
def filepath(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This property is not tested

# type: () -> str
"""str: Get the filepath associated with the Database object"""
return self._database_filepath
7 changes: 7 additions & 0 deletions nixnet/system/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

from nixnet.system import _device
from nixnet.system import _interface
from nixnet.system import databases


class System(object):
Expand All @@ -21,6 +22,7 @@ def __init__(self):
# type: () -> None
self._handle = None # To satisfy `__del__` in case nx_system_open throws
self._handle = _funcs.nx_system_open()
self._databases = databases.Databases(self._handle)

def __del__(self):
if self._handle is not None:
Expand Down Expand Up @@ -67,6 +69,11 @@ def close(self):

self._handle = None

@property
def databases(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't have a type annotation

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was getting a flake8 error when trying to have return type: databases.Databases

So I removed it. It may have to do with 'databases' being overloaded

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly but we should dig deeper or call these thing out in the PR rather than deleting.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just a type annotation! I don't think it's super critical that needs to be addressed right away, adding notes to the PR

""":any:`nixnet.system.databases.Databases`: Operate on systems's database's aliases"""
return self._databases

@property
def dev_refs(self):
# type: () -> typing.Iterable[_device.Device]
Expand Down
Loading